Un poco fuera de tema...
acabo de hacer un parser en C, para archivos tipo .ini, que son mas o
menos asi:
[seccion]
variable = valor
otra variable = otro valor
Esta un tanto especializado, pero se puede usar de ejemplo.
Si a alguen le sirve, me mocho...
Suena interesante. ¿Quizá ponerlo a disposición en la red?
Na, esta muy crudo...
En este ejemplo, tengo que parsear un archivo que tiene un [Global]
y varias secciones de "destinos". Tiene que almacenar varias variables
descritas en la seccion global, y agregar "destinos" a una lista ligada
(lo hace mediante funciones, no escribiendo en la variable directamente)
En fin, se puede dar una idea uno...
Tal vez, en cuanto termine mi proyecto (donde uso esta cosa) publicare
en algun lado una libreria de parseo generica.
--
Alexander aka alk[ anoide | olico | ulero | ero | atraz]
(mi matrializacion es fisica, mi escencia es matematica)
//look for a ini file, if such, parse it
FILE* iniFile;
//temporal storage
char* currentLine;
char* param;
char* value;
//temporal storage of the destination data
char* tmpDestID;
char* tmpDestHost;
bool tmpDestPASV;
char* tmpDestUser;
char* tmpDestPass;
char* tmpDestUpld;
char* tmpDestNotf;
int lineSize = 80; //maybe more (:
char c;
bool inGlobal = FALSE;
currentLine = (char*)malloc(lineSize+1);
param = (char*)malloc(lineSize+1);
value = (char*)malloc(lineSize+1);
strcpy(currentLine, "");
strcpy(param, "");
strcpy(value, "");
tmpDestID = (char*)malloc(lineSize+1);
tmpDestHost = (char*)malloc(lineSize+1);
tmpDestUser = (char*)malloc(lineSize+1);
tmpDestPass = (char*)malloc(lineSize+1);
tmpDestUpld = (char*)malloc(lineSize+1);
tmpDestNotf = (char*)malloc(lineSize+1);
strcpy(tmpDestID, "");
tmpDestPASV = TRUE;
strcpy(tmpDestHost,"");
strcpy(tmpDestUser,"");
strcpy(tmpDestPass,"");
strcpy(tmpDestUpld,"");
strcpy(tmpDestNotf,"");
if(iniFile = fopen(iniFileName, "r")) //attempt to open the ini file
{
report("ini file found, parsing...");
while( (c=getc(iniFile)) != EOF) //while not at the end of the file yet
{
free(currentLine); //reset currentLine storage location
currentLine = (char*)malloc(lineSize+1);
strcpy(currentLine, "");
while(c != '\n') //while the end of the line is not reached yet
{
if((int)strlen(currentLine) <= lineSize) //if there is
space to keep writing in the current line
strncat(currentLine, &c, 1); //append the
character to the line
if( (c=getc(iniFile)) == EOF) break; //if the next
character is EOF, end the loop
}
free(param); //reset param and valie storage locations
free(value);
param = (char*)malloc(lineSize+1);
value = (char*)malloc(lineSize+1);
strcpy(param, "");
strcpy(value, "");
while(isspace(*currentLine) && *currentLine != '\0')
++currentLine; //strip whitespaces from the beginnig
while(isspace(*(currentLine + strlen(currentLine) - 1 )) &&
strlen(currentLine) != 0) *(currentLine + strlen(currentLine) - 1) = '\0';
//strip whitespaces from the end
//proceed to parse the line
if(
*currentLine != '[' //it has no "[" at the beginning
&& strchr(currentLine, '=') != NULL //there is a "=" in
the string
&& strchr(currentLine, '=') != currentLine //it's not
at the beginnign
&& strchr(currentLine, '=') != currentLine +
strlen(currentLine) - 1 //nethier at the end
) //so it's a valid parameter=value line
{
//assign data to temporal storage
strcpy(param, strtok(currentLine, "=") );
strcpy(value, strtok(NULL , "=") );
//strip whitespaces
while(isspace(*param) && *param != '\0') ++param;
while(isspace(*value) && *value != '\0') ++value;
while(isspace(*(param + strlen(param) - 1 )) &&
strlen(param) != 0) *(param + strlen(param) - 1) = '\0';
while(isspace(*(value + strlen(value) - 1 )) &&
strlen(value) != 0) *(value + strlen(value) - 1) = '\0';
if(strlen(param) != 0 && strlen(value) != 0)
{
//attempt to parse JT parameters
if(strcmp(param, "jtName") == 0)
set_jtName(value);
if(strcmp(param, "jtMail") == 0)
set_jtMail(value);
if(strcmp(param, "jtComp") == 0)
set_jtComp(value);
if(strcmp(param, "jtDest") == 0)
set_jtDest(atoi(value));
if(strcmp(param, "wsTmp") == 0)
set_wsTempDir(value);
if(strcmp(param, "wsSpl") == 0)
set_wsSplitSize(atol(value));
//attempt to parse destination parameters
if(strcmp(param, "Host") == 0)
strcpy(tmpDestHost,value);
if(strcmp(param, "PASV") == 0)
if(strcmp(value, "no") == 0)
tmpDestPASV = FALSE;
else
tmpDestPASV = TRUE;
if(strcmp(param, "User") == 0)
strcpy(tmpDestUser,value);
if(strcmp(param, "Pass") == 0)
strcpy(tmpDestPass,value);
if(strcmp(param, "Upload") == 0)
strcpy(tmpDestUpld,value);
if(strcmp(param, "Notify") == 0)
strcpy(tmpDestNotf,value);
}
}
if(*currentLine == '[') //assume it's a section delimiter
{
if( strcmp(currentLine,"[Global]") == 0 ) //assume it's
the global section begining
inGlobal = TRUE; //set inGlobal flag
else if(inGlobal) //assume it's global section end
inGlobal = FALSE; // so end it
if(!inGlobal) //assume it's a destination section
beginning
{
//attempt to store the previus destination data
if(
strlen(tmpDestID) != 0 ||
strlen(tmpDestHost) != 0 ||
strlen(tmpDestUser) != 0 ||
strlen(tmpDestPass) != 0 ) //data is
valid
destList->add( new
dest(tmpDestID, tmpDestHost, tmpDestPASV, tmpDestUser, tmpDestPass,
tmpDestUpld, tmpDestNotf) );
else report("data not valid");
//reset the tmpDest data
strcpy(tmpDestID, "");
tmpDestPASV = TRUE;
strcpy(tmpDestHost,"");
strcpy(tmpDestUser,"");
strcpy(tmpDestPass,"");
strcpy(tmpDestUpld,"");
strcpy(tmpDestNotf,"");
//proceed to parse the destination header
++currentLine; //strip the leading "["
if( *(currentLine + strlen(currentLine) - 1) ==
']') //if the line ends on a "]"
*(currentLine + strlen(currentLine) -
1) = '\0'; //strip it,
else continue;
//it's a dirty line, next loop
strcpy(value, currentLine); //store the new ID
found for processing
while(isspace(*value) && *value != '\0')
++value; //strip whitespaces from the beginnig
while(isspace(*(value + strlen(value) - 1 )) &&
strlen(value) != 0) *(value + strlen(value) - 1) = '\0'; //strip whitespaces
from the end
strcpy(tmpDestID, value);
}
}
}
//attempt to store the last destination data
if(
strlen(tmpDestID) != 0 ||
strlen(tmpDestHost) != 0 ||
strlen(tmpDestUser) != 0 ||
strlen(tmpDestPass) != 0 ) //data is valid
destList->add( new dest(tmpDestID, tmpDestHost,
tmpDestPASV, tmpDestUser, tmpDestPass, tmpDestUpld, tmpDestNotf) );
else report("data not valid");
fclose(iniFile);
}