read_config_file.c revision 1b9cfd6ad305ad909e8ff17139111a7c78f01464
1#if HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include <string.h> 6#include <stdlib.h> 7#include <ctype.h> 8 9#include "ltrace.h" 10#include "read_config_file.h" 11#include "options.h" 12#include "output.h" 13 14/* 15 * "void" ARGTYPE_VOID 16 * "int" ARGTYPE_INT 17 * "uint" ARGTYPE_UINT 18 * "octal" ARGTYPE_OCTAL 19 * "char" ARGTYPE_CHAR 20 * "string" ARGTYPE_STRING 21 * "format" ARGTYPE_FORMAT 22 * "addr" ARGTYPE_ADDR 23 */ 24 25struct function * list_of_functions = NULL; 26 27static struct list_of_pt_t { 28 char * name; 29 enum arg_type pt; 30} list_of_pt[] = { 31 { "void", ARGTYPE_VOID }, 32 { "int", ARGTYPE_INT }, 33 { "uint", ARGTYPE_UINT }, 34 { "octal", ARGTYPE_OCTAL }, 35 { "char", ARGTYPE_CHAR }, 36 { "addr", ARGTYPE_ADDR }, 37 { "file", ARGTYPE_FILE }, 38 { "format", ARGTYPE_FORMAT }, 39 { "string", ARGTYPE_STRING }, 40 { "string0",ARGTYPE_STRING0 }, 41 { "string1",ARGTYPE_STRING1 }, 42 { "string2",ARGTYPE_STRING2 }, 43 { "string3",ARGTYPE_STRING3 }, 44 { NULL, ARGTYPE_UNKNOWN } /* Must finish with NULL */ 45}; 46 47static enum arg_type str2type(char ** str) 48{ 49 struct list_of_pt_t * tmp = &list_of_pt[0]; 50 51 while(tmp->name) { 52 if (!strncmp(*str, tmp->name, strlen(tmp->name)) 53 && index(" ,)#", *(*str+strlen(tmp->name)))) { 54 *str += strlen(tmp->name); 55 return tmp->pt; 56 } 57 tmp++; 58 } 59 return ARGTYPE_UNKNOWN; 60} 61 62static void eat_spaces(char ** str) 63{ 64 while(**str==' ') { 65 (*str)++; 66 } 67} 68 69/* 70 Returns position in string at the left parenthesis which starts the 71 function's argument signature. Returns NULL on error. 72 FIXME: this routine incorrectly returns the beginning of the string in 73 things like "hello)" (cespedes) 74*/ 75static char * start_of_arg_sig(char * str) 76{ 77 char * pos; 78 int stacked = 0; 79 80 if (!strlen(str)) return NULL; 81 82 pos = &str[strlen(str)]; 83 do { 84 pos--; 85 while ((pos > str) && (*pos != ')') && (*pos != '(')) pos--; 86 87 if (pos < str) return NULL; 88 else if (*pos == ')') stacked++; 89 else stacked--; 90 91 } while (stacked > 0); 92 93 return (stacked == 0) ? pos : NULL; 94} 95 96static int line_no; 97static char * filename; 98 99struct function * process_line (char * buf) { 100 struct function fun; 101 struct function * fun_p; 102 char * str = buf; 103 char * tmp; 104 int i; 105 106 line_no++; 107 if (opt_d>2) { 108 output_line(0, "Reading line %d of `%s'", line_no, filename); 109 } 110 eat_spaces(&str); 111 fun.return_type = str2type(&str); 112 if (fun.return_type==ARGTYPE_UNKNOWN) { 113 if (opt_d>2) { 114 output_line(0, " Skipping line %d", line_no); 115 } 116 return NULL; 117 } 118 if (opt_d>3) { 119 output_line(0, " return_type = %d", fun.return_type); 120 } 121 eat_spaces(&str); 122#if 0 /* Obsoleted code. 19990702 mortene. */ 123 /* FIXME: why the space? 19990702 mortene. */ 124 tmp = strpbrk(str, " ("); 125#else 126 tmp = start_of_arg_sig(str); 127#endif 128 if (!tmp) { 129 output_line(0, "Syntax error in `%s', line %d", filename, line_no); 130 return NULL; 131 } 132 *tmp = '\0'; 133 fun.name = strdup(str); 134 str = tmp+1; 135 if (opt_d>2) { 136 output_line(0, " name = %s", fun.name); 137 } 138 fun.params_right = 0; 139 for(i=0; i<MAX_ARGS; i++) { 140 eat_spaces(&str); 141 if (*str == ')') { 142 break; 143 } 144 if (str[0]=='+') { 145 fun.params_right++; 146 str++; 147 } else if (fun.params_right) { 148 fun.params_right++; 149 } 150 fun.arg_types[i] = str2type(&str); 151 if (fun.return_type==ARGTYPE_UNKNOWN) { 152 output_line(0, "Syntax error in `%s', line %d", filename, line_no); 153 return NULL; 154 } 155 eat_spaces(&str); 156 if (*str==',') { 157 str++; 158 continue; 159 } else if (*str==')') { 160 continue; 161 } else { 162 output_line(0, "Syntax error in `%s', line %d", filename, line_no); 163 return NULL; 164 } 165 } 166 fun.num_params = i; 167 fun_p = malloc(sizeof(struct function)); 168 memcpy(fun_p, &fun, sizeof(struct function)); 169 return fun_p; 170} 171 172void read_config_file(char * file) 173{ 174 FILE * stream; 175 char buf[1024]; 176 177 filename = file; 178 179 if (opt_d) { 180 output_line(0, "Reading config file `%s'...", filename); 181 } 182 183 stream = fopen(filename, "r"); 184 if (!stream) { 185 return; 186 } 187 line_no=0; 188 while (fgets(buf, 1024, stream)) { 189 struct function * tmp = process_line(buf); 190 191 if (tmp) { 192 if (opt_d > 1) { 193 output_line(0, "New function: `%s'", tmp->name); 194 } 195 tmp->next = list_of_functions; 196 list_of_functions = tmp; 197 } 198 } 199 fclose(stream); 200} 201