cstring

cstring.c

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

strState is the set of states to be used by stateFilter to process text.

typedef enum { strStart, strPrint, strNStates } strState;

strTable

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

strRules describes the state transitions and text substitutions to be used by stateFilter to process text.

static filterRules strRules[] =
{
    { "", "\t\"", strStart, strPrint, 0 },
    { "\"", "\\\"", strPrint, strPrint, 0 },
    { "\\", "\\\\", strPrint, strPrint, 0 },
    { "\t", "\\t", strPrint, strPrint, 0 },
    { "\n", "\",\n", strPrint, strStart, 0 },    
    { 0 }
};

fileToCStrings

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

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