📄 am_string_array.c
字号:
bool contains_a_number(string_array *sa){ bool result = FALSE; int i; for ( i = 0 ; !result && i < string_array_size(sa) ; i++ ) result = is_a_number(string_array_ref(sa,i)); return(result);}#define UQ_START 0#define UQ_MIDDLE 1#define UQ_INSIDE_Q 2#define UQ_INSIDE_A 3#define UQ_STOP 4void line_count_unquoted(char *string, int *r_num_unquoted_commas, int *r_num_unquoted_bars){ int state = UQ_START; int i = 0; *r_num_unquoted_commas = 0; *r_num_unquoted_bars = 0; while ( state != UQ_STOP ) { char c = string[i]; if ( c == '\0' ) state = UQ_STOP; else { switch ( state ) { case UQ_START: if ( c == ' ' ) state = UQ_START; else if ( c == '\"' ) state = UQ_INSIDE_Q; else if ( c == '\'' ) state = UQ_INSIDE_A; else if ( c == ',' ) { *r_num_unquoted_commas += 1; state = UQ_START; } else if ( c == '|' ) { *r_num_unquoted_bars += 1; state = UQ_START; } else state = UQ_MIDDLE; break; case UQ_MIDDLE: if ( c == ' ' ) state = UQ_START; else if ( c == ',' ) { *r_num_unquoted_commas += 1; state = UQ_START; } else if ( c == '|' ) { *r_num_unquoted_bars += 1; state = UQ_START; } else state = UQ_MIDDLE; break; case UQ_INSIDE_A: if ( c == '\'' ) state = UQ_START; else state = UQ_INSIDE_A; break; case UQ_INSIDE_Q: if ( c == '\"' ) state = UQ_START; else state = UQ_INSIDE_Q; break; default: my_error("wiudbiuwb"); break; } } i += 1; }}string_array *mk_parse_data_line(char *string,int line_format){ char separator; switch ( line_format ) { case WHITESPACE_FORMAT: separator = ' '; break; case COMMA_FORMAT: separator = ','; break; case BAR_FORMAT: separator = '|'; break; case AUTO_FORMAT: { int num_unquoted_commas; int num_unquoted_bars; line_count_unquoted(string,&num_unquoted_commas,&num_unquoted_bars); if ( num_unquoted_commas == 0 && num_unquoted_bars == 0 ) separator = ' '; else if ( num_unquoted_commas >= num_unquoted_bars ) separator = ','; else separator = '|'; break; } default: separator = '?'; my_error("Unknown line_format"); break; } return mk_string_array_from_parse(string,separator);}string_array *mk_next_tokens(PFILE *s,int *line_number,int line_format){ char *line_string = mk_next_interesting_line_string(s,line_number); string_array *tokens; if ( line_string == NULL ) tokens = NULL; else tokens = mk_parse_data_line(line_string,line_format); if ( line_string != NULL ) free_string(line_string); return(tokens);}string_array *mk_default_attribute_names(int num_atts){ string_array *sa = mk_string_array(num_atts); int i; for ( i = 0 ; i < num_atts ; i++ ) { char buff[100]; sprintf(buff,"x%d",i+1); string_array_set(sa,i,buff); } return(sa);} /* private struct */typedef struct parse_state{ int id; int s_action; int s_next; int c_action; int c_next; int a_action; int a_next; int q_action; int q_next; int t_action; int t_next; int end_action;} parse_state;#define CGO 0#define C1 1#define C2 2#define CQS 3#define CQ 4#define CAS 5#define CA 6#define SGO 7#define S1 8#define SQST 9#define SQ 10#define SAST 11#define SA 12#define ADD 0#define PUSH 1#define NIL 2#define DASH 3#define DP 4#define UNKN 5parse_state Parse_array[] =/* State S(act,next) C(act,next) A(act,next) Q(act,next) T(act,next) END(act)*/{{ CGO , NIL ,CGO , UNKN,CGO , NIL ,CAS , NIL ,CQS , PUSH,C1 , UNKN}, { C1 , NIL ,C2 , ADD ,CGO , PUSH,C1 , PUSH,C1 , PUSH,C1 , ADD }, { C2 , NIL ,C2 , ADD ,CGO , DP ,C1 , DP ,C1 , DP ,C1 , ADD }, { CQS , DASH,CQ , PUSH,CQ , PUSH,CQ , NIL ,CGO , PUSH,CQ , UNKN}, { CQ , DASH,CQ , PUSH,CQ , PUSH,CQ , NIL ,C1 , PUSH,CQ , ADD }, { CAS , DASH,CA , PUSH,CA , NIL ,CGO , PUSH,CA , PUSH,CA , UNKN}, { CA , DASH,CA , PUSH,CA , NIL ,C1 , PUSH,CA , PUSH,CA , ADD }, { SGO , NIL ,SGO , PUSH,S1 , NIL ,SAST , NIL ,SQST , PUSH,S1 , NIL }, { S1 , ADD ,SGO , PUSH,S1 , PUSH,S1 , PUSH,S1 , PUSH,S1 , ADD }, { SQST, DASH,SQ , PUSH,SQ , PUSH,SQ , UNKN,SGO , PUSH,SQ , UNKN}, { SQ , DASH,SQ , PUSH,SQ , PUSH,SQ , ADD ,SGO , PUSH,SQ , ADD }, { SAST, DASH,SA , PUSH,SA , UNKN,SA , PUSH,SA , PUSH,SA , UNKN}, { SA , DASH,SA , PUSH,SA , ADD ,SA , PUSH,SA , PUSH,SA , ADD }};string_array *mk_string_array_from_parse(char *s,char separator){ bool space_separated = separator == ' '; int state = (space_separated) ? SGO : CGO; bool finished = FALSE; int s_ptr = 0; string_array *tokarray = mk_string_array(0); int currtok_size = strlen(s) + 1; char *currtok = AM_MALLOC_ARRAY(char,currtok_size); int currtok_ptr = 0; while ( !finished ) { parse_state *ps = &(Parse_array[state]); char c = s[s_ptr]; int action; int next; if ( state != ps->id ) my_error("Parse_array misspecified"); if ( c == '\0' ) { finished = TRUE; next = -1; action = ps->end_action; } else if ( c == ' ' ) { action = ps->s_action ; next = ps->s_next; } else if ( c == '\t' ) { action = ps->s_action ; next = ps->s_next; } else if ( c == separator ) { action = ps->c_action ; next = ps->c_next; } else if ( c == '\'' ) { action = ps->a_action ; next = ps->a_next; } else if ( c == '\"' ) { action = ps->q_action ; next = ps->q_next; } else { action = ps->t_action ; next = ps->t_next; } switch ( action ) { case ADD : currtok[currtok_ptr] = '\0'; add_to_string_array(tokarray,currtok); currtok_ptr = 0; break; case PUSH: currtok[currtok_ptr] = c; currtok_ptr += 1; break; case NIL : /* skip */ break; case DASH: currtok[currtok_ptr] = '_'; currtok_ptr += 1; break; case DP : currtok[currtok_ptr] = '_'; currtok_ptr += 1; currtok[currtok_ptr] = c; currtok_ptr += 1; break; case UNKN: add_to_string_array(tokarray,"?"); currtok_ptr = 0; break; default: my_error("ljdnlkjs"); break; } state = next; s_ptr += 1; } AM_FREE_ARRAY(currtok,char,currtok_size); return(tokarray);}string_array *mk_string_array_from_argc_argv(int argc,char *argv[]){ string_array *sa = mk_string_array(argc); int i; for ( i = 0 ; i < argc ; i++ ) string_array_set(sa,i,argv[i]); return(sa);}/* Makes and returns a string array of given size in which every entry contains a copy of the string stored in value */string_array *mk_constant_string_array(int size,char *value){ string_array *sa = mk_string_array(size); int i; for ( i = 0 ; i < size ; i++ ) string_array_set(sa,i,value); return sa;}/* Parse a boolean from a string array. */bool bool_from_argarray( char *key, string_array *argarray, bool defval){ bool result; int fakeargc, i; char **fakeargv; fakeargc = string_array_size( argarray); fakeargv = mk_array_from_string_array( argarray); result = bool_from_args( key, fakeargc, fakeargv, defval); for( i=0; i<fakeargc; ++i) free_string( fakeargv[i]); AM_FREE_ARRAY( fakeargv, char *, fakeargc); return result;}/* Parse a int from a string array. */int int_from_argarray( char *key, string_array *argarray, int defval){ int result, fakeargc, i; char **fakeargv; fakeargc = string_array_size( argarray); fakeargv = mk_array_from_string_array( argarray); result = int_from_args( key, fakeargc, fakeargv, defval); for( i=0; i<fakeargc; ++i) free_string( fakeargv[i]); AM_FREE_ARRAY( fakeargv, char *, fakeargc); return result;}/* Parse a double from a string array. */double double_from_argarray( char *key, string_array *argarray, double defval){ int fakeargc, i; double result; char **fakeargv; fakeargc = string_array_size( argarray); fakeargv = mk_array_from_string_array( argarray); result = double_from_args( key, fakeargc, fakeargv, defval); for( i=0; i<fakeargc; ++i) free_string( fakeargv[i]); AM_FREE_ARRAY( fakeargv, char *, fakeargc); return result;}/* Parse a string from a string array. */char *mk_string_from_argarray( char *key, string_array *argarray, char *defval){ int size, idx; char *result; size = string_array_size( argarray); idx = find_index_in_string_array( argarray, key); if (idx == size-1) { my_errorf( "mk_string_from_argarray: key '%s' found at end of arguments\n", "but we require a value after the key.", key); } if (idx < 0) result = mk_copy_string( defval); else result = mk_copy_string( string_array_ref( argarray, idx+1)); return result;}/* Split argument array into our options and extra options. This allows one project to parse its options, then pass the unparsed options to another project's parse function. */void mk_split_option_array( string_array *keys_with_args, string_array *keys_without_args, string_array *argarray, string_array **my_opts, string_array **extra_opts){ int i, numargs; char *s; string_array *sa_mine, *sa_extra; numargs = string_array_size( argarray); /* Arrays to hold our args and extra args. */ sa_mine = mk_string_array( 0); sa_extra = mk_string_array( 0); /* Sort args between ours (i.e. one of the keys listed above), and not ours. Note that an extra options which takes an arg will be copied in-order to the sa_extra array, unless the arg val is the same as one of our keys. */ for (i=0; i<numargs; ++i) { /* Token. */ s = string_array_ref( argarray, i); if (string_array_member( keys_without_args, s)) { /* Token is lonely. */ add_to_string_array( sa_mine, s); } else if (string_array_member( keys_with_args, s)) { /* Token should be followed by argument. */ add_to_string_array( sa_mine, s); if (i+1 == numargs) { /* Print error if argument is missing. */ my_errorf( "mk_active_train_option_arrays:\n" "option '%s' is missing its required argument\n", s); } s = string_array_ref( argarray, i+1); add_to_string_array( sa_mine, s); /* Increment i an extra time. */ i = i + 1; } else { /* Extra arg. */ add_to_string_array( sa_extra, s); } } /* Assign arg arrays to my_opts and extra_opts. */ *my_opts = sa_mine; *extra_opts = sa_extra; return;}/*----------------------------------------------------------------*/string_array *mk_split_string(const char *str, const char *delimiter){ string_array *ret = mk_string_array(0); const char *begin = str; const char *c = str; if (!str || !delimiter || strlen(delimiter) == 0) return ret; while ((c = strstr(begin, delimiter))) { if (c - begin == 0) /*two delimiters in a row. Add an empty string*/ { string_array_add(ret, ""); } else /*add the sub string*/ { char *sub_str = AM_MALLOC_ARRAY(char, c-begin+1); strncpy(sub_str, begin, c-begin); sub_str[c-begin] = '\0'; string_array_add(ret, sub_str); AM_FREE_ARRAY(sub_str, char, c-begin+1); } c+= strlen(delimiter); begin = c; } if (!begin) /*str ended in a delimeter. Add an empty string*/ { string_array_add(ret, ""); } else /*add the last string*/ { char *tmp = mk_copy_string(begin); string_array_add(ret, tmp); free_string(tmp); } return ret;}char *mk_join_string_array(const string_array *sa, const char *delimiter){ char *ret = mk_copy_string(""); char *tmp; int i; int size = string_array_size(sa); for (i = 0; i < size; i++) { const char *delim = (i == 0) ? "" : delimiter; tmp = mk_printf("%s%s%s", ret, delim, string_array_ref(sa, i)); free_string(ret); ret = tmp; } return ret;}string_array *mk_append_string_arrays(string_array *a,string_array *b){ string_array *sa = mk_copy_string_array(a); int i; for ( i = 0 ; i < string_array_size(b) ; i++ ) add_to_string_array(sa,string_array_ref(b,i)); return sa;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -