CAMLprim value pcre_compile_stub(intnat v_opt, value v_tables, value v_pat) { value v_rex; /* Final result -> value of type [regexp] */ const char *error = NULL; /* pointer to possible error message */ int error_ofs = 0; /* offset in the pattern at which error occurred */ /* If v_tables = [None], then pointer to tables is NULL, otherwise set it to the appropriate value */ chartables tables = (v_tables == None) ? NULL : get_tables(Field(v_tables, 0)); /* Compiles the pattern */ pcre *regexp = pcre_compile(String_val(v_pat), v_opt, &error, &error_ofs, tables); /* Raises appropriate exception with [BadPattern] if the pattern could not be compiled */ if (regexp == NULL) raise_bad_pattern(error, error_ofs); /* GC will do a full cycle every 1_000_000 regexp allocations (a typical regexp probably consumes less than 100 bytes -> maximum of 100_000_000 bytes unreclaimed regexps) */ v_rex = caml_alloc_custom(®exp_ops, sizeof(struct pcre_ocaml_regexp), 1, 1000000); set_rex(v_rex, regexp); set_extra(v_rex, NULL); set_studied(v_rex, 0); return v_rex; }
/* Studies a regexp */ CAMLprim value pcre_study_stub(value v_rex) { /* If it has not yet been studied */ if (! get_studied(v_rex)) { const char *error = NULL; pcre_extra *extra = pcre_study(get_rex(v_rex), 0, &error); if (error != NULL) caml_invalid_argument((char *) error); set_extra(v_rex, extra); set_studied(v_rex, 1); } return v_rex; }
CAMLprim value pcre_set_imp_match_limit_stub(value v_rex, intnat v_lim) { pcre_extra *extra = get_extra(v_rex); if (extra == NULL) { extra = pcre_malloc(sizeof(pcre_extra)); extra->flags = PCRE_EXTRA_MATCH_LIMIT; set_extra(v_rex, extra); } else { unsigned long *flags_ptr = &extra->flags; *flags_ptr = PCRE_EXTRA_MATCH_LIMIT | *flags_ptr; } extra->match_limit = v_lim; return v_rex; }
void setup() { set_adjs( "yellow spotted" ); set_type( "toadstool" ); set_extra( 0 ); } /* setup() */
int main( int argc, char** argv ) { GetOptContext ctx; init_getopt_context( &ctx ); char c; while( (c = getopt( argc, argv, "?i:o:a:de:x:lrh:v", &ctx )) != -1 ) { switch( c ) { case 'i': g_inputFileName = ctx.optarg; break; case 'o': g_outputFileName = ctx.optarg; break; case 'e': if( strcmp( ctx.optarg, "big" ) == 0 ) g_swapEndian = true; else if( strcmp( ctx.optarg, "little" ) == 0 ) g_swapEndian = false; else { fprintf( stderr, "error: unknown argument for option -e: %s\n", ctx.optarg ); return -1; } break; case 'a': g_asmFileName = ctx.optarg; break; case 'l': g_printIncludes = true; break; case 'v': /* verbose, print extra funny stuff! */ break; case 'h': g_outputHeaderName = ctx.optarg; break; case ':': print_usage(); return -1; break; case '?': print_usage(); return 0; break; } } if(ctx.optind != argc) { fprintf( stdout, "%s: unexpected argument '%s'\n", argv[0], argv[ctx.optind] ); print_usage(); return -1; } int returnCode = 0; if( !g_inputFileName ) { returnCode = -1; fprintf( stderr, "error: No input file given.\n" ); } // Convert all \ to / in the input file name, in order to // aid the include path translation for( char* p = g_inputFileName; p && *p; ++p ) { if( *p == '\\' ) *p = '/'; } if( returnCode == 0 ) { Allocator a; a.m_Alloc = &allocate_memory; a.m_Free = &free_memory; BehaviorTreeContext btc = create_bt_context( a ); ParserContextFunctions pcf; pcf.m_Read = &read_file; pcf.m_Error = &parser_error; pcf.m_Warning = &parser_warning; pcf.m_Translate = &parser_translate_include; ParsingInfo pi; pi.m_Name = g_inputFileName; pi.m_File = fopen( pi.m_Name, "r" ); if( !pi.m_File ) { fprintf( stderr, "%s(0): error: unable to open input file \"%s\" for reading.\n", g_inputFileName, pi.m_Name ); returnCode = -1; } if( returnCode == 0 ) { ParserContext pc = create_parser_context( btc ); set_extra( pc, &pi ); set_current( pc, pi.m_Name ); returnCode = parse( pc, &pcf ); destroy( pc ); } if( pi.m_File ) fclose( pi.m_File ); Include* include = get_first_include( btc ); while( returnCode == 0 && include ) { pi.m_Name = include->m_Name; pi.m_File = fopen( pi.m_Name, "r" ); if( !pi.m_File ) { fprintf( stderr, "%s(%d): error: unable to open include file \"%s\" for reading.\n", include->m_Parent, include->m_LineNo, pi.m_Name ); returnCode = -1; break; } ParserContext pc = create_parser_context( btc ); set_extra( pc, &pi ); set_current( pc, pi.m_Name ); returnCode = parse( pc, &pcf ); destroy( pc ); if( pi.m_File ) fclose( pi.m_File ); if( returnCode != 0 ) break; include = include->m_Next; } include = get_first_include( btc ); while( returnCode == 0 && include && g_printIncludes ) { printf( "%s\n", include->m_Name ); include = include->m_Next; } if( g_outputHeaderName && returnCode == 0 ) { FILE* header = fopen( g_outputHeaderName, "w" ); if( !header ) { fprintf( stderr, "%s(0): error: Unable to open output file %s for writing.\n", g_inputFileName, g_outputHeaderName ); returnCode = -1; } else { returnCode = print_header( header, g_inputFileName, btc ); if( returnCode != 0 ) fprintf( stderr, "%s(0): error: unspecified error when writing header %s.\n", g_inputFileName, g_outputHeaderName ); fclose( header ); } } if( g_outputFileName && returnCode == 0 ) { Program p; unsigned int debug_hash = hashlittle( "debug_info" ); Parameter* debug_param = find_by_hash( get_options( btc ), debug_hash ); if( debug_param ) p.m_I.SetGenerateDebugInfo( as_integer( *debug_param ) ); returnCode = setup( btc, &p ); if( returnCode == 0 ) { returnCode = generate( &p ); if( returnCode != 0 ) fprintf( stderr, "%s(0): error: Internal compiler error in generate.\n", g_inputFileName ); } else { fprintf( stderr, "%s(0): error: Internal compiler error in setup.\n", g_inputFileName ); } teardown( &p ); if( returnCode == 0 ) { g_outputFile = fopen( g_outputFileName, "wb" ); if( !g_outputFile ) { fprintf( stderr, "%s(0): error: Unable to open output file %s for writing.\n", g_inputFileName, g_outputFileName ); returnCode = -2; } if( returnCode == 0 ) returnCode = save_program( g_outputFile, g_swapEndian, &p ); if( returnCode != 0 ) { fprintf( stderr, "%s(0): error: Failed to write output file %s.\n", g_inputFileName, g_outputFileName ); returnCode = -5; } } if( !g_asmFileName ) { unsigned int hash = hashlittle( "force_asm" ); Parameter* force_asm = find_by_hash( get_options( btc ), hash ); if( force_asm && as_bool( *force_asm ) ) { unsigned int len = strlen( g_outputFileName ); g_asmFileNameMemory = (char*)malloc( len + 5 ); memcpy( g_asmFileNameMemory, g_outputFileName, len ); g_asmFileNameMemory[len + 0] = '.'; g_asmFileNameMemory[len + 1] = 'a'; g_asmFileNameMemory[len + 2] = 's'; g_asmFileNameMemory[len + 3] = 'm'; g_asmFileNameMemory[len + 4] = 0; g_asmFileName = g_asmFileNameMemory; } } if( returnCode == 0 && g_asmFileName ) { FILE* asmFile = fopen( g_asmFileName, "w" ); if( !asmFile ) { fprintf( stderr, "%s(0): error: Unable to open assembly file %s for writing.\n", g_inputFileName, g_asmFileName ); returnCode = -1; } else { print_program( asmFile, &p ); fclose( asmFile ); } } } destroy( btc ); } if( g_asmFileNameMemory ) free( g_asmFileNameMemory ); if( g_outputFile ) fclose( g_outputFile ); return returnCode; }