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);
}

Responder a