LIST * regex_split( FRAME * frame, int flags ) { LIST * args = lol_get( frame->args, 0 ); OBJECT * s; OBJECT * separator; regexp * re; const char * pos; LIST * result = L0; LISTITER iter = list_begin( args ); s = list_item( iter ); separator = list_item( list_next( iter ) ); re = regex_compile( separator ); pos = object_str( s ); while ( regexec( re, pos ) ) { result = list_push_back( result, object_new_range( pos, re->startp[ 0 ] - pos ) ); pos = re->endp[ 0 ]; } result = list_push_back( result, object_new( pos ) ); return result; }
LIST* builtin_subst( PARSE *parse, FRAME *frame ) { LIST* result = L0; LIST* arg1 = lol_get( frame->args, 0 ); if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) ) { const char* source = arg1->string; const char* pattern = list_next(arg1)->string; regexp* repat = regex_compile( pattern ); if ( regexec( repat, (char*)source) ) { LIST* subst = list_next(arg1); while ((subst = list_next(subst)) != L0) { # define BUFLEN 4096 char buf[BUFLEN + 1]; const char* in = subst->string; char* out = buf; for ( in = subst->string; *in && out < buf + BUFLEN; ++in ) { if ( *in == '\\' || *in == '$' ) { ++in; if ( *in == 0 ) { break; } else if ( *in >= '0' && *in <= '9' ) { unsigned n = *in - '0'; const size_t srclen = repat->endp[n] - repat->startp[n]; const size_t remaining = buf + BUFLEN - out; const size_t len = srclen < remaining ? srclen : remaining; memcpy( out, repat->startp[n], len ); out += len; continue; } /* fall through and copy the next character */ } *out++ = *in; } *out = 0; result = list_new( result, newstr( buf ) ); #undef BUFLEN } } } return result; }
int CRegEx::regex_match (char *pattern, char *line) //**************************************************************************** // //**************************************************************************** { regex_compile(pattern); return regex_match(line); }
void macro_headers( TARGET *t ) { static regexp *re = 0; FILE *f; char buf[ 1024 ]; if ( DEBUG_HEADER ) printf( "macro header scan for %s\n", t->name ); /* this regexp is used to detect lines of the form */ /* "#define MACRO <....>" or "#define MACRO "....." */ /* in the header macro files.. */ if ( re == 0 ) { re = regex_compile( "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*" "[<\"]([^\">]*)[\">].*$" ); } if ( !( f = fopen( t->boundname, "r" ) ) ) return; while ( fgets( buf, sizeof( buf ), f ) ) { HEADER_MACRO var; HEADER_MACRO *v = &var; if ( regexec( re, buf ) && re->startp[1] ) { /* we detected a line that looks like "#define MACRO filename */ re->endp[1][0] = '\0'; re->endp[2][0] = '\0'; if ( DEBUG_HEADER ) printf( "macro '%s' used to define filename '%s' in '%s'\n", re->startp[1], re->startp[2], t->boundname ); /* add macro definition to hash table */ if ( !header_macros_hash ) header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" ); v->symbol = re->startp[1]; v->filename = 0; if ( hashenter( header_macros_hash, (HASHDATA **)&v ) ) { v->symbol = newstr( re->startp[1] ); /* never freed */ v->filename = newstr( re->startp[2] ); /* never freed */ } /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */ /* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */ } } fclose( f ); }
int strlist_compile_regexes(struct strlist *strlist) { struct strlist *l; // FIX THIS: when the regex does not compile, should remove the // strlist entry completely. for(l=strlist; l; l=l->next) if(!(l->re=regex_compile(l->path))) logp("unable to compile regex: %s\n", l->path); return 0; }
void headers( TARGET * t ) { LIST * hdrscan; LIST * hdrrule; #ifndef OPT_HEADER_CACHE_EXT LIST * headlist = L0; #endif regexp * re[ MAXINC ]; int rec = 0; LISTITER iter, end; hdrscan = var_get( root_module(), constant_HDRSCAN ); if ( list_empty( hdrscan ) ) return; hdrrule = var_get( root_module(), constant_HDRRULE ); if ( list_empty( hdrrule ) ) return; if ( DEBUG_HEADER ) printf( "header scan %s\n", object_str( t->name ) ); /* Compile all regular expressions in HDRSCAN */ iter = list_begin( hdrscan ), end = list_end( hdrscan ); for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) ) { re[ rec++ ] = regex_compile( list_item( iter ) ); } /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ { FRAME frame[1]; frame_init( frame ); lol_add( frame->args, list_new( object_copy( t->name ) ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); #else lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); #endif if ( lol_get( frame->args, 1 ) ) { /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( frame->args, list_new( object_copy( t->boundname ) ) ); list_free( evaluate_rule( list_front( hdrrule ), frame ) ); } /* Clean up. */ frame_free( frame ); } }
int dfsch_regex_match_once_p(char* expression, int cflags, int mflags, char* string){ regex_t regex; int r; regex_compile(®ex, expression, cflags); r = regex_match(®ex, string, mflags); regfree(®ex); return r; }
void headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; LIST *headlist = 0; regexp *re[ MAXINC ]; int rec = 0; if( !( hdrscan = var_get( "HDRSCAN" ) ) || !( hdrrule = var_get( "HDRRULE" ) ) ) return; if( DEBUG_HEADER ) printf( "header scan %s\n", t->name ); /* Compile all regular expressions in HDRSCAN */ while( rec < MAXINC && hdrscan ) { re[rec++] = regex_compile( hdrscan->string ); hdrscan = list_next( hdrscan ); } /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ { FRAME frame[1]; frame_init( frame ); lol_add( frame->args, list_new( L0, t->name ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); #else lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); #endif if( lol_get( frame->args, 1 ) ) { /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( frame->args, list_new( L0, t->boundname ) ); list_free( evaluate_rule( hdrrule->string, frame ) ); } /* Clean up */ frame_free( frame ); } }
dfsch_object_t* dfsch_regex_substrings_once(char* expression, int cflags, int mflags, char* string){ regex_t regex; dfsch_object_t* r; regex_compile(®ex, expression, cflags); r = regex_substrings(®ex, string, get_sub_count(expression, cflags), mflags); regfree(®ex); return r; }
dfsch_object_t* dfsch_regex_compile(char* expression, int flags){ dfsch_regex_t* r = (dfsch_regex_t*)dfsch_make_object(®ex_type); regex_compile(&(r->regex), expression, flags); if ((flags & REG_NOSUB) == REG_NOSUB){ r->sub_count = 0; }else{ r->sub_count = get_sub_count(expression, flags); } GC_REGISTER_FINALIZER(r, (GC_finalization_proc)regex_finalizer, NULL, NULL, NULL); return (dfsch_object_t*)r; }
int new_text_string( YARA_CONTEXT* context, SIZED_STRING* charstr, int flags, unsigned char** hexstr, REGEXP* re, unsigned int* length) { char *error; int erroffset; int options; int result = ERROR_SUCCESS; //assert(charstr && hexstr && regexp && length); *length = charstr->length; *hexstr = yr_malloc(charstr->length); if (*hexstr == NULL) { return ERROR_INSUFICIENT_MEMORY; } memcpy(*hexstr, charstr->c_string, charstr->length); if (flags & STRING_FLAGS_REGEXP) { if (regex_compile(re, // REGEXP * charstr->c_string, // Regex pattern flags & STRING_FLAGS_NO_CASE, // If TRUE then case insensitive search context->last_error_extra_info, // Error message sizeof(context->last_error_extra_info), // Size of error buffer &erroffset) <= 0) // Offset into regex pattern if error detected { result = ERROR_INVALID_REGULAR_EXPRESSION; } } else { // re contains multiple pointers now, if we're // not doing a regex, make sure all are NULL. memset(re, '\0', sizeof(REGEXP)); } return result; }
int list_server_init( struct asfd *a, struct sdirs *s, struct cntr *c, enum protocol p, const char *backup_str, const char *regex_str, const char *browsedir_str) { asfd=a; cntr=c; protocol=p; backup=backup_str; browsedir=browsedir_str; if(bu_get_list(s, &bu_list)) goto error; if(regex_str && *regex_str && !(regex=regex_compile(regex_str))) { char msg[256]=""; snprintf(msg, sizeof(msg), "unable to compile regex: %s\n", regex_str); log_and_send(asfd, msg); goto error; } list_mode=LIST_MODE_BACKUPS; if(regex || browsedir) list_mode=LIST_MODE_CONTENTS_MANY; if(backup && *backup) { if((bno=strtoul(backup, NULL, 10))>0) list_mode=LIST_MODE_CONTENTS_ONE; else if(*backup=='c') list_mode=LIST_MODE_CONTENTS_ONE; else if(*backup=='a') list_mode=LIST_MODE_CONTENTS_MANY; else list_mode=LIST_MODE_CONTENTS_ONE; } return 0; error: list_server_free(); return -1; }
void misc_test(pthread_mutex_t *parent_lock) { regex_t *rx; regex_result *result1, *result2; df_trkname *out1, *out2; rx = regex_compile("GetTrackName[[:space:]+](-*[0-9]+)[[:space:]+]\"(-*[0-9]*)\"[[:space:]+]\"(.*)\"[[:space:]+]\"(.*)\"[[:space:]+]\"([0-9]+:[0-9]+:[0-9]+)\"[[:space:]+]\"(-*[0-9]*)\"(?:[[:space:]+]\"(-*[0-9]*)\"[[:space:]+]\"(.*)\"|)"); result1 = regex_match(rx, "GetTrackName 0 \"0\" \"asd\" \"asdf\" \"1:1:1\" \"1\" \"1\" \"asdf\""); printf("num_sub_exps:%d\n", result1->num_subexps); out1 = malloc(sizeof(df_trkname)); sscanf(result1->subexps[2].value,"%d",&(out1->TrackKey)); out1->Name = formatting_process(result1->subexps[3].value); out1->Type = formatting_process(result1->subexps[4].value); sscanf(result1->subexps[5].value,"%u:%u:%u", &(out1->Length.hours), &(out1->Length.minutes), &(out1->Length.seconds)); sscanf(result1->subexps[6].value,"%d",&(out1->Source)); sscanf(result1->subexps[7].value,"%d",&(out1->Capabilities)); out1->StreamID = formatting_process(result1->subexps[8].value); result2 = regex_match(rx, "GetTrackName 0 \"0\" \"asd\" \"asdf\" \"1:1:1\" \"1\""); printf("num_sub_exps:%d\n", result2->num_subexps); out2 = malloc(sizeof(df_trkname)); sscanf(result2->subexps[2].value,"%d",&(out2->TrackKey)); out2->Name = formatting_process(result2->subexps[3].value); out2->Type = formatting_process(result2->subexps[4].value); sscanf(result2->subexps[5].value,"%u:%u:%u", &(out2->Length.hours), &(out2->Length.minutes), &(out2->Length.seconds)); sscanf(result2->subexps[6].value,"%d",&(out2->Source)); sscanf(result2->subexps[7].value,"%d",&(out2->Capabilities)); out2->StreamID = formatting_process(result2->subexps[8].value); pthread_mutex_unlock(parent_lock); }
LIST * regex_replace( FRAME * frame, int flags ) { LIST * args = lol_get( frame->args, 0 ); OBJECT * s; OBJECT * match; OBJECT * replacement; regexp * re; const char * pos; string buf[ 1 ]; LIST * result; LISTITER iter = list_begin( args ); s = list_item( iter ); iter = list_next( iter ); match = list_item( iter ); iter = list_next( iter ); replacement = list_item(iter ); re = regex_compile( match ); string_new( buf ); pos = object_str( s ); while ( regexec( re, pos ) ) { string_append_range( buf, pos, re->startp[ 0 ] ); string_append( buf, object_str( replacement ) ); pos = re->endp[ 0 ]; } string_append( buf, pos ); result = list_new( object_new( buf->value ) ); string_free( buf ); return result; }
static #endif LIST * headers1( LIST * l, OBJECT * file, int rec, regexp * re[] ) { FILE * f; char buf[ 1024 ]; int i; static regexp * re_macros = 0; #ifdef OPT_IMPROVED_PATIENCE_EXT static int count = 0; ++count; if ( ( ( count == 100 ) || !( count % 1000 ) ) && DEBUG_MAKE ) { out_printf( "...patience...\n" ); out_flush(); } #endif /* The following regexp is used to detect cases where a file is included * through a line like "#include MACRO". */ if ( re_macros == 0 ) { OBJECT * const re_str = object_new( "#[ \t]*include[ \t]*([A-Za-z][A-Za-z0-9_]*).*$" ); re_macros = regex_compile( re_str ); object_free( re_str ); } if ( !( f = fopen( object_str( file ), "r" ) ) ) return l; while ( fgets( buf, sizeof( buf ), f ) ) { for ( i = 0; i < rec; ++i ) if ( regexec( re[ i ], buf ) && re[ i ]->startp[ 1 ] ) { ( (char *)re[ i ]->endp[ 1 ] )[ 0 ] = '\0'; if ( DEBUG_HEADER ) out_printf( "header found: %s\n", re[ i ]->startp[ 1 ] ); l = list_push_back( l, object_new( re[ i ]->startp[ 1 ] ) ); } /* Special treatment for #include MACRO. */ if ( regexec( re_macros, buf ) && re_macros->startp[ 1 ] ) { OBJECT * header_filename; OBJECT * macro_name; ( (char *)re_macros->endp[ 1 ] )[ 0 ] = '\0'; if ( DEBUG_HEADER ) out_printf( "macro header found: %s", re_macros->startp[ 1 ] ); macro_name = object_new( re_macros->startp[ 1 ] ); header_filename = macro_header_get( macro_name ); object_free( macro_name ); if ( header_filename ) { if ( DEBUG_HEADER ) out_printf( " resolved to '%s'\n", object_str( header_filename ) ); l = list_push_back( l, object_copy( header_filename ) ); } else { if ( DEBUG_HEADER ) out_printf( " ignored !!\n" ); } } } fclose( f ); return l; }
LIST * regex_transform( FRAME * frame, int flags ) { LIST * const l = lol_get( frame->args, 0 ); LIST * const pattern = lol_get( frame->args, 1 ); LIST * const indices_list = lol_get( frame->args, 2 ); int * indices = 0; int size; LIST * result = L0; if ( !list_empty( indices_list ) ) { int * p; LISTITER iter = list_begin( indices_list ); LISTITER const end = list_end( indices_list ); size = list_length( indices_list ); indices = (int *)BJAM_MALLOC( size * sizeof( int ) ); for ( p = indices; iter != end; iter = list_next( iter ) ) *p++ = atoi( object_str( list_item( iter ) ) ); } else { size = 1; indices = (int *)BJAM_MALLOC( sizeof( int ) ); *indices = 1; } { /* Result is cached and intentionally never freed */ regexp * const re = regex_compile( list_front( pattern ) ); LISTITER iter = list_begin( l ); LISTITER const end = list_end( l ); string buf[ 1 ]; string_new( buf ); for ( ; iter != end; iter = list_next( iter ) ) { if ( regexec( re, object_str( list_item( iter ) ) ) ) { int i = 0; for ( ; i < size; ++i ) { int const index = indices[ i ]; /* Skip empty submatches. Not sure it is right in all cases, * but surely is right for the case for which this routine * is optimized -- header scanning. */ if ( re->startp[ index ] != re->endp[ index ] ) { string_append_range( buf, re->startp[ index ], re->endp[ index ] ); result = list_push_back( result, object_new( buf->value ) ); string_truncate( buf, 0 ); } } } } string_free( buf ); } BJAM_FREE( indices ); return result; }
/* rule transform ( list * : pattern : indices * ) { indices ?= 1 ; local result ; for local e in $(list) { local m = [ MATCH $(pattern) : $(e) ] ; if $(m) { result += $(m[$(indices)]) ; } } return $(result) ; } */ LIST *regex_transform( FRAME *frame, int flags ) { LIST* l = lol_get( frame->args, 0 ); LIST* pattern = lol_get( frame->args, 1 ); LIST* indices_list = lol_get(frame->args, 2); int* indices = 0; int size; int* p; LIST* result = 0; string buf[1]; string_new(buf); if (indices_list) { size = list_length(indices_list); indices = (int*)BJAM_MALLOC(size*sizeof(int)); for(p = indices; indices_list; indices_list = indices_list->next) { *p++ = atoi(object_str(indices_list->value)); } } else { size = 1; indices = (int*)BJAM_MALLOC(sizeof(int)); *indices = 1; } { /* Result is cached and intentionally never freed */ regexp *re = regex_compile( pattern->value ); for(; l; l = l->next) { if( regexec( re, object_str( l->value ) ) ) { int i = 0; for(; i < size; ++i) { int index = indices[i]; /* Skip empty submatches. Not sure it's right in all cases, but surely is right for the case for which this routine is optimized -- header scanning. */ if (re->startp[index] != re->endp[index]) { string_append_range( buf, re->startp[index], re->endp[index] ); result = list_new( result, object_new( buf->value ) ); string_truncate( buf, 0 ); } } } } string_free( buf ); } BJAM_FREE(indices); return result; }
static LIST * #endif headers1( LIST *l, char *file, int rec, regexp *re[] ) { FILE *f; char buf[ 1024 ]; int i; static regexp *re_macros = 0; #ifdef OPT_IMPROVED_PATIENCE_EXT static int count = 0; ++count; if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE ) printf("...patience...\n"); #endif /* the following regexp is used to detect cases where a */ /* file is included through a line line "#include MACRO" */ if ( re_macros == 0 ) { re_macros = regex_compile( "^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" ); } if( !( f = fopen( file, "r" ) ) ) return l; while( fgets( buf, sizeof( buf ), f ) ) { int size = strlen (buf); /* Remove trailing \r and \n, if any. */ while (size > 0 && (buf[size-1] == '\n' && buf[size-1] == '\r')) { buf[size-1] = '\0'; --size; } for( i = 0; i < rec; i++ ) if( regexec( re[i], buf ) && re[i]->startp[1] ) { re[i]->endp[1][0] = '\0'; if( DEBUG_HEADER ) printf( "header found: %s\n", re[i]->startp[1] ); l = list_new( l, newstr( re[i]->startp[1] ) ); } /* special treatment for #include MACRO */ if ( regexec( re_macros, buf ) && re_macros->startp[1] ) { char* header_filename; re_macros->endp[1][0] = '\0'; if ( DEBUG_HEADER ) printf( "macro header found: %s", re_macros->startp[1] ); header_filename = macro_header_get( re_macros->startp[1] ); if (header_filename) { if ( DEBUG_HEADER ) printf( " resolved to '%s'\n", header_filename ); l = list_new( l, newstr( header_filename ) ); } else { if ( DEBUG_HEADER ) printf( " ignored !!\n" ); } } } fclose( f ); return l; }
int paircmp_pairs(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp) #endif { int ret = 0; /* * Check for =* and !* and return appropriately */ if (check->op == T_OP_CMP_TRUE) return 0; if (check->op == T_OP_CMP_FALSE) return 1; if (!vp) { REDEBUG("Non-Unary operations require two operands"); return -2; } #ifdef HAVE_REGEX if ((check->op == T_OP_REG_EQ) || (check->op == T_OP_REG_NE)) { ssize_t slen; regex_t *preg = NULL; uint32_t subcaptures; fr_regmatch_t *regmatch; char *expr = NULL, *value = NULL; char const *expr_p, *value_p; if (check->vp_type == FR_TYPE_STRING) { expr_p = check->vp_strvalue; } else { expr_p = expr = fr_pair_value_asprint(check, check, '\0'); } if (vp->vp_type == FR_TYPE_STRING) { value_p = vp->vp_strvalue; } else { value_p = value = fr_pair_value_asprint(vp, vp, '\0'); } if (!expr_p || !value_p) { REDEBUG("Error stringifying operand for regular expression"); regex_error: talloc_free(preg); talloc_free(expr); talloc_free(value); return -2; } /* * Include substring matches. */ slen = regex_compile(request, &preg, expr_p, talloc_array_length(expr_p) - 1, false, false, true, true); if (slen <= 0) { REMARKER(expr_p, -slen, fr_strerror()); goto regex_error; } subcaptures = regex_subcapture_count(preg); if (!subcaptures) subcaptures = REQUEST_MAX_REGEX + 1; /* +1 for %{0} (whole match) capture group */ MEM(regmatch = regex_match_data_alloc(NULL, subcaptures)); /* * Evaluate the expression */ slen = regex_exec(preg, value_p, talloc_array_length(value_p) - 1, regmatch); if (slen < 0) { RPERROR("Invalid regex"); goto regex_error; } if (check->op == T_OP_REG_EQ) { /* * Add in %{0}. %{1}, etc. */ regex_sub_to_request(request, &preg, ®match); ret = (slen == 1) ? 0 : -1; } else { ret = (slen != 1) ? 0 : -1; } talloc_free(regmatch); talloc_free(preg); talloc_free(expr); talloc_free(value); goto finish; } #endif /* * Attributes must be of the same type. * * FIXME: deal with type mismatch properly if one side contain * ABINARY, OCTETS or STRING by converting the other side to * a string * */ if (vp->vp_type != check->vp_type) return -1; /* * Tagged attributes are equal if and only if both the * tag AND value match. */ if (check->da->flags.has_tag && !TAG_EQ(check->tag, vp->tag)) { ret = ((int) vp->tag) - ((int) check->tag); if (ret != 0) goto finish; } /* * Not a regular expression, compare the types. */ switch (check->vp_type) { #ifdef WITH_ASCEND_BINARY /* * Ascend binary attributes can be treated * as opaque objects, I guess... */ case FR_TYPE_ABINARY: #endif case FR_TYPE_OCTETS: if (vp->vp_length != check->vp_length) { ret = 1; /* NOT equal */ break; } ret = memcmp(vp->vp_strvalue, check->vp_strvalue, vp->vp_length); break; case FR_TYPE_STRING: ret = strcmp(vp->vp_strvalue, check->vp_strvalue); break; case FR_TYPE_UINT8: ret = vp->vp_uint8 - check->vp_uint8; break; case FR_TYPE_UINT16: ret = vp->vp_uint16 - check->vp_uint16; break; case FR_TYPE_UINT32: ret = vp->vp_uint32 - check->vp_uint32; break; case FR_TYPE_UINT64: /* * Don't want integer overflow! */ if (vp->vp_uint64 < check->vp_uint64) { ret = -1; } else if (vp->vp_uint64 > check->vp_uint64) { ret = +1; } else { ret = 0; } break; case FR_TYPE_INT32: if (vp->vp_int32 < check->vp_int32) { ret = -1; } else if (vp->vp_int32 > check->vp_int32) { ret = +1; } else { ret = 0; } break; case FR_TYPE_DATE: ret = vp->vp_date - check->vp_date; break; case FR_TYPE_IPV4_ADDR: ret = ntohl(vp->vp_ipv4addr) - ntohl(check->vp_ipv4addr); break; case FR_TYPE_IPV6_ADDR: ret = memcmp(vp->vp_ip.addr.v6.s6_addr, check->vp_ip.addr.v6.s6_addr, sizeof(vp->vp_ip.addr.v6.s6_addr)); break; case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_PREFIX: ret = memcmp(&vp->vp_ip, &check->vp_ip, sizeof(vp->vp_ip)); break; case FR_TYPE_IFID: ret = memcmp(vp->vp_ifid, check->vp_ifid, sizeof(vp->vp_ifid)); break; default: break; } finish: if (ret > 0) return 1; if (ret < 0) return -1; return 0; }
int main_run( void* main_arg ) { #if !BUILD_MONOLITHIC const char* pattern = 0; char** exe_paths = 0; unsigned int iexe, exesize; process_t* process = 0; char* process_path = 0; unsigned int* exe_flags = 0; #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL int remain_counter = 0; #endif #if BUILD_DEBUG const char* build_name = "debug"; #elif BUILD_RELEASE const char* build_name = "release"; #elif BUILD_PROFILE const char* build_name = "profile"; #elif BUILD_DEPLOY const char* build_name = "deploy"; #endif int process_result = 0; object_t thread = 0; FOUNDATION_UNUSED( main_arg ); FOUNDATION_UNUSED( build_name ); log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG ); log_infof( HASH_TEST, "Foundation library v%s built for %s using %s (%s)", string_from_version_static( foundation_version() ), FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, build_name ); thread = thread_create( event_thread, "event_thread", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread, 0 ); while( !thread_is_running( thread ) ) thread_sleep( 10 ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID while( !_test_should_start ) { #if FOUNDATION_PLATFORM_ANDROID system_process_events(); #endif thread_sleep( 100 ); } #endif fs_remove_directory( environment_temporary_directory() ); #if BUILD_MONOLITHIC test_run_fn tests[] = { test_app_run, test_array_run, test_atomic_run, test_base64_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_config_run, test_crash_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_process_run, test_profile_run, test_radixsort_run, test_random_run, test_regex_run, test_ringbuffer_run, test_semaphore_run, test_stacktrace_run, test_stream_run, //stream test closes stdin test_string_run, test_system_run, test_time_run, test_uuid_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID object_t test_thread = thread_create( test_runner, "test_runner", THREAD_PRIORITY_NORMAL, 0 ); thread_start( test_thread, tests ); log_debug( HASH_TEST, "Starting test runner thread" ); while( !thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } while( thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } process_result = (int)(intptr_t)thread_result( test_thread ); thread_destroy( test_thread ); while( thread_is_thread( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } #else process_result = (int)(intptr_t)test_runner( 0, tests ); #endif if( process_result != 0 ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while( !_test_should_terminate && _test_have_focus && ( remain_counter < 50 ) ) { system_process_events(); thread_sleep( 100 ); ++remain_counter; } #endif log_debug( HASH_TEST, "Exiting main loop" ); #else // !BUILD_MONOLITHIC //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = "^test-.*\\.exe$"; #elif FOUNDATION_PLATFORM_MACOSX pattern = "^test-.*$"; #elif FOUNDATION_PLATFORM_POSIX pattern = "^test-.*$"; #else # error Not implemented #endif exe_paths = fs_matching_files( environment_executable_directory(), pattern, false ); array_resize( exe_flags, array_size( exe_paths ) ); memset( exe_flags, 0, sizeof( unsigned int ) * array_size( exe_flags ) ); #if FOUNDATION_PLATFORM_MACOSX //Also search for test applications const char* app_pattern = "^test-.*\\.app$"; regex_t* app_regex = regex_compile( app_pattern ); char** subdirs = fs_subdirs( environment_executable_directory() ); for( int idir = 0, dirsize = array_size( subdirs ); idir < dirsize; ++idir ) { if( regex_match( app_regex, subdirs[idir], string_length( subdirs[idir] ), 0, 0 ) ) { array_push( exe_paths, string_substr( subdirs[idir], 0, string_length( subdirs[idir] ) - 4 ) ); array_push( exe_flags, PROCESS_MACOSX_USE_OPENAPPLICATION ); } } string_array_deallocate( subdirs ); regex_deallocate( app_regex ); #endif for( iexe = 0, exesize = array_size( exe_paths ); iexe < exesize; ++iexe ) { bool is_self = false; char* exe_file_name = path_base_file_name( exe_paths[iexe] ); if( string_equal( exe_file_name, environment_executable_name() ) ) is_self = true; string_deallocate( exe_file_name ); if( is_self ) continue; //Don't run self process_path = path_merge( environment_executable_directory(), exe_paths[iexe] ); process = process_allocate(); process_set_executable_path( process, process_path ); process_set_working_directory( process, environment_executable_directory() ); process_set_flags( process, PROCESS_ATTACHED | exe_flags[iexe] ); log_infof( HASH_TEST, "Running test executable: %s", exe_paths[iexe] ); process_result = process_spawn( process ); while( process_result == PROCESS_WAIT_INTERRUPTED ) { thread_sleep( 10 ); process_result = process_wait( process ); } process_deallocate( process ); string_deallocate( process_path ); if( process_result != 0 ) { if( process_result >= PROCESS_INVALID_ARGS ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed, process terminated with error %x", process_result ); else log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); process_set_exit_code( -1 ); goto exit; } log_infof( HASH_TEST, "All tests from %s passed (%d)", exe_paths[iexe], process_result ); } log_info( HASH_TEST, "All tests passed" ); exit: if( exe_paths ) string_array_deallocate( exe_paths ); array_deallocate( exe_flags ); #endif thread_terminate( thread ); thread_destroy( thread ); while( thread_is_running( thread ) ) thread_sleep( 10 ); while( thread_is_thread( thread ) ) thread_sleep( 10 ); log_infof( HASH_TEST, "Tests exiting: %d", process_result ); return process_result; }
void macro_headers( TARGET * t ) { static regexp * re = 0; FILE * f; char buf[ 1024 ]; if ( DEBUG_HEADER ) printf( "macro header scan for %s\n", object_str( t->name ) ); /* This regexp is used to detect lines of the form * "#define MACRO <....>" or "#define MACRO "....." * in the header macro files. */ if ( !re ) { OBJECT * const re_str = object_new( "^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*" "[<\"]([^\">]*)[\">].*$" ); re = regex_compile( re_str ); object_free( re_str ); } if ( !( f = fopen( object_str( t->boundname ), "r" ) ) ) return; while ( fgets( buf, sizeof( buf ), f ) ) { HEADER_MACRO var; HEADER_MACRO * v = &var; if ( regexec( re, buf ) && re->startp[ 1 ] ) { OBJECT * symbol; int found; /* we detected a line that looks like "#define MACRO filename */ ( (char *)re->endp[ 1 ] )[ 0 ] = '\0'; ( (char *)re->endp[ 2 ] )[ 0 ] = '\0'; if ( DEBUG_HEADER ) printf( "macro '%s' used to define filename '%s' in '%s'\n", re->startp[ 1 ], re->startp[ 2 ], object_str( t->boundname ) ); /* add macro definition to hash table */ if ( !header_macros_hash ) header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" ); symbol = object_new( re->startp[ 1 ] ); v = (HEADER_MACRO *)hash_insert( header_macros_hash, symbol, &found ); if ( !found ) { v->symbol = symbol; v->filename = object_new( re->startp[ 2 ] ); /* never freed */ } else object_free( symbol ); /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */ /* WE MIGHT AS WELL USE A LIST TO STORE THEM.. */ } } fclose( f ); }
int main(int argc, char **argv) { FILE *f = fopen(argv[1], "r"); if (!f) { fprintf(stderr, "Could not open tests\n"); exit(1); } int passed = 0, failed = 0, warning = 0; regex_t *re = NULL; char *re_str; ssize_t len; char *line = NULL; size_t linecap = 0; while ((len = getline(&line, &linecap, f)) > 0) { if (line[len - 1] == '\n') { line[len - 1] = 0; --len; } if (strncmp(line, "regex ", 6) == 0) { if (re) { regex_free(re); free(re_str); } re = regex_compile(line + 6); if (!re) { fprintf(stderr, "FAIL: /%s/ did not compile\n", line + 6); ++failed; } else { re_str = strdup(line + 6); ++passed; } } else if (strncmp(line, "noregex ", 8) == 0) { if (re) { regex_free(re); free(re_str); } re = regex_compile(line + 8); if (re) { regex_free(re); re = NULL; fprintf(stderr, "FAIL: /%s/ did compile\n", line + 8); ++failed; } else { ++passed; } } else if (strncmp(line, "match ", 6) == 0) { if (!re) { fprintf(stderr, "WARN: no regular expression for 'match'\n"); ++warning; } else { if (!regex_match(re, line + 6)) { fprintf(stderr, "FAIL: /%s/ should match %s\n", re_str, line + 6); ++failed; } else { ++passed; } } } else if (strncmp(line, "differ ", 7) == 0) { if (!re) { fprintf(stderr, "WARN: no regular expression for 'differ'\n"); ++warning; } else { if (regex_match(re, line + 7)) { fprintf(stderr, "FAIL: /%s/ should not match %s\n", re_str, line + 7); ++failed; } else { ++passed; } } } else if (strcmp(line, "matchnewline") == 0) { if (!re) { fprintf(stderr, "WARN: no regular expression for 'matchnewline'\n"); ++warning; } else { if (!regex_match(re, "\n")) { fprintf(stderr, "FAIL: /%s/ should match newline\n", re_str); ++failed; } else { ++passed; } } } else if (strcmp(line, "differnewline") == 0) { if (!re) { fprintf(stderr, "WARN: no regular expression for 'differnewline'\n"); ++warning; } else { if (regex_match(re, "\n")) { fprintf(stderr, "FAIL: /%s/ should not match newline\n", re_str); ++failed; } else { ++passed; } } } else if (len > 0 && line[0] != '#') { fprintf(stderr, "WARN: unknown line: %s\n", line); ++warning; } } fclose(f); if (re) { regex_free(re); free(re_str); } if (line) { free(line); } printf("%d passed, %d failed", passed, failed); if (warning) { printf(", %d warning%s", warning, warning == 1 ? "" : "s"); } printf("\n"); return failed > 0 || warning > 0; }
static pr_list* load_config_file(const char *config_file) { char buffer[1024]; char default_config_file[1024]; TSFile fh; pr_list *prl = TSmalloc(sizeof(pr_list)); prl->patterncount = 0; /* locations in a config file line, end of line, split start, split end */ char *eol, *spstart, *spend; int lineno = 0; int retval; regex_info *info = 0; if (!config_file) { /* Default config file of plugins/cacheurl.config */ sprintf(default_config_file, "%s/cacheurl.config", TSPluginDirGet()); config_file = (const char *)default_config_file; } TSDebug(PLUGIN_NAME, "Opening config file: %s", config_file); fh = TSfopen(config_file, "r"); if (!fh) { TSError("[%s] Unable to open %s. No patterns will be loaded\n", PLUGIN_NAME, config_file); return prl; } while (TSfgets(fh, buffer, sizeof(buffer) - 1)) { lineno++; if (*buffer == '#') { /* # Comments, only at line beginning */ continue; } eol = strstr(buffer, "\n"); if (eol) { *eol = 0; /* Terminate string at newline */ } else { /* Malformed line - skip */ continue; } /* Split line into two parts based on whitespace */ /* Find first whitespace */ spstart = strstr(buffer, " "); if (!spstart) { spstart = strstr(buffer, "\t"); } if (!spstart) { TSError("[%s] ERROR: Invalid format on line %d. Skipping\n", PLUGIN_NAME, lineno); continue; } /* Find part of the line after any whitespace */ spend = spstart + 1; while(*spend == ' ' || *spend == '\t') { spend++; } if (*spend == 0) { /* We reached the end of the string without any non-whitepace */ TSError("[%s] ERROR: Invalid format on line %d. Skipping\n", PLUGIN_NAME, lineno); continue; } *spstart = 0; /* We have the pattern/replacement, now do precompilation. * buffer is the first part of the line. spend is the second part just * after the whitespace */ if (log) { TSTextLogObjectWrite(log, "Adding pattern/replacement pair: '%s' -> '%s'", buffer, spend); } TSDebug(PLUGIN_NAME, "Adding pattern/replacement pair: '%s' -> '%s'\n", buffer, spend); retval = regex_compile(&info, buffer, spend); if (!retval) { TSError("[%s] Error precompiling regex/replacement. Skipping.\n", PLUGIN_NAME); } // TODO - remove patterncount and make pr_list infinite (linked list) if (prl->patterncount >= PATTERNCOUNT) { TSError("[%s] Warning, too many patterns - skipping the rest" "(max: %d)\n", PLUGIN_NAME, PATTERNCOUNT); TSfree(info); break; } prl->pr[prl->patterncount] = info; prl->patterncount++; } TSfclose(fh); // Make sure the last element is null if (prl->patterncount < PATTERNCOUNT) { prl->pr[prl->patterncount] = NULL; } return prl; }
int main_run(void* main_arg) { #if !BUILD_MONOLITHIC string_const_t pattern; string_t* exe_paths = 0; size_t iexe, exesize; process_t* process = 0; string_t process_path = { 0, 0 }; unsigned int* exe_flags = 0; #else void* test_result; #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL int remain_counter = 0; #endif #if BUILD_DEBUG const string_const_t build_name = string_const(STRING_CONST("debug")); #elif BUILD_RELEASE const string_const_t build_name = string_const(STRING_CONST("release")); #elif BUILD_PROFILE const string_const_t build_name = string_const(STRING_CONST("profile")); #elif BUILD_DEPLOY const string_const_t build_name = string_const(STRING_CONST("deploy")); #endif #if BUILD_MONOLITHIC const string_const_t build_type = string_const(STRING_CONST(" monolithic")); #else const string_const_t build_type = string_empty(); #endif char* pathbuf; int process_result = 0; thread_t event_thread; FOUNDATION_UNUSED(main_arg); FOUNDATION_UNUSED(build_name); log_set_suppress(HASH_TEST, ERRORLEVEL_DEBUG); log_infof(HASH_TEST, STRING_CONST("Task library v%s built for %s using %s (%.*s%.*s)"), string_from_version_static(task_module_version()).str, FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, STRING_FORMAT(build_name), STRING_FORMAT(build_type)); thread_initialize(&event_thread, event_loop, 0, STRING_CONST("event_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&event_thread); pathbuf = memory_allocate(HASH_STRING, BUILD_MAX_PATHLEN, 0, MEMORY_PERSISTENT); while (!thread_is_running(&event_thread)) thread_sleep(10); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_start) { #if FOUNDATION_PLATFORM_ANDROID system_process_events(); #endif thread_sleep(100); } #endif fs_remove_directory(STRING_ARGS(environment_temporary_directory())); #if BUILD_MONOLITHIC test_run_fn tests[] = { test_task_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID thread_t test_thread; thread_initialize(&test_thread, test_runner, tests, STRING_CONST("test_runner"), THREAD_PRIORITY_NORMAL, 0); thread_start(&test_thread); log_debug(HASH_TEST, STRING_CONST("Starting test runner thread")); while (!thread_is_running(&test_thread)) { system_process_events(); thread_sleep(10); } while (thread_is_running(&test_thread)) { system_process_events(); thread_sleep(10); } test_result = thread_join(&test_thread); process_result = (int)(intptr_t)test_result; thread_finalize(&test_thread); #else test_result = test_runner(tests); process_result = (int)(intptr_t)test_result; #endif if (process_result != 0) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_terminate && _test_have_focus && (remain_counter < 50)) { system_process_events(); thread_sleep(100); ++remain_counter; } #endif log_debug(HASH_TEST, STRING_CONST("Exiting main loop")); #else // !BUILD_MONOLITHIC //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = string_const(STRING_CONST("^test-.*\\.exe$")); #elif FOUNDATION_PLATFORM_MACOSX pattern = string_const(STRING_CONST("^test-.*$")); #elif FOUNDATION_PLATFORM_POSIX pattern = string_const(STRING_CONST("^test-.*$")); #else # error Not implemented #endif exe_paths = fs_matching_files(STRING_ARGS(environment_executable_directory()), STRING_ARGS(pattern), false); array_resize(exe_flags, array_size(exe_paths)); memset(exe_flags, 0, sizeof(unsigned int) * array_size(exe_flags)); #if FOUNDATION_PLATFORM_MACOSX //Also search for test applications string_const_t app_pattern = string_const(STRING_CONST("^test-.*\\.app$")); regex_t* app_regex = regex_compile(app_pattern.str, app_pattern.length); string_t* subdirs = fs_subdirs(STRING_ARGS(environment_executable_directory())); for (size_t idir = 0, dirsize = array_size(subdirs); idir < dirsize; ++idir) { if (regex_match(app_regex, subdirs[idir].str, subdirs[idir].length, 0, 0)) { string_t exe_path = { subdirs[idir].str, subdirs[idir].length - 4 }; array_push(exe_paths, exe_path); array_push(exe_flags, PROCESS_MACOSX_USE_OPENAPPLICATION); } } string_array_deallocate(subdirs); regex_deallocate(app_regex); #endif for (iexe = 0, exesize = array_size(exe_paths); iexe < exesize; ++iexe) { string_const_t* process_args = 0; string_const_t exe_file_name = path_base_file_name(STRING_ARGS(exe_paths[iexe])); if (string_equal(STRING_ARGS(exe_file_name), STRING_ARGS(environment_executable_name()))) continue; //Don't run self process_path = path_concat(pathbuf, BUILD_MAX_PATHLEN, STRING_ARGS(environment_executable_directory()), STRING_ARGS(exe_paths[iexe])); process = process_allocate(); process_set_executable_path(process, STRING_ARGS(process_path)); process_set_working_directory(process, STRING_ARGS(environment_executable_directory())); process_set_flags(process, PROCESS_ATTACHED | exe_flags[iexe]); if (!_test_memory_tracker) array_push(process_args, string_const(STRING_CONST("--no-memory-tracker"))); process_set_arguments(process, process_args, array_size(process_args)); log_infof(HASH_TEST, STRING_CONST("Running test executable: %.*s"), STRING_FORMAT(exe_paths[iexe])); process_result = process_spawn(process); while (process_result == PROCESS_WAIT_INTERRUPTED) { thread_sleep(10); process_result = process_wait(process); } process_deallocate(process); array_deallocate(process_args); if (process_result != 0) { if (process_result >= PROCESS_INVALID_ARGS) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed, process terminated with error %x"), process_result); else log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); process_set_exit_code(-1); goto exit; } log_infof(HASH_TEST, STRING_CONST("All tests from %.*s passed (%d)"), STRING_FORMAT(exe_paths[iexe]), process_result); } log_info(HASH_TEST, STRING_CONST("All tests passed")); exit: if (exe_paths) string_array_deallocate(exe_paths); array_deallocate(exe_flags); #endif _test_should_terminate = true; thread_signal(&event_thread); thread_finalize(&event_thread); memory_deallocate(pathbuf); log_infof(HASH_TEST, STRING_CONST("Tests exiting: %s (%d)"), process_result ? "FAILED" : "PASSED", process_result); if (process_result) memory_set_tracker(memory_tracker_none()); return process_result; }
void encodings_init(void) { GtkWidget *item, *menu[2], *submenu, *menu_westeuro, *menu_easteuro, *menu_eastasian, *menu_asian, *menu_utf8, *menu_middleeast, *item_westeuro, *item_easteuro, *item_eastasian, *item_asian, *item_utf8, *item_middleeast; GCallback cb_func[2]; GSList *group = NULL; gchar *label; gint order, group_size; guint i, j, k; init_encodings(); if (! pregs_loaded) { regex_compile(&pregs[0], PATTERN_HTMLMETA); regex_compile(&pregs[1], PATTERN_CODING); pregs_loaded = TRUE; } /* create encodings submenu in document menu */ menu[0] = ui_lookup_widget(main_widgets.window, "set_encoding1_menu"); menu[1] = ui_lookup_widget(main_widgets.window, "menu_reload_as1_menu"); cb_func[0] = G_CALLBACK(encodings_radio_item_change_cb); cb_func[1] = G_CALLBACK(on_reload_as_activate); for (k = 0; k < 2; k++) { menu_westeuro = gtk_menu_new(); item_westeuro = gtk_menu_item_new_with_mnemonic(_("_West European")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_westeuro), menu_westeuro); gtk_container_add(GTK_CONTAINER(menu[k]), item_westeuro); gtk_widget_show_all(item_westeuro); menu_easteuro = gtk_menu_new(); item_easteuro = gtk_menu_item_new_with_mnemonic(_("_East European")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_easteuro), menu_easteuro); gtk_container_add(GTK_CONTAINER(menu[k]), item_easteuro); gtk_widget_show_all(item_easteuro); menu_eastasian = gtk_menu_new(); item_eastasian = gtk_menu_item_new_with_mnemonic(_("East _Asian")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_eastasian), menu_eastasian); gtk_container_add(GTK_CONTAINER(menu[k]), item_eastasian); gtk_widget_show_all(item_eastasian); menu_asian = gtk_menu_new(); item_asian = gtk_menu_item_new_with_mnemonic(_("_SE & SW Asian")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_asian), menu_asian); gtk_container_add(GTK_CONTAINER(menu[k]), item_asian); gtk_widget_show_all(item_asian); menu_middleeast = gtk_menu_new(); item_middleeast = gtk_menu_item_new_with_mnemonic(_("_Middle Eastern")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_middleeast), menu_middleeast); gtk_container_add(GTK_CONTAINER(menu[k]), item_middleeast); gtk_widget_show_all(item_middleeast); menu_utf8 = gtk_menu_new(); item_utf8 = gtk_menu_item_new_with_mnemonic(_("_Unicode")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_utf8), menu_utf8); gtk_container_add(GTK_CONTAINER(menu[k]), item_utf8); gtk_widget_show_all(item_utf8); /** TODO can it be optimized? ATM 3782 runs at line "if (encodings[j].group ...)" */ for (i = 0; i < GEANY_ENCODING_GROUPS_MAX; i++) { order = 0; switch (i) { case WESTEUROPEAN: submenu = menu_westeuro; group_size = 9; break; case EASTEUROPEAN: submenu = menu_easteuro; group_size = 14; break; case EASTASIAN: submenu = menu_eastasian; group_size = 14; break; case ASIAN: submenu = menu_asian; group_size = 9; break; case MIDDLEEASTERN: submenu = menu_middleeast; group_size = 7; break; case UNICODE: submenu = menu_utf8; group_size = 8; break; default: submenu = menu[k]; group_size = 1; } while (order < group_size) /* the biggest group has 13 elements */ { for (j = 0; j < GEANY_ENCODINGS_MAX; j++) { if (encodings[j].group == i && encodings[j].order == order) { label = encodings_to_string(&encodings[j]); if (k == 0) { item = gtk_radio_menu_item_new_with_label(group, label); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); radio_items[j] = item; } else item = gtk_menu_item_new_with_label(label); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(submenu), item); g_signal_connect(item, "activate", cb_func[k], GINT_TO_POINTER(encodings[j].idx)); g_free(label); break; } } order++; } } } }