[ragel-users] Re: Fixing an edge case
Adrian Thurston
thurs... at cs.queensu.ca
Tue Jan 16 16:55:33 UTC 2007
Sorry, this was sloppy ... the question mark in the diff machine can be removed.
-Adrian
Adrian Thurston wrote:
> Hi Matt, try the attached file. The important part is in diff machine. The
> first alternative handles the edge case of an empty diff. The second part
> handles the regular case.
>
> -Adrian
>
> >
> jinclude <stdio.h>
>
> %%{
> machine diff;
> action count_line {}
> action mark {}
> action add_line {}
> action push {}
> action push_zero {}
> action pop_hunk_spec {}
> action copy_to_filespec {}
> action enter_hunk { printf(" enter_hunk\n"); }
> action exit_hunk { printf(" exit_hunk\n"); }
> action enter_diff { printf("enter_diff\n"); }
> action exit_diff { printf("exit_diff\n"); }
> action empty_diff { printf(" this diff is empty\n"); }
> action binary_diff {}
> action error {}
>
> nbsp = space - '\n' %count_line;
> lineChar = extend - '\n';
>
> diffLine = ( '\\' lineChar* '\n' %count_line ) |
> ( ' ' | '-' | '+' ) >mark lineChar* '\n' @add_line
> %count_line;
>
> separator = '='+ '\n' %count_line;
>
> oldFile = '---' lineChar+ '\n' %count_line;
> newFile = '+++' lineChar+ '\n' %count_line;
>
> range = ( '-' | '+' ) ( digit+ >mark %push ) ( ' ' %push_zero
> @{ fhold; } | ',' ( digit+ >mark %push ) );
>
> hunkHeader = '@@' nbsp* range nbsp+ range nbsp* '@@' '\n'
> @pop_hunk_spec %count_line;
>
> hunkBody = diffLine+;
>
> hunk = hunkHeader >enter_hunk hunkBody %exit_hunk %/exit_hunk;
>
> fileName = ( lineChar+ ) >mark %copy_to_filespec;
>
> fileSpec = "Index:" nbsp+ fileName '\n'+ @count_line;
>
> diffHeader = fileSpec separator;
>
> diffBody = hunk*;
>
> binaryDiff = 'C' lineChar+ '\n' %count_line lineChar+ '\n'
> %binary_diff %count_line;
>
> textDiff = oldFile newFile diffBody;
>
> diff = (
> diffHeader %empty_diff %/empty_diff |
> diffHeader ( binaryDiff | textDiff ) ?
> )
> >enter_diff %exit_diff %/exit_diff;
>
> main := diff* $!error;
> }%%
>
> %% write data;
>
> int main()
> {
> static char buf[2000000];
> int len = fread( buf, 1, sizeof(buf), stdin );
> printf( "%i\n", len );
>
> int cs;
> char *p = buf, *pe = buf+len;
> %%{
> write init;
> write exec;
> }%%
>
> if ( cs < diff_first_final )
> printf(" ERROR \n" );
> else {
> %% write eof;
> }
> return 0;
> }
>
More information about the ragel-users
mailing list