@@ -102,6 +102,9 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
102102 }
103103 RConsContext * ctx = cons -> context ;
104104 RConsGrep * grep = & ctx -> grep ;
105+ // reset dynamic tokens from previous grep expression
106+ R_FREE (grep -> tokens );
107+ grep -> tokens_count = 0 ;
105108
106109 size_t str_len = strlen (str );
107110 size_t buf_len = str_len ;
@@ -121,7 +124,14 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
121124 memcpy (buf , str , buf_len );
122125 buf [buf_len ] = '\0' ;
123126
124- char * ptrs [R_CONS_GREP_COUNT ];
127+ // split expression into sub-expressions separated by '~'
128+ size_t ptrs_capacity = buf_len + 1 ;
129+ char * * ptrs = malloc (ptrs_capacity * sizeof (char * ));
130+ if (!ptrs ) {
131+ R_LOG_ERROR ("r_cons_grep: cannot allocate ptrs" );
132+ free (buf );
133+ return ;
134+ }
125135 size_t ptrs_length = 1 ;
126136 ptrs [0 ] = buf ;
127137 char * ptr = buf ;
@@ -131,10 +141,7 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
131141 ptrs [ptrs_length ]++ ;
132142 ptr = ptrs [ptrs_length ];
133143 ptrs_length ++ ;
134- if (ptrs_length >= R_CONS_GREP_COUNT ) {
135- R_LOG_ERROR ("too many nested greps" );
136- goto cleanup ;
137- }
144+ // no static limit: ptrs_capacity is sufficient for buf_len+1 splits
138145 }
139146
140147 R_FREE (grep -> str );
@@ -297,8 +304,9 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
297304 ptr2 ++ ;
298305 for (; ptr2 <= ptr3 ; ptr2 ++ ) {
299306 if (fail ) {
300- ZERO_FILL (grep -> tokens );
301- grep -> tokens_used = 0 ;
307+ // reset dynamic tokens list on failure
308+ R_FREE (grep -> tokens );
309+ grep -> tokens_count = 0 ;
302310 break ;
303311 }
304312 switch (* ptr2 ) {
@@ -309,13 +317,16 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
309317 break ;
310318 case ']' : // fallthrough to handle ']' like ','
311319 case ',' :
320+ // add range of token indices dynamically
312321 for (; range_begin <= range_end ; range_begin ++ ) {
313- if (range_begin >= R_CONS_GREP_TOKENS ) {
314- fail = true;
315- break ;
322+ int idx = (int )range_begin ;
323+ int * tmp = realloc (grep -> tokens , (grep -> tokens_count + 1 ) * sizeof (int ));
324+ if (!tmp ) {
325+ R_LOG_ERROR ("r_cons_grep: cannot allocate tokens" );
326+ goto cleanup ;
316327 }
317- grep -> tokens [ range_begin ] = 1 ;
318- grep -> tokens_used = 1 ;
328+ grep -> tokens = tmp ;
329+ grep -> tokens [ grep -> tokens_count ++ ] = idx ;
319330 }
320331 if (* ptr2 == ']' && is_range && !num_is_parsed ) {
321332 num_is_parsed = true;
@@ -405,8 +416,9 @@ R_API void r_cons_grep_expression(RCons *cons, const char *str) {
405416 r_list_append (grep -> strings , gw );
406417 }
407418cleanup :
419+ free (ptrs );
408420 free (buf );
409- }
421+ }
410422
411423// Finds and returns next intgrep expression, unescapes escaped twiddles
412424static char * find_next_intgrep (char * cmd , const char * quotes ) {
@@ -1120,11 +1132,9 @@ R_API int r_cons_grep_line(char *buf, int len) {
11201132 RConsGrep * grep = & cons -> context -> grep ;
11211133 const char * delims = " |,;=\t" ;
11221134 char * tok = NULL ;
1123- char * save_ptr = NULL ;
11241135 bool hit = true;
11251136 int outlen = 0 ;
11261137 bool use_tok = false;
1127- size_t i ;
11281138
11291139 char * in = calloc (1 , len + 1 );
11301140 if (!in ) {
@@ -1189,11 +1199,13 @@ R_API int r_cons_grep_line(char *buf, int len) {
11891199 } else {
11901200 use_tok = true;
11911201 }
1192- if (use_tok && grep -> tokens_used ) {
1193- for (i = 0 ; i < R_CONS_GREP_TOKENS ; i ++ ) {
1194- tok = r_str_tok_r (i ? NULL : in , delims , & save_ptr );
1195- if (tok ) {
1196- if (grep -> tokens [i ]) {
1202+ if (use_tok && grep -> tokens_count > 0 ) {
1203+ // dynamic tokens selection: pick only specified columns
1204+ char * save_ptr2 = NULL ;
1205+ size_t k , tok_idx = 0 ;
1206+ while ((tok = r_str_tok_r (tok_idx ? NULL : in , delims , & save_ptr2 ))) {
1207+ for (k = 0 ; k < grep -> tokens_count ; k ++ ) {
1208+ if ((size_t )grep -> tokens [k ] == tok_idx ) {
11971209 const size_t toklen = strlen (tok );
11981210 memcpy (out + outlen , tok , toklen );
11991211 memcpy (out + outlen + toklen , " " , 2 );
@@ -1203,19 +1215,13 @@ R_API int r_cons_grep_line(char *buf, int len) {
12031215 free (out );
12041216 return -1 ;
12051217 }
1206- }
1207- } else {
1208- if (* out ) {
12091218 break ;
12101219 }
1211- free (in );
1212- free (out );
1213- return 0 ;
12141220 }
1221+ tok_idx ++ ;
12151222 }
1216- outlen = outlen > 0 ? outlen - 1 : 0 ;
1217- if (outlen > len ) { // should never happen
1218- R_LOG_ERROR ("r_cons_grep_line: wtf, how you reach this?" );
1223+ outlen = outlen > 0 ? outlen - 1 : 0 ;
1224+ if (outlen > len ) {
12191225 free (in );
12201226 free (out );
12211227 return -1 ;
0 commit comments