C/Read an ini file

From Attie's Wiki
(Redirected from Read an ini file)
Jump to: navigation, search
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define CHUNK_SIZE 128
 
enum lineTypes {
  unknown,
  empty,
  comment,
  sectionHead,
  variableOnly,
  variableValue
};
 
struct lineByLine {
  char *line;
  int length;
  enum lineTypes type;
};
 
int main(int argc, char *argv[]) {
 
  FILE *f;
  void *p;
 
  struct lineByLine *lines;
  struct lineByLine *tline;
  int linec;
 
  int isNewline;
  char *c; /* contents*/
  int i;
  int l; /* length */
  int r; /* amount read */
  int s; /* memory size */
  int printedLines;
 
  f = fopen("php.ini","r");
  if (!f) {
    perror("fopen()");
    goto die;
  }
 
  c = NULL;
  l = 0;
  s = 0;
  while (!feof(f)) {
    s += CHUNK_SIZE;
    p = realloc(c, sizeof(char) * s);
    if (!p) {
      perror("realloc()");
      goto die1;
    }
    c = p;
    r = fread(&(c[l]), 1, s - l, f);
    if (!r) {
      if (feof(f)) break;
      /* else error */
      fprintf(stderr,"fread(): An error occured\n");
      goto die1;
    } else if (r < 0) {
      perror("fread()");
      break;
    }
    l += r;
  }
 
  p = realloc(c, sizeof(char) * (l + 1));
  if (!p) {
    perror("realloc()");
  } else {
    c = p;
  }
 
  c[l] = '\0';
 
  lines = NULL;
  linec = 0;
  isNewline = 1;
  for (i = 0; i <= l; i++) {
    if (isNewline) {
      isNewline = 0;
      p = realloc(lines, sizeof(struct lineByLine) * (linec + 1));
      if (!p) {
        perror("realloc()");
        goto die2;
      }
      lines = p;
      tline = &(lines[linec]);
      tline->line = &(c[i]);
      tline->length = -1;
      tline->type = unknown;
      linec++;
    }
    if (i == l || c[i] == '\n') {
      isNewline = 1;
      if (i < l) c[i] = '\0';
      if (linec > 0) {
        tline = &(lines[linec-1]);
        tline->length = strlen(tline->line);
        switch (tline->line[0]) {
          case '\0': tline->type = empty; break;
          case ';':  tline->type = comment; break;
          case '[':  tline->type = sectionHead; break;
          default:
            if (strchr(tline->line,'=')) {
              tline->type = variableValue;
            } else {
              tline->type = variableOnly;
            }
        }
      }
    }
  }
 
  printedLines = 0;
  for (i = 0; i < linec; i++) {
    tline = &(lines[i]);
    switch (tline->type) {
      case sectionHead:
        if (printedLines) printf("\n");
      case variableOnly:
      case variableValue:
        printf("%s\n", tline->line);
        printedLines++;
        break;
      case empty:
      case unknown:
      case comment:
        break;
    }
  }
 
  return 0;
die2:
  if (lines) free(lines);
die1:
  if (c) free(c);
die:
  return 1;
}
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox