+ // Read the file for real
+ for(
+ ptr = FileData, i = 0;
+ *ptr;
+ i++
+ )
+ {
+ start = ptr;
+
+ ret->Lines[i].nParts = 0;
+
+ // Count parts
+ for(;;)
+ {
+ // Read leading whitespace
+ while( *ptr == '\t' || *ptr == ' ' ) ptr++;
+
+ // End of line/file
+ if( *ptr == '\0' || *ptr == '\n' ) {
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
+ // Comment
+ if( *ptr == '#' || *ptr == ';' ) {
+ while( *ptr && *ptr != '\n' ) ptr ++;
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
+
+ ret->Lines[i].nParts ++;
+ // Quoted
+ if( *ptr == '"' ) {
+ ptr ++;
+ while( *ptr && !(*ptr == '"' && ptr[-1] == '\\') && *ptr != '\n' )
+ ptr++;
+ continue;
+ }
+ // Unquoted
+ while( *ptr && !(*ptr == '\t' || *ptr == ' ') && *ptr != '\n' )
+ ptr++;
+ }
+
+ LOG("ret->Lines[%i].nParts = %i", i, ret->Lines[i].nParts);
+
+ if( ret->Lines[i].nParts == 0 ) {
+ ret->Lines[i].Parts = NULL;
+ continue;
+ }
+
+ // Allocate part list
+ ret->Lines[i].Parts = malloc( sizeof(char*) * ret->Lines[i].nParts );
+
+ // Fill list
+ for( ptr = start, j = 0; ; j++ )
+ {
+ // Read leading whitespace
+ while( *ptr == '\t' || *ptr == ' ' ) ptr++;
+
+ // End of line/file
+ if( *ptr == '\0' || *ptr == '\n' ) {
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
+ // Comment
+ if( *ptr == '#' || *ptr == ';' ) {
+ while( *ptr && *ptr != '\n' ) ptr ++;
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
+
+ ret->Lines[i].Parts[j] = ptr;
+
+ // Quoted
+ if( *ptr == '"' ) {
+ ptr ++;
+ while( *ptr && !(*ptr == '"' && ptr[-1] == '\\') && *ptr != '\n' )
+ ptr++;
+ }
+ // Unquoted
+ else {
+ while( *ptr != '\t' && *ptr != ' ' && *ptr != '\n' )
+ ptr++;
+ }
+
+ // Break if we have reached NULL
+ if( *ptr == '\0' ) {
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
+ break;
+ }
+ if( *ptr == '\n' ) {
+ *ptr = '\0';
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
+ ptr ++;
+ break;
+ }
+ *ptr = '\0'; // Cap off string
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
+ ptr ++; // And increment for the next round
+ }
+ }