
    /*+-----------------------------------------------------------------**
     **                       OpenScop Library                          **
     **-----------------------------------------------------------------**
     **                            util.c                               **
     **-----------------------------------------------------------------**
     **                   First version: 08/10/2010                     **
     **-----------------------------------------------------------------**

 
 *****************************************************************************
 * OpenScop: Structures and formats for polyhedral tools to talk together    *
 *****************************************************************************
 *    ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__,                *
 *    /   / /  //  //  //  // /   / /  //  //   / /  // /  /|,_,             *
 *   /   / /  //  //  //  // /   / /  //  //   / /  // /  / / /\             *
 *  |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/  \            *
 *  | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\  \ /\           *
 *  | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\          *
 *  | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \  \         *
 *  | P |n| l | = | s | t |=| = |d| = | = | = | |   |=| o | | \# \  \        *
 *  | H | | y |   | e | o | | = |l|   |   | = | |   | | G | |  \  \  \       *
 *  | I | |   |   | e |   | |   | |   |   |   | |   | |   | |   \  \  \      *
 *  | T | |   |   |   |   | |   | |   |   |   | |   | |   | |    \  \  \     *
 *  | E | |   |   |   |   | |   | |   |   |   | |   | |   | |     \  \  \    *
 *  | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | /      \* \  \   *
 *  | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/        \  \ /   *
 *  '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---'          '--'    *
 *                                                                           *
 * Copyright (C) 2008 University Paris-Sud 11 and INRIA                      *
 *                                                                           *
 * (3-clause BSD license)                                                    *
 * Redistribution and use in source  and binary forms, with or without       *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 * 3. The name of the author may not be used to endorse or promote products  *
 *    derived from this software without specific prior written permission.  *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 *                                                                           *
 * OpenScop Library, a library to manipulate OpenScop formats and data       *
 * structures. Written by:                                                   *
 * Cedric Bastoul     <Cedric.Bastoul@u-psud.fr> and                         *
 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr>                          *
 *                                                                           *
 *****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <osl/macros.h>
#include <osl/util.h>


/*+***************************************************************************
 *                             Utility functions                             *
 *****************************************************************************/


/**
 * osl_util_skip_blank_and_comments "file skip" function:
 * this function reads the open file 'file' line by line and skips
 * blank/comment lines and spaces. The first line where there is some
 * useful information is stored at the address 'str' (the memory to
 * store the line must be allocated before the call to this function
 * and must be at least OSL_MAX_STRING * sizeof(char)). The pointer
 * to the first useful information in this line is returned by the
 * function.
 * \param[in] file The (opened) file to read.
 * \param[in] str  Address of an allocated space to store the first line
 *                 that contains useful information.
 * \return The address of the first useful digit in str.
 */
char * osl_util_skip_blank_and_comments(FILE * file, char * str) {
  char * start;

  do {
    start = fgets(str, OSL_MAX_STRING, file);
    while ((start != NULL) && isspace(*start) && (*start != '\n'))
      start++;
  }
  while (start != NULL && (*start == '#' || *start == '\n'));

  return start;
}


/**
 * osl_util_sskip_blank_and_comments "string skip" function:
 * this function updates the str pointer, which initialy points to a string,
 * to the first character in this string which is not a space or a comment
 * (comments start at '#' and end at '\n'), or to the end of string.
 * \param[in,out] str Address of a string, updated to the address of
 *                    the first non-space or comment character.
 */
void osl_util_sskip_blank_and_comments(char ** str) {
  do {
    // Skip spaces/blanc lines.
    while (*str && **str && isspace(**str))
      (*str)++;

    // Skip the comment if any.
    if (*str && **str && **str == '#') {
      while (**str && **str != '\n') {
        (*str)++;
      }
    }
  }
  while (*str && **str && **str == '\n');
}


/**
 * osl_util_read_int function:
 * reads an int on the input 'file' or the input string 'str' depending on
 * which one is not NULL (exactly one of them must not be NULL).
 * \param[in]     file The file where to read an int (if not NULL).
 * \param[in,out] str  The string where to read an int (if not NULL). This
 *                     pointer is updated to reflect the read and points
 *                     after the int in the input string.
 * \return The int that has been read.
 */
int osl_util_read_int(FILE * file, char ** str) {
  char s[OSL_MAX_STRING], * start;
  int res;
  int i = 0;

  if ((file != NULL && str != NULL) || (file == NULL && str == NULL))
    OSL_error("one and only one of the two parameters can be non-NULL");

  if (file != NULL) {
    // Parse from a file.
    start = osl_util_skip_blank_and_comments(file, s);
    if (sscanf(start, " %d", &res) != 1)
      OSL_error("an int was expected");
  }
  else {
    // Parse from a string.
    // Skip blank/commented lines.
    osl_util_sskip_blank_and_comments(str);
    
    // Build the chain to analyze.
    while (**str && !isspace(**str) && **str != '\n' && **str != '#')
      s[i++] = *((*str)++);
    s[i] = '\0';
    if (sscanf(s, "%d", &res) != 1)
      OSL_error("an int was expected");
  }

  return res;
}


/**
 * osl_util_read_string function:
 * reads a string on the input 'file' or the input string 'str' depending on
 * which one is not NULL (exactly one of them must not be NULL).
 * \param[in]     file The file where to read a string (if not NULL).
 * \param[in,out] str  The string where to read a string (if not NULL). This
 *                     pointer is updated to reflect the read and points
 *                     after the string in the input string.
 * \return The string that has been read.
 */
char * osl_util_read_string(FILE * file, char ** str) {
  char s[OSL_MAX_STRING], * start;
  char * res;
  int i = 0;

  if ((file != NULL && str != NULL) || (file == NULL && str == NULL))
    OSL_error("one and only one of the two parameters can be non-NULL");

  OSL_malloc(res, char *, OSL_MAX_STRING * sizeof(char));
  if (file != NULL) {
    // Parse from a file.
    start = osl_util_skip_blank_and_comments(file, s);
    if (sscanf(start, " %s", res) != 1)
      OSL_error("a string was expected");
  }
  else {
    // Parse from a string.
    // Skip blank/commented lines.
    osl_util_sskip_blank_and_comments(str);
    
    // Build the chain to analyze.
    while (**str && !isspace(**str) && **str != '\n' && **str != '#')
      s[i++] = *((*str)++);
    s[i] = '\0';
    if (sscanf(s, "%s", res) != 1)
      OSL_error("a string was expected");
  }

  OSL_realloc(res, char *, strlen(res) + 1);
  return res;
}


/**
 * osl_util_read_line function:
 * reads a line on the input 'file' or the input string 'str' depending on
 * which one is not NULL (exactly one of them must not be NULL). A line
 * is defined as the array of characters before the comment tag or the end of
 * line (it may include spaces).
 * \param[in]     file The file where to read a line (if not NULL).
 * \param[in,out] str  The string where to read a line (if not NULL). This
 *                     pointer is updated to reflect the read and points
 *                     after the line in the input string.
 * \return The line that has been read.
 */
char * osl_util_read_line(FILE * file, char ** str) {
  char s[OSL_MAX_STRING], * start;
  char * res;
  int i = 0;

  if ((file != NULL && str != NULL) || (file == NULL && str == NULL))
    OSL_error("one and only one of the two parameters can be non-NULL");

  OSL_malloc(res, char *, OSL_MAX_STRING * sizeof(char));
  if (file != NULL) {
    // Parse from a file.
    start = osl_util_skip_blank_and_comments(file, s);
    while (*start && *start != '\n' && *start != '#' && i < OSL_MAX_STRING)
      res[i++] = (*start)++;
  }
  else {
    // Parse from a string.
    osl_util_sskip_blank_and_comments(str);
    while (**str && **str != '\n' && **str != '#' && i < OSL_MAX_STRING)
      res[i++] = *((*str)++);
  }

  res[i] = '\0';
  OSL_realloc(res, char *, strlen(res) + 1);
  return res;
}


/**
 * osl_util_read_int internal function:
 * reads a tag (the form of a tag with name "name" is \<name\>) on the input
 * 'file' or the input string 'str' depending on which one is not NULL (exactly
 * one of them must not be NULL). It returns the name of the tag (thus without
 * the < and > as a string. Note that in the case of an ending tag, e.g.,
 * \</foo\>, the slash is returned as a part of the name, e.g., /foo.
 * \param[in]     file The file where to read a tag (if not NULL).
 * \param[in,out] str  The string where to read a tag (if not NULL). This
 *                     pointer is updated to reflect the read and points
 *                     after the tag in the input string.
 * \return The tag name that has been read.
 */
char * osl_util_read_tag(FILE * file, char ** str) {
  char s[OSL_MAX_STRING], * start;
  char * res;
  int i = 0;

  if ((file != NULL && str != NULL) || (file == NULL && str == NULL))
    OSL_error("one and only one of the two parameters can be non-NULL");

  // Skip blank/commented lines.
  if (file != NULL) {
    start = osl_util_skip_blank_and_comments(file, s);
    str = &start;
  }
  else {
    osl_util_sskip_blank_and_comments(str);
  }

  // Pass the starting '<'.
  if (**str != '<')
    OSL_error("a \"<\" to start a tag was expected");
  (*str)++;

  // Read the tag.
  OSL_malloc(res, char *, (OSL_MAX_STRING + 1) * sizeof(char));
  res[OSL_MAX_STRING] = '\0';
  
  while (**str && **str != '>') {
    if (((**str >= 'A') && (**str <= 'Z')) ||
        ((**str >= 'a') && (**str <= 'z')) ||
        ((**str == '/') && (i == 0))       ||
        (**str == '_')) {
      res[i++] = *((*str)++);
      res[i] = '\0';
    }
    else {
      OSL_error("illegal character in the tag name");
    }
  }

  // Check we actually end up with a '>' and pass it.
  if (**str != '>')
    OSL_error("a \">\" to end a tag was expected");
  (*str)++;

  return res;
}


/**
 * osl_util_read_uptotag function:
 * this function reads a file up to a given tag (the tag is read) or the
 * end of file. It puts everything it reads, except the tag, in a string 
 * which is returned. However ot returns NULL is the tag is not found.
 * \param[in] file The file where to read the tail.
 * \param[in] tag  The tag which, when reached, stops the file reading.
 * \return The string that has been read from the file.
 */
char * osl_util_read_uptotag(FILE * file, char * tag) {
  int high_water_mark = OSL_MAX_STRING;
  int nb_chars = 0;
  int lentag = strlen(tag);
  int tag_found = 0;
  char * res;

  OSL_malloc(res, char *, high_water_mark * sizeof(char));

  // - Copy everything to the res string.
  while (!feof(file)) {
    res[nb_chars] = fgetc(file); 
    nb_chars++;

    if ((nb_chars >= lentag) &&
        (!strncmp(&res[nb_chars - lentag], tag, lentag))) {
      tag_found = 1;
      break;
    }

    if (nb_chars >= high_water_mark) {
      high_water_mark += high_water_mark;
      OSL_realloc(res, char *, high_water_mark * sizeof(char));
    }
  }

  if (!tag_found) {
    OSL_debug("tag was not found, end of file reached");
    free(res);
    return NULL;
  }

  // - 0-terminate the string.
  OSL_realloc(res, char *, (nb_chars - strlen(tag) + 1) * sizeof(char));
  res[nb_chars - strlen(tag)] = '\0';

  return res;
}


/**
 * osl_util_read_uptoendtag function:
 * this function reads a file up to a given end tag (this end tag is read)
 * or the end of file. The name of the tag is provided as parameter (hence
 * without the starting "</" end the closing ">"). It puts everything it reads
 * in a string which is returned.
 * \param[in] file The file where to read the tail.
 * \param[in] name The name of the end tag to the file reading.
 * \return The string that has been read from the file.
 */
char * osl_util_read_uptoendtag(FILE * file, char * name) {
  char tag[strlen(name) + 4];
  
  sprintf(tag, "</%s>", name);
  return osl_util_read_uptotag(file, tag);
}


/**
 * osl_util_tag_content function:
 * this function returns a freshly allocated string containing the
 * content, in the given string 'str', between the tag '\<name\>' and
 * the tag '\</name\>'. If the tag '\<name\>' is not found, it returns NULL.
 * \param[in] str    The string where to find a given content.
 * \param[in] name   The name of the tag we are looking for.
 * \return The string between '\<name\>' and '\</name\>' in 'str'.
 */
char * osl_util_tag_content(char * str, char * name) {
  int i;
  char * start;
  char * stop;
  char tag[strlen(name) + 3];
  char endtag[strlen(name) + 4];
  int size = 0;
  int lentag;
  char * res = NULL;

  sprintf(tag, "<%s>", name);
  sprintf(endtag, "</%s>", name);
  
  if (str) {
    start = str;
    lentag = strlen(tag);
    for (; start && *start && strncmp(start, tag, lentag); ++start)
      continue;
    
    // The tag 'tag' was not found.
    if (! *start)
      return NULL;
    start += lentag;
    stop = start;
    lentag = strlen(endtag);
    for (size = 0; *stop && strncmp(stop, endtag, lentag); ++stop, ++size)
      continue;
    
    // the tag 'endtag' was not found.
    if (! *stop)
      return NULL;
    OSL_malloc(res, char *, (size + 1) * sizeof(char));
    
    // Copy the chain between the two tags.
    for (++start, i = 0; start != stop; ++start, ++i)
      res[i] = *start;
    res[i] = '\0';
  }

  return res;
}


/**
 * osl_util_safe_strcat function:
 * this function concatenates the string src to the string *dst
 * and reallocates *dst if necessary. The current size of the
 * *dst buffer must be *hwm (high water mark), if there is some
 * reallocation, this value is updated.
 * \param[in,out] dst pointer to the destination string (may be reallocated).
 * \param[in]     src string to concatenate to dst.
 * \param[in,out] hwm pointer to the size of the *dst buffer (may be updated).
 */
void osl_util_safe_strcat(char ** dst, char * src, int * hwm) {

  while (strlen(*dst) + strlen(src) >= *hwm) {
    *hwm += OSL_MAX_STRING;
    OSL_realloc(*dst, char *, *hwm * sizeof(char));
  }

  strcat(*dst, src);
}


/**
 * osl_util_get_precision function:
 * this function returns the precision defined by the precision environment
 * variable or the highest available precision if it is not defined.
 * \return environment precision if defined or highest available precision.
 */
int osl_util_get_precision() {
  int precision = OSL_PRECISION_DP;
  char * precision_env;

#ifdef OSL_GMP_IS_HERE
  precision = OSL_PRECISION_MP;
#endif

  precision_env = getenv(OSL_PRECISION_ENV);
  if (precision_env != NULL) {
    if (!strcmp(precision_env, OSL_PRECISION_ENV_SP))
      precision = OSL_PRECISION_SP;
    else if (!strcmp(precision_env, OSL_PRECISION_ENV_DP))
      precision = OSL_PRECISION_DP;
    else if (!strcmp(precision_env, OSL_PRECISION_ENV_MP)) {
#ifndef OSL_GMP_IS_HERE
      OSL_warning("$OSL_PRECISION says GMP but osl not compiled with "
                  "GMP support, switching to double precision");
      precision = OSL_PRECISION_DP;
#else
      precision = OSL_PRECISION_MP;
#endif
    }
    else
      OSL_warning("bad OSL_PRECISION environment value, see osl's manual");
  }

  return precision;
}


/**
 * osl_util_print_provided function:
 * this function prints a "provided" boolean in a file (file, possibly stdout),
 * with a comment title according to the OpenScop specification.
 * \param[in] file     File where the information has to be printed.
 * \param[in] provided The provided boolean to print.
 * \param[in] title    A string to use as a title for the provided booblean.
 */
void osl_util_print_provided(FILE * file, int provided, char * title) {
  if (provided) {
    fprintf(file, "# %s provided\n", title);
    fprintf(file, "1\n");
  }
  else {
    fprintf(file, "# %s not provided\n", title);
    fprintf(file, "0\n\n");
  }
}


/**
 * osl_util_identifier_is_here function:
 * this function returns 1 if the input "identifier" is found at the
 * "index" position in the "expression" input string, 0 otherwise.
 * \param[in] expression The input expression.
 * \param[in] identifier The identifier to look for.
 * \param[in] index      The position in the expression where to look.
 * \return 1 if the identifier is found at the position in the expression.
 */
static
int osl_util_identifier_is_here(char * expression, char * identifier,
                                int index) {
  // If there is no space enough to find the identifier: no.
  if (strlen(identifier) + index > strlen(expression))
    return 0;
  
  // If there is a character before and it is in [A-Za-z0-9]: no.
  if ((index > 0) &&
      (((expression[index - 1] >= 'A') && (expression[index - 1] <= 'Z')) || 
       ((expression[index - 1] >= 'a') && (expression[index - 1] <= 'z')) || 
       ((expression[index - 1] >= '0') && (expression[index - 1] <= '9'))))
    return 0;

  // If there is a character after and it is in [A-Za-z0-9]: no.
  if ((strlen(identifier) + index < strlen(expression)) &&
      (((expression[strlen(identifier) + index] >= 'A') &&
        (expression[strlen(identifier) + index] <= 'Z'))   || 
       ((expression[strlen(identifier) + index] >= 'a') &&
        (expression[strlen(identifier) + index] <= 'z'))   || 
       ((expression[strlen(identifier) + index] >= '0') &&
        (expression[strlen(identifier) + index] <= '9'))))
    return 0;

  // If the identifier string is not here: no.
  if (strncmp(expression + index, identifier, strlen(identifier)))
    return 0;

  return 1;
}


/**
 * osl_util_lazy_isolated_identifier function:
 * this function returns 1 if the identifier at the "index" position in the
 * "expression" is guaranteed not to need parenthesis around is we
 * substitute it with anything. For instance the identifier "i" can be
 * always substituted in "A[i]" with no need of parenthesis but not in
 * "A[2*i]". This function is lazy in the sense that it just check obvious
 * cases, not all of them. The identifier must already be at the indicated
 * position, this function does not check that.
 * \param[in] expression The input expression.
 * \param[in] identifier The identifier to check.
 * \param[in] index      The position of the identifier in the expression.
 * \return 1 if the identifier is isolated, 0 if unsure.
 */
static
int osl_util_lazy_isolated_identifier(char * expression, char * identifier,
                                      int index) {
  int look;

  // If the first non-space character before is not in [\[(,\+=]: no. 
  look = index - 1;
  while (look >= 0) {
    if (isspace(expression[look]))
      look--;
    else
      break;
  }

  if ((look >= 0) &&
      (expression[look] != '[') &&
      (expression[look] != '(') &&
      (expression[look] != '+') &&
      (expression[look] != '=') &&
      (expression[look] != ','))
    return 0;
        
  // If the first non-space character after is not in [\]),;\+]: no. 
  look = index + strlen(identifier);
  while (look < strlen(expression)) {
    if (isspace(expression[look]))
      look++;
    else
      break;
  }

  if ((look < strlen(expression)) &&
      (expression[look] != ']')   &&
      (expression[look] != ')')   &&
      (expression[look] != '+')   &&
      (expression[look] != ',')   &&
      (expression[look] != ';'))
    return 0;

  return 1;
}


/**
 * osl_util_identifier_substitution function:
 * this function replaces some identifiers in an input expression string and
 * returns the final string. The list of identifiers to replace are provided
 * as an array of strings. They are replaced from the input string with the
 * new substring "@i@" or "(@i@)" where i is the rank of the identifier in the
 * array of identifiers. The parentheses are added when it is not obvious that
 * the identifier can be replaced with an arbitrary expression without the
 * need of parentheses. For instance, let us consider the input expression
 * "C[i+j]+=A[2*i]*B[j];" and the array of strings {"i", "j"}: the resulting
 * string would be "C[@0@+@1@]+=A[2*(@0@)]*B[@1@];".
 * \param[in] expression The original expression.
 * \param[in] identifiers NULL-terminated array of identifiers.
 * \return A new string where the ith identifier is replaced by \@i\@.
 */
char * osl_util_identifier_substitution(char * expression,
                                        char ** identifiers) {
  int index, j, found;
  int high_water_mark = OSL_MAX_STRING;
  char buffer[OSL_MAX_STRING];
  char * string;
 
  OSL_malloc(string, char *, high_water_mark * sizeof(char));
  string[0] = '\0';

  index = 0;
  while (index < strlen(expression)) {
    j = 0;
    found = 0;
    while (identifiers[j] != NULL) {
      if (osl_util_identifier_is_here(expression, identifiers[j], index)) {
        if (osl_util_lazy_isolated_identifier(expression,identifiers[j],index))
          sprintf(buffer, "@%d@", j);
        else
          sprintf(buffer, "(@%d@)", j);
        osl_util_safe_strcat(&string, buffer, &high_water_mark);
        index += strlen(identifiers[j]);
        found = 1;
        break;
      }
      j++;
    }
    if (!found) {
      sprintf(buffer, "%c", expression[index]);
      osl_util_safe_strcat(&string, buffer, &high_water_mark);
      index++;
    }
  }

  return string;
}



