252 lines
7.7 KiB
C++
252 lines
7.7 KiB
C++
|
/*
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||
|
* file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_END@
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "ConfParser.h"
|
||
|
#include "OSMemory.h"
|
||
|
|
||
|
#include "MyAssert.h"
|
||
|
#include "OSHeaders.h"
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "GetWord.h"
|
||
|
#include "Trim.h"
|
||
|
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
|
||
|
static Bool16 SampleConfigSetter( const char* paramName, const char* paramValue[], void* userData );
|
||
|
static void DisplayConfigErr( const char*fname, int lineCount, const char*lineBuff, const char *errMessage );
|
||
|
|
||
|
|
||
|
|
||
|
void TestParseConfigFile()
|
||
|
{
|
||
|
ParseConfigFile( false, "qtss.conf", SampleConfigSetter, NULL );
|
||
|
|
||
|
}
|
||
|
|
||
|
static Bool16 SampleConfigSetter( const char* paramName, const char* paramValue[], void* /*userData*/ )
|
||
|
{
|
||
|
qtss_printf( "param: %s", paramName );
|
||
|
|
||
|
int x = 0;
|
||
|
|
||
|
while ( paramValue[x] )
|
||
|
{
|
||
|
qtss_printf( " value(%"_S32BITARG_"): %s ", (SInt32)x, (char *) paramValue[x] );
|
||
|
x++;
|
||
|
}
|
||
|
|
||
|
qtss_printf( "\n" );
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void DisplayConfigErr( const char*fname, int lineCount, const char*lineBuff, const char *errMessage )
|
||
|
{
|
||
|
|
||
|
qtss_printf( "- Configuration file error:\n" );
|
||
|
|
||
|
|
||
|
if ( lineCount )
|
||
|
qtss_printf( " file: %s, line# %i\n", fname, lineCount );
|
||
|
else
|
||
|
qtss_printf( " file: %s\n", fname );
|
||
|
|
||
|
if ( lineBuff )
|
||
|
qtss_printf( " text: %s", lineBuff ); // lineBuff already includes a \n
|
||
|
|
||
|
if ( errMessage )
|
||
|
qtss_printf( " reason: %s\n", errMessage ); // lineBuff already includes a \n
|
||
|
}
|
||
|
|
||
|
|
||
|
int ParseConfigFile(
|
||
|
Bool16 allowNullValues
|
||
|
, const char* fname
|
||
|
, Bool16 (*ConfigSetter)( const char* paramName, const char* paramValue[], void* userData )
|
||
|
, void* userData )
|
||
|
{
|
||
|
int error = -1;
|
||
|
FILE *configFile;
|
||
|
int lineCount = 0;
|
||
|
|
||
|
Assert( fname );
|
||
|
Assert( ConfigSetter );
|
||
|
|
||
|
|
||
|
if (!fname) return error;
|
||
|
if (!ConfigSetter) return error;
|
||
|
|
||
|
|
||
|
configFile = fopen( fname, "r" );
|
||
|
|
||
|
// Assert( configFile );
|
||
|
|
||
|
if ( configFile )
|
||
|
{
|
||
|
SInt32 lineBuffSize = kConfParserMaxLineSize;
|
||
|
SInt32 wordBuffSize = kConfParserMaxParamSize;
|
||
|
|
||
|
|
||
|
char lineBuff[kConfParserMaxLineSize];
|
||
|
char wordBuff[kConfParserMaxParamSize];
|
||
|
|
||
|
char *next;
|
||
|
|
||
|
// debug assistance -- CW debugger won't display large char arrays as strings
|
||
|
//char* l = lineBuff;
|
||
|
//char* w = wordBuff;
|
||
|
|
||
|
|
||
|
do
|
||
|
{
|
||
|
next = lineBuff;
|
||
|
|
||
|
// get a line ( fgets adds \n+ 0x00 )
|
||
|
|
||
|
if ( fgets( lineBuff, lineBuffSize, configFile ) == NULL )
|
||
|
break;
|
||
|
|
||
|
lineCount++;
|
||
|
error = 0; // allow empty lines at beginning of file.
|
||
|
|
||
|
// trim the leading whitespace
|
||
|
next = TrimLeft( lineBuff );
|
||
|
|
||
|
if (*next)
|
||
|
{
|
||
|
|
||
|
if ( *next == '#' )
|
||
|
{
|
||
|
// it's a comment
|
||
|
// prabably do nothing in release version?
|
||
|
|
||
|
// qtss_printf( "comment: %s" , &lineBuff[1] );
|
||
|
|
||
|
error = 0;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{ char* param;
|
||
|
|
||
|
// grab the param name, quoted or not
|
||
|
if ( *next == '"' )
|
||
|
next = GetQuotedWord( wordBuff, next, wordBuffSize );
|
||
|
else
|
||
|
next = GetWord( wordBuff, next, wordBuffSize );
|
||
|
|
||
|
Assert( *wordBuff );
|
||
|
|
||
|
param = NEW char[strlen( wordBuff ) + 1 ];
|
||
|
|
||
|
Assert( param );
|
||
|
|
||
|
if ( param )
|
||
|
{
|
||
|
const char* values[kConfParserMaxParamValues+1];
|
||
|
int maxValues = 0;
|
||
|
|
||
|
strcpy( param, wordBuff );
|
||
|
|
||
|
|
||
|
values[maxValues] = NULL;
|
||
|
|
||
|
while ( maxValues < kConfParserMaxParamValues && *next )
|
||
|
{
|
||
|
// ace
|
||
|
next = TrimLeft( next );
|
||
|
|
||
|
if (*next)
|
||
|
{
|
||
|
if ( *next == '"' )
|
||
|
next = GetQuotedWord( wordBuff, next, wordBuffSize );
|
||
|
else
|
||
|
next = GetWord( wordBuff, next, wordBuffSize );
|
||
|
|
||
|
char* value = NEW char[strlen( wordBuff ) + 1 ];
|
||
|
|
||
|
Assert( value );
|
||
|
|
||
|
if ( value )
|
||
|
{
|
||
|
strcpy( value, wordBuff );
|
||
|
|
||
|
values[maxValues++] = value;
|
||
|
values[maxValues] = 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( (maxValues > 0 || allowNullValues) && !(*ConfigSetter)( param, values, userData ) )
|
||
|
error = 0;
|
||
|
else
|
||
|
{ error = -1;
|
||
|
if ( maxValues > 0 )
|
||
|
DisplayConfigErr( fname, lineCount, lineBuff, "Parameter could not be set." );
|
||
|
else
|
||
|
DisplayConfigErr( fname, lineCount, lineBuff, "No value to set." );
|
||
|
}
|
||
|
|
||
|
delete [] param;
|
||
|
|
||
|
maxValues = 0;
|
||
|
|
||
|
while ( values[maxValues] )
|
||
|
{ char** tempValues = (char**)values; // Need to do this to delete a const
|
||
|
delete [] tempValues[maxValues];
|
||
|
maxValues++;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
} while ( feof( configFile ) == 0 && error == 0 );
|
||
|
|
||
|
(void)fclose( configFile );
|
||
|
}
|
||
|
// else
|
||
|
// {
|
||
|
// qtss_printf("Couldn't open config file at: %s\n", fname);
|
||
|
// }
|
||
|
|
||
|
return error;
|
||
|
|
||
|
}
|