All pastes #372941 Raw Edit

Untitled

public c v1 · immutable
#372941 ·published 2007-02-26 12:11 UTC
rendered paste body
void parse_config(const char *filename){  FILE   *cfile;  char   *fbuf   = NULL;  char   *eip    = NULL;  char   *fptr   = NULL;  struct tconfig_block *block = NULL;  size_t  size   = 0;  size_t  i      = 0;  size_t  count  = 0;  /* For debug purposes */  int line       = 1;  /* No memory allocated at this point, we don't need   * to die nicely   */  if ((cfile = fopen(filename,"r")) == NULL)  {    fprintf(stderr,"Could not open configuration file: %s\n",filename);    exit(EXIT_FAILURE);  }  /* Allocate initial memory for fbuf */  if ((fbuf = malloc(1024)) == NULL)  {    fprintf(stderr, "Could not allocate memory, barfing.\n");    exit(EXIT_FAILURE);  }  /* Read the entire file into memory */  for(i=0;(count = fread(&fbuf[i],1,1024,cfile)) == 1024;i+=1024)  {    if ((fbuf = realloc(fbuf,i+1024+1024)) == NULL)    {      fprintf(stderr,"Could not allocate memory for config file, barfing.\n");      exit(EXIT_FAILURE);    }  }  /* If NOT the end-of-file, we must have had an error of some sort, barf and die */  if (!feof(cfile))  {    fprintf(stderr, "An error occurred while reading the config file\n");    exit(EXIT_FAILURE);  }  /* Terminate it with a NULL */  fbuf[i+count] = '\0';  close(cfile);  /* We now have the config file in memory, now to parse it */  if ((block = malloc(sizeof(struct tconfig_block))) == NULL)  {    fprintf(stderr, "Could not allocate memory for tconfig block\n");    exit(EXIT_FAILURE);  }  block->parent = NULL;  block->child  = NULL;  block->prev   = NULL;  block->next   = NULL;  block->key    = NULL;  block->value  = NULL;  eip = fbuf;  while(*eip)  {    switch (*eip)    {      case '{':        if ((block->child = malloc(sizeof(struct tconfig_block))) == NULL)        {          fprintf(stderr, "Could not allocate memory for tconfig block\n");          exit(EXIT_FAILURE);        }        block->child->parent = block;        block                = block->child;        block->child         = NULL;        block->prev          = NULL;        block->next          = NULL;        block->key           = NULL;        block->value         = NULL;        break;      /* The very left element in tree should have the parent */      case '}':        /* Rewind the list the very left */        while (block->prev != NULL)          block = block->prev;        if (block->parent == NULL)        {          fprintf(stderr, "Mismatched } around line: %d\n",line);          exit(EXIT_FAILURE);        }        block              = block->parent;        break;      /* Ugly comment parsing routines */      case '/':        if (*(eip+1) != '*' || *(eip+1) != '/')        {          fprintf(stderr,"Stray / on line: %d\n",line);          exit(EXIT_FAILURE);        }        /* If comment takes C form */        if (*(eip+1) == '*')        {          /* Skip over /* */          eip+=2;          /* Go until terminating -> */          while (*eip != '\0')          {            if (*(eip+1) == '\0')            {              fprintf(stderr,"Reached end of file while looking for */\n");              exit(EXIT_FAILURE);            }            if (*eip == '*' && *(eip+1) == '/')            {              /* loop increases eip, so only add 1 */              eip++;              break; /* Found end of comment */            }            if (*eip == '\r' && *(eip+1) == '\n')            {              eip++;              line++;            }            else if (*eip == '\n')            {              line++;            }            else if (*eip == '\r')            {              line++;            }            eip++;          }          if (eip == '\0')          {            return;          }        }        else /* // comment, go until \r\n, \n, or \r */        {          eip+=2; /* Skip over // */          while (*eip != '\0')          {            if (*eip == '\r')            {              /* This just means the file is over, not an error */              if (*(eip+1) == '\0')                return;              if (*(eip+1) != '\n')              {                eip++;                line++;                break;              }              else              {                line++;                break;              }            }            else if (*eip == '\n')            {              line++;              break;            }            eip++;          }          if (*eip == '\0')            return;          break;        case '\r':          if (*(eip+1) == '\n')          {            eip++;            line++;          }          else            line++;          if (eip == '\0')            return;          break;        case '\n':          line++;          break;        case '\t':          break;        case ' ':          break;        default:          if (block->key == NULL)          {            /* Do a wasteful scan so I don't have to deal with realloc */            if (*eip != '"')            {              for (i=0;*(eip+i+1) != '\0' && *(eip+i+1) != '\n' && *(eip+i+1) != '\r' &&                       *(eip+i+1) != '"';i++);            }            else            {              for (i=0;*(eip+i) != '\0' && *(eip+i) != '"';i++);              eip++;            }            if (*(eip+i) == '\0')            {              fprintf(stderr, "Reached end of file while looking for value on line %d\n",line);              exit(EXIT_FAILURE);            }            size = i;            /* No I'm not off by 1, in the case of a " " string, we're over by 1 */            if ((block->key = malloc(size)) == NULL)            {              fprintf(stderr,"Could not allocate memory for config key\n");              exit(EXIT_FAILURE);            }            for (i=0;*(eip+i) != ' ' && *(eip+i) != '\t';i++)            {              *(block->key+i) = *(eip+i);            }       }    }    eip++; /* While loop increase */  }}