/* +JMJ * inifile.c - INI file reader/parser module * 2014 David Meyer <papa@sdf.org> * * Primitive objects: * i: scanned INI file property data * p: property (section/key name combination) * s: section * k: key name * v: value */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "krcompat.h" #include "adamstyl.h" #include "inifile.h" void parse_property PARAMS((char* linein, char* wcurrs)); void parse_section PARAMS((char* linein, char* wcurrs)); int nump = 0; char vsop[MAXP][LENW]; char vkop[MAXP][LENW]; char kvop[MAXP][LENL]; int nums = 0; char vsection[MAXS][LENW]; int icurrp, icurrs; char wsearchs[LENW]; /* iproprty - Return index of property or -1 for undefined */ int iproprty (wsection, wkey) char* wsection; char* wkey; { int ip = 0; while (ip < nump && (strcmp (vsop[ip], wsection) != 0 || strcmp (vkop[ip], wkey) != 0)) ip++; if (ip < nump) return ip; else return -1; } /* ireadi - Read and parse groups/keys/values from specified INI file * Returns number of keys processed */ int ireadi (winifn) char* winifn; { FILE* xinif; char lin[LENL]; char wcurrs[LENW] = ""; xinif = fopen (winifn, "r"); while ((int) fgets (lin, LENL, xinif) != EOF) { switch (lin[0]) { case '#': case ';': case ' ': case '\t': case '\n': case '\r': case '\0': break; case '[': parse_section (lin, wcurrs); break; default: parse_property (lin, wcurrs); } } return 0; } /* ireseti - forget all group/key/value data */ int ireseti () { int ip, is; for (ip = 0; ip < nump+1; ip++) { vsop[ip][0] = '\0'; vkop[ip][0] = '\0'; kvop[ip][0] = '\0'; } nump = 0; for (is = 0; is < nums+1; is++) { vsection[is][0] = '\0'; } nums = 0; return 0; } /* isection - Return index for section or -1 if section not defined */ int isection (wsection) char* wsection; { int is = 0; while (is < nums && strcmp (vsection[is], wsection) != 0) is++; if (is == nums) return -1; else return is; } /* lvop - Value string of specified group/key * Returns null string for group/key not defined or group/key * defined without value (use iproprty() to differentiate) */ char* lvop (wsection, wkey) char* wsection; char* wkey; { int ip = 0; while (ip < nump && strcmp (vsop[ip], wsection) != 0 && strcmp (vkop[ip], wkey) != 0) ip++; if (ip == nump) return ""; else return kvop[ip]; } /* parse_property - parse property name and value from input * line and record with section name. */ void parse_property (lin, wcurrs) char* lin; char* wcurrs; { char wkey[LENW]; char lvalue[LENL]; int i, ilenl, ilenk, ioldp; ilenl = strlen (lin); for (i = 0; i < ilenl && lin[i] != '='; i++) wkey[i] = lin[i]; wkey[i] = '\0'; ilenk = i; if (lin[i] == '=') i++; while (i < ilenl) { lvalue[i-ilenk-1] = lin[i]; i++; } lvalue[i-ilenk-1] = '\0'; ioldp = iproprty (wcurrs, wkey); if (ioldp > -1) strcpy (lvalue, kvop[ioldp]); else { if (nump == MAXP) { fprintf (stderr, "Error: more than MAXP INI file properties\n"); exit (1); } strcpy (wcurrs, vsop[nump]); strcpy (wkey, vkop[nump]); strcpy (lvalue, kvop[nump]); nump++; if (isection (wcurrs) == -1) { if (nums == MAXS) { fprintf (stderr, "Error: more than MAXS INI file sections\n"); exit (1); } strcpy (wcurrs, vsection[nums]); nums++; } } } /* parse_section - parse section name from input line. */ void parse_section (lin, wcurrs) char* lin; char* wcurrs; { int i, n; n = strlen (lin); for (i = 1; lin[i] != ']' && i < n; i++) wcurrs[i-1] = lin[i]; wcurrs[n-2] = '\0'; } /* wfkos - First key name in specified section */ char* wfkos (wsection) char* wsection; { icurrp = 0; while (icurrp < nump && strcmp (vsop[icurrp], wsection) != 0) icurrp++; if (icurrp < nump) { strcpy (wsection, wsearchs); return vkop[icurrp]; } else { icurrp = 0; wsearchs[0] = '\0'; return ""; } } /* wfsoi - First section name */ char* wfsoi () { if (nums > 0) { icurrs = 0; return vsection[0]; } else return ""; } /* wnkos - Next key in previously previously specified section */ char* wnkos () { icurrp++; if (icurrp < nump && strcmp (vsop[icurrp], wsearchs) == 0) return vkop[icurrp]; else { icurrp = 0; wsearchs[0] = '\0'; return ""; } } /* wnsoi - Next section name */ char* wnsoi () { icurrs++; if (nums > icurrs) { return vsection[icurrs]; } else return ""; }