cstring is a command line tool for converting a text file into
an array of C strings. It demonstrates a simple use of file and filter.
Copyright © 2003, 2004 Dave Bayer. Subject to a BSD-style license.
#include "root.h" #include "file.h" #include "filter.h"
strState is the set of states to be used by
stateFilter to process text.
strStart is the initial state, and the state at the start of each line.strPrint is the state within each line, after opening quotes have been
written.strNStates counts the number of states, and is not itself a state.
typedef enum { strStart, strPrint, strNStates } strState;
strTable represents the finite state machine to be passed to stateFilter.
Initialized by initFilterTable, it stores linked lists of rules for each
state/character combination,
in an order implementing longest match.
static filterRules *strTable[strNStates][NCHARS];
strRules describes the state transitions and text substitutions
to be used by stateFilter to process text.
strStart, replace the empty string with an indented opening
double quote \``, and move to statestrPrint`.strPrint, rewrite a double quote \`` as\``.strPrint, rewrite a backslash \\ as \\\\.strPrint, rewrite a tab as \t.strPrint, append a closing double quote and a comma \,to
the end of each line, and move to statestrStart`.
static filterRules strRules[] =
{
{ "", "\t\"", strStart, strPrint, 0 },
{ "\"", "\\\"", strPrint, strPrint, 0 },
{ "\\", "\\\\", strPrint, strPrint, 0 },
{ "\t", "\\t", strPrint, strPrint, 0 },
{ "\n", "\",\n", strPrint, strStart, 0 },
{ 0 }
};
void fileToCStrings( const char *inputFile, const char *outputFile )
{
FILE *fin, *fout;
line *l;
lineFilter filter;
filterState state;
Clear "strTable" and initialize it with the rules specified by "strRules".
initFilterTable( strTable, strRules, strNStates, YES );
filter is the struct to be passed to fileRead, to specify its
filtering behavior. We use a single instance of the filter routine
stateFilter, implementing the finite state machine strTable in
initial state strStart. We are not providing a custom filt routine,
so we set state.filt to null.
filter.filt = stateFilter;
filter.next = 0;
filter.data = &state;
state.table = strTable;
state.state = strStart;
state.filt = 0;
Open the input and output files, aborting on any error.
fin = fileOpen( inputFile, "r", YES );
fout = fileOpen( outputFile, "w", YES );
Read the input file into the linked list l, applying the filter
filter, without detabbing. Write l to the output file, without
applying any filters.
l = fileRead( fin, &filter, 0 );
fprintf( fout, "{\n" );
fileWrite( fout, l, 0 );
fprintf( fout, "\t0\n};\n" );
Close the input and output files, aborting on any error.
fileClose( fin, YES );
fileClose( fout, YES );
Free allocated memory. This is not necessary, because cstring is about
to terminate, but finding memory leaks is one way to find bugs.
lineListFree( l, markFree );
Now check that all allocated memory has been freed.
mallocCount();
}
main checks the command line arguments, and calls fileToCStrings.
int main( int argc, const char *argv[] )
{
if ( argc != 3 )
printf( "Usage: cstring input output\n" );
else
fileToCStrings( argv[1], argv[2] );
return 0;
}