src/t_csv_l.c
static void
t_csv_parse( lua_State *L, struct t_csv_row *row )
{
	// CSV/TSV parsing finite state machine
	while (row->ste < T_CSV_RECDNE)
	{
#if PRINT_DEBUGS == 3
		printf( " [%s]\t-[%c][%c][%zu][%c]-   ", t_csv_ste_nme[row->ste], *(row->run), *(row->beg), row->len, row->beg[row->len] );
#endif
		switch (row->ste)
		{
			case T_CSV_DATNKD:
				// TODO: handle escape char
				if (row->dlm == *(row->run))                                 // regular field end
				{
					(row->len)++;
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				}
				else if ('\n' == *(row->run))                                // last field end
				{
					(row->len)++;
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				}
				row->len = (' ' == *(row->run)) ? row->len : row->run - row->beg;       // only progress when not space
				break;
			case T_CSV_DATQTE:
				row->len = row->run - row->beg;                  // don't include last enclosing quote
				if (row->qte == *(row->run))
					row->ste = T_CSV_QTEONE;
				break;
			case T_CSV_QTEONE:
				if (row->dlm == *(row->run))
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else if (row->qte == *(row->run))
					row->ste = T_CSV_QTETWO;
				else
					row->len = (' ' == *(row->run)) ? row->len : row->run - row->beg;       // only progress when not space
				break;
			case T_CSV_QTETWO:
				row->hdb = 1;
				if (row->qte == *(row->run))
					row->ste    = T_CSV_QTEONE;
				else
					row->ste    = T_CSV_DATQTE;
				row->len = row->run - row->beg;       // only progress when not space
				break;
			case T_CSV_FLDBEG:
				// resetting some values for the new field
				row->beg = row->fld = row->run;
				row->hdb = row->hec = row->len = 0;
				if (row->qte == *(row->run))
					row->ste     = T_CSV_QTE1ST;
				else if (' ' == *(row->run))                         // Whitespace ... just keep eating
					;
				else if (row->dlm == *(row->run))                    // ...,,... empty field aka. NULL value
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))                    // ...,,... empty field aka. NULL value
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else
					row->ste = T_CSV_DATNKD;
				break;
			case T_CSV_QTE1ST:
				row->beg    = row->run;
				if (row->qte == *(row->run))
					row->ste = T_CSV_QTE2ND;
				else
					row->ste = T_CSV_DATQTE;
				break;
			case T_CSV_QTE2ND:
				if (row->dlm == *(row->run))                        // is ...,"",...
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))                       // is ...,"",...
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else if (row->qte == *(row->run))
					row->ste = T_CSV_QTETWO;
				break;
			default:
				break;
		}
#if PRINT_DEBUGS == 3
		printf("  [%c][%zu][%c]   [%s]   __%s", *(row->beg), row->len, row->beg[row->len], t_csv_ste_nme[row->ste], row->run );
#endif
		if ('\0' == *(row->run))
			break;
		(row->run)++;
	}
	return;
}
/**--------------------------------------------------------------------------
 * Eat through a CSV line and add fields to a Lua table on the stack
 * \param   L       Lua state.
 * \param   csv     t_csv struct userdata.
 * --------------------------------------------------------------------------*/
Eat through a CSV line and add fields to a Lua table on the stack
\param   L       Lua state.
\param   csv     t_csv struct userdata.
Eat through a CSV line and add fields to a Lua table on the stack \ param L Lua state . \ param csv t_csv struct userdata .
static void
t_csv_parse( lua_State *L, struct t_csv_row *row )
{
	while (row->ste < T_CSV_RECDNE)
	{
#if PRINT_DEBUGS == 3
		printf( " [%s]\t-[%c][%c][%zu][%c]-   ", t_csv_ste_nme[row->ste], *(row->run), *(row->beg), row->len, row->beg[row->len] );
#endif
		switch (row->ste)
		{
			case T_CSV_DATNKD:
				if (row->dlm == *(row->run))                                 
				{
					(row->len)++;
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				}
				else if ('\n' == *(row->run))                                
				{
					(row->len)++;
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				}
				row->len = (' ' == *(row->run)) ? row->len : row->run - row->beg;       
				break;
			case T_CSV_DATQTE:
				row->len = row->run - row->beg;                  
				if (row->qte == *(row->run))
					row->ste = T_CSV_QTEONE;
				break;
			case T_CSV_QTEONE:
				if (row->dlm == *(row->run))
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else if (row->qte == *(row->run))
					row->ste = T_CSV_QTETWO;
				else
					row->len = (' ' == *(row->run)) ? row->len : row->run - row->beg;       
				break;
			case T_CSV_QTETWO:
				row->hdb = 1;
				if (row->qte == *(row->run))
					row->ste    = T_CSV_QTEONE;
				else
					row->ste    = T_CSV_DATQTE;
				row->len = row->run - row->beg;       
				break;
			case T_CSV_FLDBEG:
				row->beg = row->fld = row->run;
				row->hdb = row->hec = row->len = 0;
				if (row->qte == *(row->run))
					row->ste     = T_CSV_QTE1ST;
				else if (' ' == *(row->run))                         
					;
				else if (row->dlm == *(row->run))                    
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))                    
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else
					row->ste = T_CSV_DATNKD;
				break;
			case T_CSV_QTE1ST:
				row->beg    = row->run;
				if (row->qte == *(row->run))
					row->ste = T_CSV_QTE2ND;
				else
					row->ste = T_CSV_DATQTE;
				break;
			case T_CSV_QTE2ND:
				if (row->dlm == *(row->run))                        
					t_csv_pushfield( L, row, T_CSV_FLDBEG );
				else if ('\n' == *(row->run))                       
					t_csv_pushfield( L, row, T_CSV_RECDNE );
				else if (row->qte == *(row->run))
					row->ste = T_CSV_QTETWO;
				break;
			default:
				break;
		}
#if PRINT_DEBUGS == 3
		printf("  [%c][%zu][%c]   [%s]   __%s", *(row->beg), row->len, row->beg[row->len], t_csv_ste_nme[row->ste], row->run );
#endif
		if ('\0' == *(row->run))
			break;
		(row->run)++;
	}
	return;
}
static void t_csv_parse ( lua_State * L , struct t_csv_row * row ) { while ( row -> ste < T_CSV_RECDNE ) { #if PRINT_DEBUGS == 3 printf ( " \t " , t_csv_ste_nme [ row -> ste ] , * ( row -> run ) , * ( row -> beg ) , row -> len , row -> beg [ row -> len ] ) ; #endif switch ( row -> ste ) { case T_CSV_DATNKD : if ( row -> dlm == * ( row -> run ) ) { ( row -> len ) ++ ; t_csv_pushfield ( L , row , T_CSV_FLDBEG ) ; } else if ( ' \n ' == * ( row -> run ) ) { ( row -> len ) ++ ; t_csv_pushfield ( L , row , T_CSV_RECDNE ) ; } row -> len = ( ' ' == * ( row -> run ) ) ? row -> len : row -> run - row -> beg ; break ; case T_CSV_DATQTE : row -> len = row -> run - row -> beg ; if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTEONE ; break ; case T_CSV_QTEONE : if ( row -> dlm == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_FLDBEG ) ; else if ( ' \n ' == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_RECDNE ) ; else if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTETWO ; else row -> len = ( ' ' == * ( row -> run ) ) ? row -> len : row -> run - row -> beg ; break ; case T_CSV_QTETWO : row -> hdb = 1 ; if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTEONE ; else row -> ste = T_CSV_DATQTE ; row -> len = row -> run - row -> beg ; break ; case T_CSV_FLDBEG : row -> beg = row -> fld = row -> run ; row -> hdb = row -> hec = row -> len = 0 ; if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTE1ST ; else if ( ' ' == * ( row -> run ) ) ; else if ( row -> dlm == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_FLDBEG ) ; else if ( ' \n ' == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_RECDNE ) ; else row -> ste = T_CSV_DATNKD ; break ; case T_CSV_QTE1ST : row -> beg = row -> run ; if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTE2ND ; else row -> ste = T_CSV_DATQTE ; break ; case T_CSV_QTE2ND : if ( row -> dlm == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_FLDBEG ) ; else if ( ' \n ' == * ( row -> run ) ) t_csv_pushfield ( L , row , T_CSV_RECDNE ) ; else if ( row -> qte == * ( row -> run ) ) row -> ste = T_CSV_QTETWO ; break ; default : break ; } #if PRINT_DEBUGS == 3 printf ( " " , * ( row -> beg ) , row -> len , row -> beg [ row -> len ] , t_csv_ste_nme [ row -> ste ] , row -> run ) ; #endif if ( ' \0 ' == * ( row -> run ) ) break ; ( row -> run ) ++ ; } return ; }
Eat through a CSV line and add fields to a Lua table on the stack
 \param   L       Lua state.
Eat through a CSV line and add fields to a Lua table on the stack \ param L Lua state .
// CSV/TSV parsing finite state machine // TODO: handle escape char // regular field end // last field end // only progress when not space // don't include last enclosing quote // only progress when not space // only progress when not space // resetting some values for the new field // Whitespace ... just keep eating // ...,,... empty field aka. NULL value // ...,,... empty field aka. NULL value // is ...,"",... // is ...,"",...