Update which binlog a job refers to.
[beanstalkd.git] / tests / cutgen.c
blobabf204643c54b061fded0bd4d458cde3273ade37
1 /*
2 * This file has been modified from the original CUT distribution.
4 * CUT 2.3-kr1
5 * Copyright (c) 2001-2002 Samuel A. Falvo II, William D. Tanksley
6 * See CUT-LICENSE.TXT for details.
8 * $Log: cutgen.c,v $
9 * Revision 1.4 2003/03/18 05:53:50 sfalvo
10 * ADD: cutgen.c: cut_exit() -- common exit point; returns proper error code
11 * at all times.
13 * FIX: cutgen.c: Factored all instances of exit() to invoke cut_exit()
14 * instead. This fixes the bug #703793.
16 * Revision 1.3 2003/03/13 04:27:54 sfalvo
17 * ADD: LICENSE.TXT -- zlib license
19 * ADD: README cut.h cutgen.c -- Changelog token for CVS
21 * FIX: test/bringup-failure -- reflects new usage for bringups and
22 * teardowns in CUT 2.2.
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
31 #define DO_NOT_PROCESS "..."
33 #define SEARCH_TOKEN_TEST "__CUT__"
34 #define SEARCH_TOKEN_BRINGUP "__CUT_BRINGUP__"
35 #define SEARCH_TOKEN_TAKEDOWN "__CUT_TAKEDOWN__"
37 #define MAX_SYMBOL_LENGTH 256 /* arbitrary */
38 #define MAX_LINE_LENGTH 1024 /* arbitrary */
40 #define SEARCH_TOKEN_TEST_LENGTH sizeof( SEARCH_TOKEN_TEST )-1
41 #define SEARCH_TOKEN_BRINGUP_LENGTH sizeof( SEARCH_TOKEN_BRINGUP )-1
42 #define SEARCH_TOKEN_TAKEDOWN_LENGTH sizeof( SEARCH_TOKEN_TAKEDOWN )-1
44 typedef enum TestType {
45 TYPE_TEST = 0,
46 TYPE_BRINGUP = 1,
47 TYPE_TAKEDOWN = 2
48 } TestType;
50 typedef struct TestItem {
51 char name[MAX_SYMBOL_LENGTH];
52 enum TestType type;
53 struct TestItem *next;
54 } TestItem;
56 /* globals */
58 TestItem *testList = 0;
59 FILE *outfile;
60 extern char *libCUT[]; /* defined at the end of this file */
62 static int g_count, g_ready, g_index; /* Used by filename globbing support for windows */
63 static char **g_wildcards, g_fileName[MAX_LINE_LENGTH];
65 TestItem *FindFirstMatch( TestItem *current, char *basis_name, int basis_type )
67 while ( current )
69 if ( !strcmp(current->name,basis_name) && current->type == basis_type )
70 return current;
71 current = current->next;
73 return 0;
76 int NameAndTypeInTestList( char *name, TestType type )
78 return 0 != FindFirstMatch(testList,name,type);
81 void AppendToTestList( char *name, TestType type )
83 struct TestItem *current = testList;
84 if ( !current )
85 current = testList = malloc( sizeof( *testList) );
86 else
88 while ( current->next ) current = current->next;
89 current->next = malloc(sizeof( *testList));
90 current = current->next;
93 current->next = 0;
94 strcpy(current->name, name);
95 current->type = type;
98 void InsertNameAndTypeIntoTestList( char *name, TestType type )
100 if ( !NameAndTypeInTestList( name, type ) )
101 AppendToTestList( name, type );
104 int CharacterIsDigit(char ch)
106 return ( ( ch >= '0') && ( ch <= '9' ) );
109 int CharacterIsUppercase(char ch)
111 return ( ( ch >= 'A' ) && ( ch <= 'Z' ) );
114 int CharacterIsLowercase(char ch)
116 return ( ( ch >= 'a' ) && ( ch <= 'z' ) );
119 int CharacterIsAlphabetic(char ch)
121 return CharacterIsUppercase(ch) || CharacterIsLowercase(ch) || ( ch == '_' );
124 int CharacterIsAlphanumeric( char ch )
126 return CharacterIsDigit(ch) || CharacterIsAlphabetic(ch);
129 void ProcessGenericFunction( char *line, int position,
130 TestType type, int tokenDisplacement )
132 char name[MAX_SYMBOL_LENGTH] = "";
133 int maxLength = strlen( line ) - 1, offset=0;
134 position = position + tokenDisplacement;
136 while ( CharacterIsAlphanumeric(line[position])
137 && (position<maxLength) && (offset<MAX_SYMBOL_LENGTH) )
139 name[offset++] = line[position++];
140 name[offset] = 0;
143 InsertNameAndTypeIntoTestList( name, type );
146 void ProcessBringupFunction( char *line, int position )
148 ProcessGenericFunction( line, position, TYPE_BRINGUP, SEARCH_TOKEN_BRINGUP_LENGTH );
151 void ProcessTestFunction( char *line, int position )
153 ProcessGenericFunction( line, position, TYPE_TEST, SEARCH_TOKEN_TEST_LENGTH );
156 void ProcessTakedownFunction( char *line, int position )
158 ProcessGenericFunction( line, position, TYPE_TAKEDOWN, SEARCH_TOKEN_TAKEDOWN_LENGTH );
162 int OffsetOfSubstring( char *line, char *token )
164 char *inset = strstr(line,token);
166 if ( !inset ) return -1;
167 else return inset - line;
170 void CallIfSubstringFound( char *line, char *token, void (*function)(char*,int) )
172 int index = OffsetOfSubstring( line, token );
173 if ( index != -1 )
174 function( line, index );
177 void ProcessSourceFile( char *filename )
179 FILE *source;
180 char line[MAX_LINE_LENGTH];
182 if( strcmp( filename, DO_NOT_PROCESS ) != 0 )
185 source = fopen(filename,"r");
187 while ( fgets(line,MAX_LINE_LENGTH,source) )
189 CallIfSubstringFound( line, SEARCH_TOKEN_BRINGUP, ProcessBringupFunction );
190 CallIfSubstringFound( line, SEARCH_TOKEN_TEST, ProcessTestFunction );
191 CallIfSubstringFound( line, SEARCH_TOKEN_TAKEDOWN, ProcessTakedownFunction );
194 fclose(source);
198 void EmitExternDeclarationFor( char *name, char *prefix )
200 fprintf( outfile, "extern void %s%s( void );\n", prefix, name );
203 void Emit(char *text)
205 fprintf(outfile, "%s\n", text);
208 void BlankLine()
210 Emit( "" );
213 void ListExternalFunctions()
215 TestItem *current = testList;
216 while ( current )
218 if (current->type == TYPE_TEST)
219 EmitExternDeclarationFor( current->name, SEARCH_TOKEN_TEST );
220 else if (current->type == TYPE_BRINGUP)
221 EmitExternDeclarationFor( current->name, SEARCH_TOKEN_BRINGUP );
222 else if (current->type == TYPE_TAKEDOWN)
223 EmitExternDeclarationFor( current->name, SEARCH_TOKEN_TAKEDOWN );
224 current = current->next;
227 BlankLine();
230 void EmitLibrary(void)
232 int i=0;
233 while ( libCUT[i] )
234 Emit(libCUT[i++]);
237 void ListHeaderFiles(void)
239 EmitLibrary();
240 BlankLine();
241 BlankLine();
244 void EmitIndented(int indent,char *format, ...)
246 va_list v;
247 /* Print two spaces per level of indentation. */
248 fprintf( outfile, "%*s", indent*2, "" );
250 va_start(v,format);
251 vfprintf( outfile, format, v );
252 va_end(v);
254 fprintf( outfile, "\n" );
257 void EmitBringup(int indent,char *name)
259 BlankLine();
260 EmitIndented(indent, "cut_start( \"group-%s\", __CUT_TAKEDOWN__%s );",
261 name, name );
262 EmitIndented(indent, "__CUT_BRINGUP__%s();", name );
263 EmitIndented(indent, "cut_check_errors();");
266 void EmitTest(int indent,char *name)
268 EmitIndented(indent, "cut_start( \"%s\", 0 );", name );
269 EmitIndented(indent, "__CUT__%s();", name );
270 EmitIndented(indent, "cut_end( \"%s\" );", name );
273 void EmitTakedown(int indent,char *name)
275 EmitIndented(indent, "cut_end( \"group-%s\" );", name );
276 EmitIndented(indent, "__CUT_TAKEDOWN__%s();", name );
277 BlankLine();
280 void EmitUnitTesterBody()
282 int indent=0;
283 TestItem *test;
284 Emit( "int main( int argc, char *argv[] )\n{" );
285 Emit( " if ( argc == 1 )" );
286 Emit( " cut_init( -1 );" );
287 Emit( " else cut_init( atoi( argv[1] ) );" );
288 BlankLine();
290 indent = 1;
291 test = testList;
292 while ( test )
294 if (test->type == TYPE_BRINGUP)
296 EmitBringup(indent,test->name);
297 indent ++;
300 if (test->type == TYPE_TEST)
301 EmitTest(indent,test->name);
303 if (test->type == TYPE_TAKEDOWN)
305 indent --;
306 EmitTakedown(indent,test->name);
308 test = test->next;
311 BlankLine();
312 Emit( " cut_break_formatting();" );
313 Emit( " printf(\"Done.\");" );
314 Emit( " return 0;\n}\n" );
317 void EmitCutCheck()
319 Emit( "/* Automatically generated: DO NOT MODIFY. */" );
320 ListHeaderFiles();
321 BlankLine();
322 ListExternalFunctions();
323 BlankLine();
324 EmitUnitTesterBody();
327 #if defined(_MSC_VER) // version tested for MS Visual C++ 6.0
328 #include <io.h>
330 void FileName(char *base)
332 char *pos = strrchr(g_wildcards[g_index],'/');
333 char *pos2 = strrchr(g_wildcards[g_index],'\\');
334 if ( !pos || pos2 > pos )
335 pos = pos2;
337 if ( pos )
339 size_t length = 1 + pos - g_wildcards[g_index];
340 strncpy(g_fileName,g_wildcards[g_index],length);
341 g_fileName[length] = 0;
343 else g_fileName[0] = 0;
344 strcat(g_fileName,base);
347 int LoadArgument(void)
349 static struct _finddata_t fd;
350 static long handle = -1;
352 if ( g_index>=g_count )
353 return 0;
355 if ( -1 == handle )
357 handle = _findfirst(g_wildcards[g_index], &fd);
358 if ( -1 == handle ) // there MUST be at least a first match for each wildcard.
359 return 0;
360 FileName(fd.name);
361 return 1;
363 else if ( 0 == _findnext(handle,&fd) )
364 { // there's a 'next' filename
365 FileName(fd.name);
366 return 1;
368 else
369 { // this wasn't the first filename, and there isn't a next.
370 _findclose(handle);
371 handle = -1;
372 g_index++;
373 return LoadArgument();
377 #endif
378 #if defined(__LINUX__)
380 void FileName( char *base )
382 strncpy( g_fileName, base, MAX_LINE_LENGTH );
383 g_fileName[ MAX_LINE_LENGTH - 1 ] = 0;
386 int LoadArgument( void )
388 if ( g_index >= g_count )
389 return 0;
391 FileName( g_wildcards[g_index] );
392 g_index++; /* MUST come after FileName() call; bad code smell */
393 return 1;
396 #endif
398 void StartArguments( int starting, int count, char *array[] )
400 g_index = starting;
401 g_count = count;
402 g_wildcards = array;
404 g_ready = LoadArgument();
407 int NextArgument( void )
409 if( g_ready )
410 g_ready = LoadArgument();
412 return g_ready;
415 char *GetArgument( void )
417 if( g_ready )
418 return g_fileName;
420 return NULL;
423 void EstablishOutputFile( int argc, char *argv[] )
425 int i;
427 i = 0;
428 while( i < argc )
430 if( ( argv[i+1] != NULL ) && ( strcmp( argv[i], "-o" ) == 0 ) )
432 outfile = fopen( argv[i+1], "wb+" );
433 if( outfile == NULL )
434 fprintf( stderr, "ERROR: Can't open %s for writing.\n", argv[i+1] );
436 argv[i] = argv[i+1] = DO_NOT_PROCESS;
438 return;
441 i++;
444 outfile = stdout;
447 int main( int argc,char *argv[] )
449 char *filename;
451 if ( argc < 2 )
453 fprintf(
454 stderr,
455 "USAGE:\n"
456 " %s [options] <input file> [<input file> [...]]\n"
457 "\n"
458 "OPTIONS:\n"
459 " -o filename Specifies output file.\n"
460 "\n"
461 "NOTES:\n"
462 " If -o is left unspecified, output defaults to stdout.\n",
463 argv[0]
465 return 3;
468 EstablishOutputFile( argc, argv );
470 /* Skip the executable's name and the output filename. */
471 StartArguments(0,argc,argv);
473 /* Consume the rest of the arguments, one at a time. */
474 while ( NextArgument() )
476 filename = GetArgument();
478 if( strcmp( filename, DO_NOT_PROCESS ) )
480 fprintf( stderr, " - parsing '%s'... ", filename);
481 ProcessSourceFile( filename );
482 fprintf( stderr, "done.\n");
486 EmitCutCheck();
487 fflush(outfile);
488 fclose(outfile);
489 return 0;
492 char * libCUT[] =
494 "/*",
495 " * libcut.inc",
496 " * CUT 2.1",
497 " *",
498 " * Copyright (c) 2001-2002 Samuel A. Falvo II, William D. Tanksley",
499 " * See CUT-LICENSE.TXT for details.",
500 " *",
501 " * Based on WDT's 'TestAssert' package.",
502 " *",
503 " * $log$",
504 " */",
506 "#include <string.h>",
507 "#include <stdlib.h>",
508 "#include <stdio.h>",
509 "#include <stdarg.h>",
510 "#include \"cut.h\"",
512 "#ifndef BOOL /* Just in case -- helps in portability */",
513 "#define BOOL int",
514 "#endif",
516 "#ifndef FALSE",
517 "#define FALSE (0)",
518 "#endif",
520 "#ifndef TRUE",
521 "#define TRUE 1",
522 "#endif",
524 "typedef struct NameStackItem NameStackItem;",
525 "typedef struct NameStackItem *NameStack;",
527 "struct NameStackItem",
528 "{",
529 " NameStackItem * next;",
530 " char * name;",
531 " CUTTakedownFunction *takedown;",
532 "};",
534 "static int breakpoint = 0;",
535 "static int count = 0;",
536 "static BOOL test_hit_error = FALSE;",
537 "static NameStack nameStack;",
539 "static void traceback( void );",
540 "static void cut_exit( void );",
542 "/* I/O Functions */",
544 "static void print_string( char *string )",
545 "{",
546 " printf( \"%s\", string );",
547 " fflush( stdout );",
548 "}",
550 "static void print_string_as_error( char *filename, int lineNumber, char *string )",
551 "{",
552 " printf( \"%s(%d): %s\", filename, lineNumber, string );",
553 " fflush( stdout );",
554 "}",
556 "static void print_integer_as_expected( int i )",
557 "{",
558 " printf( \"(signed) %d (unsigned) %u (hex) 0x%08X\", i, i, i );",
559 "}",
561 "static void print_integer( int i )",
562 "{",
563 " printf( \"%d\", i );",
564 " fflush( stdout );",
565 "}",
567 "static void print_integer_in_field( int i, int width )",
568 "{",
569 " printf( \"%*d\", width, i );",
570 " fflush( stdout );",
571 "}",
573 "static void new_line( void )",
574 "{",
575 " printf( \"\\n\" );",
576 " fflush( stdout );",
577 "}",
579 "static void print_character( char ch )",
580 "{",
581 " printf( \"%c\", ch );",
582 " fflush( stdout );",
583 "}",
585 "static void dot( void )",
586 "{",
587 " print_character( '.' );",
588 "}",
590 "static void space( void )",
591 "{",
592 " print_character( ' ' );",
593 "}",
595 "/* Name Stack Functions */",
597 "static NameStackItem *stack_topOf( NameStack *stack )",
598 "{",
599 " return *stack;",
600 "}",
602 "static BOOL stack_isEmpty( NameStack *stack )",
603 "{",
604 " return stack_topOf( stack ) == NULL;",
605 "}",
607 "static BOOL stack_isNotEmpty( NameStack *stack )",
608 "{",
609 " return !( stack_isEmpty( stack ) );",
610 "}",
612 "static void stack_push( NameStack *stack, char *name, CUTTakedownFunction *tdfunc )",
613 "{",
614 " NameStackItem *item;",
616 " item = (NameStackItem *)( malloc( sizeof( NameStackItem ) ) );",
617 " if( item != NULL )",
618 " {",
619 " item -> next = stack_topOf( stack );",
620 " item -> name = name;",
621 " item -> takedown = tdfunc;",
623 " *stack = item;",
624 " }",
625 "}",
627 "static void stack_drop( NameStack *stack )",
628 "{",
629 " NameStackItem *oldItem;",
631 " if( stack_isNotEmpty( stack ) )",
632 " {",
633 " oldItem = stack_topOf( stack );",
634 " *stack = oldItem -> next;",
636 " free( oldItem );",
637 " }",
638 "}",
640 "/* CUT Initialization and Takedown Functions */",
642 "void cut_init( int brkpoint )",
643 "{",
644 " breakpoint = brkpoint;",
645 " count = 0;",
646 " test_hit_error = FALSE;",
647 " nameStack = NULL;",
649 " if( brkpoint >= 0 )",
650 " {",
651 " print_string( \"Breakpoint at test \" );",
652 " print_integer( brkpoint );",
653 " new_line();",
654 " }",
655 "}",
657 "void cut_exit( void )",
658 "{",
659 " exit( test_hit_error != FALSE );",
660 "}",
662 "/* User Interface functions */",
664 "static void print_group( int position, int base, int leftover )",
665 "{",
666 " if( !leftover )",
667 " return;",
669 " print_integer_in_field( base, position );",
670 " while( --leftover )",
671 " dot();",
672 "}",
674 "static void print_recap( int count )",
675 "{",
676 " int countsOnLastLine = count % 50;",
677 " int groupsOnLastLine = countsOnLastLine / 10;",
678 " int dotsLeftOver = countsOnLastLine % 10;",
679 " int lastGroupLocation =",
680 " countsOnLastLine - dotsLeftOver + ( 4 * groupsOnLastLine ) + 5;",
682 " if( dotsLeftOver == 0 )",
683 " {",
684 " if( countsOnLastLine == 0 )",
685 " lastGroupLocation = 61;",
686 " else",
687 " lastGroupLocation -= 14;",
689 " print_group( lastGroupLocation, countsOnLastLine-10, 10);",
690 " }",
691 " else",
692 " {",
693 " print_group(",
694 " lastGroupLocation,",
695 " countsOnLastLine - dotsLeftOver,",
696 " dotsLeftOver",
697 " );",
698 " }",
699 "}",
701 "void cut_break_formatting( void ) // DEPRECATED: Do not use in future software",
702 "{",
703 " new_line();",
704 "}",
706 "void cut_resume_formatting( void )",
707 "{",
708 " new_line();",
709 " print_recap( count );",
710 "}",
712 "void cut_interject( const char *comment, ... )",
713 "{",
714 " va_list marker;",
715 " va_start(marker,comment);",
716 " ",
717 " cut_break_formatting();",
718 " vprintf(comment,marker);",
719 " cut_resume_formatting();",
720 " ",
721 " va_end(marker);",
722 "}",
724 "/* Test Progress Accounting functions */",
726 "void __cut_mark_point( char *filename, int lineNumber )",
727 "{",
728 " if( ( count % 10 ) == 0 )",
729 " {",
730 " if( ( count % 50 ) == 0 )",
731 " new_line();",
733 " print_integer_in_field( count, 5 );",
734 " }",
735 " else",
736 " dot();",
738 " count++;",
739 " if( count == breakpoint )",
740 " {",
741 " print_string_as_error( filename, lineNumber, \"Breakpoint hit\" );",
742 " new_line();",
743 " traceback();",
744 " cut_exit();",
745 " }",
746 "}",
748 "void __cut_assert_equals( // DEPRECATED: Do not use in future software",
749 " char *filename,",
750 " int lineNumber,",
751 " char *message,",
752 " char *expression,",
753 " BOOL success,",
754 " int expected",
755 " )",
756 "{",
757 " __cut_mark_point( filename, lineNumber );",
758 " ",
759 " if( success != FALSE )",
760 " return;",
761 " ",
762 " cut_break_formatting();",
763 " print_string_as_error( filename, lineNumber, message );",
764 " new_line();",
765 " print_string_as_error( filename, lineNumber, \"Failed expression: \" );",
766 " print_string( expression );",
767 " new_line();",
768 " print_string_as_error( filename, lineNumber, \"Actual value: \" );",
769 " print_integer_as_expected( expected );",
770 " new_line();",
772 " test_hit_error = TRUE;",
773 " cut_resume_formatting();",
774 "}",
777 "void __cut_assert(",
778 " char *filename,",
779 " int lineNumber,",
780 " char *message,",
781 " char *expression,",
782 " BOOL success",
783 " )",
784 "{",
785 " __cut_mark_point( filename, lineNumber );",
786 " ",
787 " if( success != FALSE )",
788 " return;",
789 " ",
790 " cut_break_formatting();",
791 " print_string_as_error( filename, lineNumber, message );",
792 " new_line();",
793 " print_string_as_error( filename, lineNumber, \"Failed expression: \" );",
794 " print_string( expression );",
795 " new_line();",
797 " test_hit_error = TRUE;",
798 " cut_resume_formatting();",
799 "}",
802 "/* Test Delineation and Teardown Support Functions */",
804 "static void traceback()",
805 "{",
806 " if( stack_isNotEmpty( &nameStack ) )",
807 " print_string( \"Traceback\" );",
808 " else",
809 " print_string( \"(No traceback available.)\" );",
811 " while( stack_isNotEmpty( &nameStack ) )",
812 " {",
813 " print_string( \": \" );",
814 " print_string( stack_topOf( &nameStack ) -> name );",
816 " if( stack_topOf( &nameStack ) -> takedown != NULL )",
817 " {",
818 " print_string( \"(taking down)\" );",
819 " stack_topOf( &nameStack ) -> takedown();",
820 " }",
822 " stack_drop( &nameStack );",
824 " if( stack_isNotEmpty( &nameStack ) )",
825 " space();",
826 " }",
828 " new_line();",
829 "}",
831 "void cut_start( char *name, CUTTakedownFunction *takedownFunction )",
832 "{",
833 " stack_push( &nameStack, name, takedownFunction );",
834 "}",
836 "int __cut_check_errors( char *filename, int lineNumber )",
837 "{",
838 " if( test_hit_error || stack_isEmpty( &nameStack ) )",
839 " {",
840 " cut_break_formatting();",
841 " if( stack_isEmpty( &nameStack ) )",
842 " print_string_as_error( filename, lineNumber, \"Missing cut_start(); no traceback possible.\" );",
843 " else",
844 " traceback();",
846 " cut_exit();",
847 " return 0;",
848 " } else return 1;",
849 "}",
851 "void __cut_end( char *filename, int lineNumber, char *closingFrame )",
852 "{",
853 " if( test_hit_error || stack_isEmpty( &nameStack ) )",
854 " {",
855 " cut_break_formatting();",
856 " if( stack_isEmpty( &nameStack ) )",
857 " print_string_as_error( filename, lineNumber, \"Missing cut_start(); no traceback possible.\" );",
858 " else",
859 " traceback();",
861 " cut_exit();",
862 " }",
863 " else",
864 " {",
865 " if( strcmp( stack_topOf( &nameStack ) -> name, closingFrame ) == 0 )",
866 " stack_drop( &nameStack );",
867 " else",
868 " {",
869 " print_string_as_error( filename, lineNumber, \"Mismatched cut_end().\" );",
870 " traceback();",
871 " cut_exit();",
872 " }",
873 " }",
874 "}",
879 * vim: tabstop=3 shiftwidth=3 expandtab