/*! *********************************************************************** * \brief * Parse the command line parameters and read the config files. * \param ac * number of command line parameters * \param av * command line parameters *********************************************************************** */ void Configure (int ac, char *av[]) { char *content; int CLcount, ContentLen, NumberParams; char *filename=DEFAULTCONFIGFILENAME; memset (&configinput, 0, sizeof (InputParameters)); //Set default parameters. printf ("Setting Default Parameters...\n"); InitEncoderParams(); // Process default config file CLcount = 1; if (ac==2) { if (0 == strncmp (av[1], "-h", 2)) { JMHelpExit(); } } if (ac>=3) { if (0 == strncmp (av[1], "-d", 2)) { filename=av[2]; CLcount = 3; } if (0 == strncmp (av[1], "-h", 2)) { JMHelpExit(); } } printf ("Parsing Configfile %s", filename); content = GetConfigFileContent (filename); if (NULL==content) error (errortext, 300); ParseContent (content, strlen(content)); printf ("\n"); free (content); // Parse the command line while (CLcount < ac) { if (0 == strncmp (av[CLcount], "-h", 2)) { JMHelpExit(); } if (0 == strncmp (av[CLcount], "-f", 2)) // A file parameter? { content = GetConfigFileContent (av[CLcount+1]); if (NULL==content) error (errortext, 300); printf ("Parsing Configfile %s", av[CLcount+1]); ParseContent (content, strlen (content)); printf ("\n"); free (content); CLcount += 2; } else { if (0 == strncmp (av[CLcount], "-p", 2)) // A config change? { // Collect all data until next parameter (starting with -<x> (x is any character)), // put it into content, and parse content. CLcount++; ContentLen = 0; NumberParams = CLcount; // determine the necessary size for content while (NumberParams < ac && av[NumberParams][0] != '-') ContentLen += strlen (av[NumberParams++]); // Space for all the strings ContentLen += 1000; // Additional 1000 bytes for spaces and \0s if ((content = malloc (ContentLen))==NULL) no_mem_exit("Configure: content");; content[0] = '\0'; // concatenate all parameters identified before while (CLcount < NumberParams) { char *source = &av[CLcount][0]; char *destin = &content[strlen (content)]; while (*source != '\0') { if (*source == '=') // The Parser expects whitespace before and after '=' { *destin++=' '; *destin++='='; *destin++=' '; // Hence make sure we add it } else *destin++=*source; source++; } *destin = '\0'; CLcount++; } printf ("Parsing command line string '%s'", content); ParseContent (content, strlen(content)); free (content); printf ("\n"); } else { snprintf (errortext, ET_SIZE, "Error in command line, ac %d, around string '%s', missing -f or -p parameters?", CLcount, av[CLcount]); error (errortext, 300); } } } printf ("\n"); PatchInp(); if (input->DisplayEncParams) DisplayEncoderParams(); }
/*! *********************************************************************** * \brief * Parses the character array buf and writes global variable input, which is defined in * configfile.h. This hack will continue to be necessary to facilitate the addition of * new parameters through the Map[] mechanism (Need compiler-generated addresses in map[]). * \param buf * buffer to be parsed * \param bufsize * buffer size of buffer *********************************************************************** */ void ParseContent (char *buf, int bufsize) { char *items[MAX_ITEMS_TO_PARSE]; int MapIdx; int item = 0; int InString = 0, InItem = 0; char *p = buf; char *bufend = &buf[bufsize]; int IntContent; int i; // Stage one: Generate an argc/argv-type list in items[], without comments and whitespace. // This is context insensitive and could be done most easily with lex(1). while (p < bufend) { switch (*p) { case 13: p++; break; case '#': // Found comment *p = '\0'; // Replace '#' with '\0' in case of comment immediately following integer or string while (*p != '\n' && p < bufend) // Skip till EOL or EOF, whichever comes first p++; InString = 0; InItem = 0; break; case '\n': InItem = 0; InString = 0; *p++='\0'; break; case ' ': case '\t': // Skip whitespace, leave state unchanged if (InString) p++; else { // Terminate non-strings once whitespace is found *p++ = '\0'; InItem = 0; } break; case '"': // Begin/End of String *p++ = '\0'; if (!InString) { items[item++] = p; InItem = ~InItem; } else InItem = 0; InString = ~InString; // Toggle break; default: if (!InItem) { items[item++] = p; InItem = ~InItem; } p++; } } item--; for (i=0; i<item; i+= 3) { if (0 > (MapIdx = ParameterNameToMapIndex (items[i]))) { snprintf (errortext, ET_SIZE, " Parsing error in config file: Parameter Name '%s' not recognized.", items[i]); error (errortext, 300); } if (strcmp ("=", items[i+1])) { snprintf (errortext, ET_SIZE, " Parsing error in config file: '=' expected as the second token in each line."); error (errortext, 300); } // Now interprete the Value, context sensitive... switch (Map[MapIdx].Type) { case 0: // Numerical if (1 != sscanf (items[i+2], "%d", &IntContent)) { snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]); error (errortext, 300); } * (int *) (Map[MapIdx].Place) = IntContent; printf ("."); break; case 1: strcpy ((char *) Map[MapIdx].Place, items [i+2]); printf ("."); break; default: assert ("Unknown value type in the map definition of configfile.h"); } } memcpy (input, &configinput, sizeof (InputParameters)); PatchInp(); }