Logo Search packages:      
Sourcecode: vertex version File versions

utils.c

#include "pconf.h"

void FREE(void *p);
int STRLEN(const char *s);
int STRISYES(const char *s);
char *STRDUP(const char *s);
const char *STRCHR(const char *s, int c);
void STRSTRIP(char *s);
int STRCASECMP(const char *s1, const char *s2);
int STRPFX(const char *str, const char *pfx);
int STRCASEPFX(const char *str, const char *pfx);
extern char *STRLISTAPPEND(char ***list, int *total, const char *s);
extern void STRFREEARRAY(char **list, int total);

char *GETENV(const char *parameter);

FILE *FOPEN(const char *path, const char *mode);
void FCLOSE(FILE *fp);
int FGETC(FILE *fp);
int FPUTC(int c, FILE *fp);
void FSEEKNEXTLINE(FILE *fp);
void FSEEKPASTSPACES(FILE *fp);
char *FGETLINE(FILE *fp);
char *FSEEKNEXTPARAMETER(
        FILE *fp, char *buf, char comment, char delim 
);



/*
 *    Safer form of free().
 */
void FREE(void *p)
{
      if(p == NULL)
          return;

      free(p);

      return;
}

/*
 *    Returns length of string, does not distingush error.
 */
int STRLEN(const char *s)
{
      int len = 0;

      if(s == NULL)
          return(0);

      while((*s) != '\0')
      {
          len++;
          s++;
      }

      return(len);
}

/*
 *    Returns true if string s implies a `yes'.
 */
int STRISYES(const char *s)
{
      if(s == NULL)
          return(0);

      while(ISBLANK(*s))
          s++;

      /* Yes? */
      if(toupper(*s) == 'Y')
          return(1);
      /* On? */
      if(STRCASEPFX(s, "ON"))
          return(1);
      /* True? */
      if(toupper(*s) == 'T')
          return(1);
      /* All else non-zero number? */
      if((*s) != '0')
          return(1);

      return(0);
}

/*
 *    Safer form of strdup().
 */
char *STRDUP(const char *s)
{
      int len;
      char *sr = NULL, *sr_ptr;

      if(s == NULL)
          return(sr);

      len = STRLEN(s);
      sr = sr_ptr = (char *)malloc((len + 1) * sizeof(char));
      if(sr == NULL)
          return(sr);

      while((*s) != '\0')
      {
          *sr_ptr++ = *s++;
      }
      (*sr_ptr) = '\0';

      return(sr);
}

/*
 *    Returns the position of c in s or NULL on no match.
 */
const char *STRCHR(const char *s, int c)
{
      if((s == NULL) || ((char)c == '\0'))
          return(NULL);

      while((*s) != '\0')
      {
          if((*s) == (char)c)
            return(s);
          s++;
      }

      return(NULL);
}

/*
 *      Strips blank characters leading and tailing string s.
 */
void STRSTRIP(char *s)
{
        int tar, src, lead, tail;

        if(s == NULL)
            return;
        if((*s) == '\0')
            return;

        /* Strip leading blank characters. */
        lead = 0;
        while(ISBLANK(s[lead]))
            lead++;

        if(lead > 0)
        {
            for(tar = 0, src = lead; s[src] != '\0'; tar++, src++)
                s[tar] = s[src];

            s[tar] = '\0';

            /* Calculate tail position. */
            tail = (tar > 0) ? tar - 1 : 0;
        }
        else
        {
            /* Calculate tail position. */
            tar = STRLEN(s);
            tail = (tar > 0) ? tar - 1 : 0;
        }

        /* Strip tailing blank characters. */
        for(tar = tail; tar >= 0; tar--)
        {
            if(ISBLANK(s[tar]))  
                s[tar] = '\0';
            else
                break;
        }

        return;
}


/*
 *    Returns 1 for no match and 0 for match.
 */
int STRCASECMP(const char *s1, const char *s2)
{
        if((s1 == NULL) ||
           (s2 == NULL)
        )
            return(1);  /* False. */

        while((*s1) && (*s2))
        {
            if(toupper(*s1) != toupper(*s2))
                return(1);      /* False. */

            s1++;
            s2++;
        }

        if((*s1) == (*s2))
            return(0);  /* True. */
        else
            return(1);  /* False. */
}

/*
 *      Returns true if pfx is a prefix of str (case insensitive),
 *    otherwise returns false.
 */
int STRPFX(const char *str, const char *pfx)
{
        /* If either strings is NULL, return false. */
        if((str == NULL) ||
           (pfx == NULL)
        )       
            return(0);

        /* If pfx contains no characters, return false. */
        if((*pfx) == '\0') 
            return(0);  

        /* Begin prefix matching. */
        while((*pfx) != '\0')
        {
            if((*str) != (*pfx))
                return(0);

            str++; pfx++;
        }

        return(1);
}

/*
 *    Returns true if pfx is a prefix of str (case insensitive),
 *    otherwise returns false.
 */
int STRCASEPFX(const char *str, const char *pfx)
{
        /* If either strings is NULL, return false. */
        if((str == NULL) ||
           (pfx == NULL)
        )
            return(0);

        /* If pfx contains no characters, return false. */
        if((*pfx) == '\0')
            return(0);

        /* Begin prefix matching. */
        while((*pfx) != '\0')
        {
            if(toupper(*str) != toupper(*pfx))  
                return(0);

            str++; pfx++;
        }

        return(1);
}

/*
 *    Dupliates string s (may not be NULL) and adds it to the given
 *    list.
 *
 *    Reallocates the given list and increases the total.
 *
 *    Returns pointer to duplicated string or NULL on error.
 */
char *STRLISTAPPEND(char ***list, int *total, const char *s)
{
      int i;
      char *ns;

      if((list == NULL) || (total == NULL) || (s == NULL))
          return(NULL);

      if((*total) < 0)
          (*total) = 0;

      ns = STRDUP(s);
      if(ns == NULL)
          return(NULL);

      i = (*total);
      (*total) = i + 1;

      (*list) = (char **)realloc(
          *list, (*total) * sizeof(char *)
      );
      if((*list) == NULL)
      {
          (*total) = 0;
          FREE(ns);
          return(NULL);
      }

      (*list)[i] = ns;  

      return(ns);
}

/*
 *    Deallocates the given list of strings.
 */
void STRFREEARRAY(char **list, int total)
{
      int i;

      if(list == NULL)
          return;

      for(i = 0; i < total; i++)
          FREE(list[i]);

      FREE(list);

      return;
}


/*
 *    Safe form of getenv().
 */
char *GETENV(const char *parameter)
{
      if(parameter == NULL)
          return(NULL);

      return(getenv(parameter));
}


/*
 *    Opens a file, returns its handle or NULL on failure. Works
 *    just like ansi fopen().
 */
FILE *FOPEN(const char *path, const char *mode)
{
      if((path == NULL) || (mode == NULL))
          return(NULL);
      else
          return(fopen(path, mode));
}

/*
 *    Closes a file opened by FOPEN.
 */
void FCLOSE(FILE *fp)
{
      if(fp == NULL)
          return;

      fclose(fp);

      return;
}

/*
 *    Safe form of fgetc.
 */
int FGETC(FILE *fp)
{
      if(fp == NULL)
          return(EOF);
      else
          return(fgetc(fp));
}

/*
 *    Safe form of fputc.
 */
int FPUTC(int c, FILE *fp)
{
      if(fp == NULL)
          return(EOF);
      else
          return(fputc(c, fp));
}


/*
 *    Seeks to next line, escape sequences will be parsed.
 */
void FSEEKNEXTLINE(FILE *fp)
{
        int c;

        if(fp == NULL)
            return;

        do
        {
            c = FGETC(fp);

            /* Escape sequence? */
            if(c == '\\')
                c = FGETC(fp);
            /* New line? */
            else if(ISCR(c))
                break;

        } while(c != EOF);

        return;
}

/*
 *      Seeks fp past any spaces.
 */
void FSEEKPASTSPACES(FILE *fp)
{
        int c;

        if(fp == NULL)
            return;

        while(1)
        {
            c = FGETC(fp);
            if(c == EOF)
                break;
  
            if(ISBLANK(c))
                continue;
         
            fseek(fp, -1, SEEK_CUR);
            break;
        }

        return;
}

/*
 *    String is loaded literally and only escape sequence handled is
 *    the occurance of two characters '\\' '\n' and where the '\n'
 *    character will be saved into the return string.
 *
 *    Spaces will not be striped, the fp will be positioned after the
 *    non-escaped newline or EOF (whichever is encountered first).
 *
 *    Return must be deallocated by calling function.
 */
char *FGETLINE(FILE *fp)
{
        int c, i, len = 0;
        char *strptr = NULL;
        char *strptr2;

        if(fp == NULL)
            return(strptr);

        /* Begin reading string from file. */

        /* Get first character. */
        c = FGETC(fp);
        if(c == EOF)
            return(strptr);

        /* Read string. */
        while(1)
        {           
            i = len;    /* Current string index i. */
            len++;      /* Current string length. */

            /* Reallocate string buffer. */
            strptr = (char *)realloc(strptr, len * sizeof(char));
            if(strptr == NULL)
                break;

            strptr2 = &(strptr[i]);     /* Pointer to current string index. */
            (*strptr2) = c;             /* Set new character value. */

            /* End of the line? */
            if((c == EOF) ||
               ISCR(c)
            )
            {
                (*strptr2) = '\0';
                break;
            }
            /* Escape sequence? */
            else if(c == '\\')
            {
                /* Read next character after backslash. */
                c = FGETC(fp);
                if(c == EOF)
                {
                    continue;
                }   
                else if(ISCR(c))
                {
                    /* New line, store it as is. */
                    (*strptr2) = c;
                }
                else if(c == '\\')
            {
                /* Another backslash, store as a single backslash. */
                (*strptr2) = c;
            }
            else
                {
                    /* All other escaped characters leave as is
                     * it will be set on the next loop.
                     */
                    continue; 
                }

                /* Read next character. */
                c = FGETC(fp);
            }
            /* Regular character. */
            else
            {
                /* Read next character. */
                c = FGETC(fp);
            }
        }

        return(strptr);
}

/*
 *    Fetches the next parameter found at the file position fp.
 *
 *    If buf is NULL then a newly allocated string will be returned
 *    containing the fetched parm. If buf is not NULL, then buf will
 *    be realloc()'ed and returned as a new pointer containing
 *    the fetched parm.
 *
 *    If EOF is reached by the given fp position, then NULL will
 *    be returned and the given buf will have been free()ed by this
 *    function.
 */
char *FSEEKNEXTPARAMETER(
        FILE *fp, char *buf, char comment, char delim 
)
{
#ifndef FREAD_ALLOC_CHUNK_SIZE
# define FREAD_ALLOC_CHUNK_SIZE     8
#endif
        int c, buf_pos = 0, buf_len, buf_inc = FREAD_ALLOC_CHUNK_SIZE;

        if(fp == NULL)
        {
            FREE(buf);
            return(NULL);
        }

        /* Get length of buf (less than actual allocated is okay). */
        buf_len = ((buf == NULL) ? 0 : STRLEN(buf));

        /* Seek past spaces and comments to next parameter. */
        while(1)
        {
            FSEEKPASTSPACES(fp);
            c = FGETC(fp);
            if(c == EOF)
            {
                FREE(buf);
                return(NULL);
            }   
            else if(c == comment)
            {
                FSEEKNEXTLINE(fp);
                continue;
            }
            else if(ISCR(c))
            {
                continue;
            }
            else
            {
                fseek(fp, -1, SEEK_CUR);
                break;
            }
        }

        /* Begin fetching this parm. */
        while(1)
        {
            /* Get next char. */
            c = FGETC(fp);
            if(c == EOF)
            {
                break;
            }   

            /* Blank character reached? */
            if(ISBLANK(c))
            {
                /* Blank char reached, seek past delimiantor and position
                 * fp at beginning of value.
                 */
                if(delim == '\0')
                {
                    FSEEKPASTSPACES(fp);
                }
                else
                {
                    FSEEKPASTSPACES(fp);
             
                    /* Seek to deim or newline. */
                    do
                    {
                        c = FGETC(fp);
                        if((c == EOF) || (c == delim))
                            break;
             
                        if(ISCR(c))
                        {
                            fseek(fp, -1, SEEK_CUR);
                            break;
                        }
        
                    } while(1);
            
                    FSEEKPASTSPACES(fp);
                }
                break;
            }

            /* CR reached? */
            if(ISCR(c))
            {
                fseek(fp, -1, SEEK_CUR);
                break;
            }

            /* Deliminator reached? */  
            if(c == delim)
            {
                FSEEKPASTSPACES(fp);
                break;
            }

            /* Need to allocate buffer? */
            if(buf_pos <= buf_len)
            {
                buf_len += buf_inc;
                            
                buf = (char *)realloc(buf, buf_len * sizeof(char));
                if(buf == NULL)
                {
                    FSEEKNEXTLINE(fp);
                    return(NULL); 
                }
            }

            buf[buf_pos] = (char)c;
            buf_pos++;
        }

        /* Put null terminating byte on buffer. */
        if(c == EOF)
        {
            FREE(buf); 
            buf = NULL;
        }
        else
        {
            if(buf_pos <= buf_len)
            {
                buf_len = buf_pos + 1;
             
                buf = (char *)realloc(buf, buf_len * sizeof(char));
                if(buf == NULL)
                    return(NULL);
            }       
            buf[buf_pos] = '\0';
        }

        return(buf);
}

Generated by  Doxygen 1.6.0   Back to index