read_config_file.c revision 28f60197b93b45422a73e5d1a6aa581584d6c4a5
1#include <string.h>
2#include <stdlib.h>
3#include <ctype.h>
4
5#include "ltrace.h"
6#include "read_config_file.h"
7#include "options.h"
8#include "output.h"
9
10/*
11 *	"void"		LT_PT_VOID
12 *	"int"		LT_PT_INT
13 *	"uint"		LT_PT_UINT
14 *	"octal"		LT_PT_OCTAL
15 *	"char"		LT_PT_CHAR
16 *	"string"	LT_PT_STRING
17 *	"format"	LT_PT_FORMAT
18 *	"addr"		LT_PT_ADDR
19 */
20
21struct function * list_of_functions = NULL;
22
23static struct list_of_pt_t {
24	char * name;
25	enum param_type pt;
26} list_of_pt[] = {
27	{ "void",	LT_PT_VOID },
28	{ "int",	LT_PT_INT },
29	{ "uint",	LT_PT_UINT },
30	{ "octal",	LT_PT_OCTAL },
31	{ "char",	LT_PT_CHAR },
32	{ "addr",	LT_PT_ADDR },
33	{ "file",	LT_PT_FILE },
34	{ "format",	LT_PT_FORMAT },
35	{ "string",	LT_PT_STRING },
36	{ "string0",	LT_PT_STRING0 },
37	{ "string1",	LT_PT_STRING1 },
38	{ "string2",	LT_PT_STRING2 },
39	{ "string3",	LT_PT_STRING3 },
40	{ NULL,		LT_PT_UNKNOWN }		/* Must finish with NULL */
41};
42
43static enum param_type str2type(char ** str)
44{
45	struct list_of_pt_t * tmp = &list_of_pt[0];
46
47	while(tmp->name) {
48		if (!strncmp(*str, tmp->name, strlen(tmp->name))
49			&& index(" ,)#", *(*str+strlen(tmp->name)))) {
50				*str += strlen(tmp->name);
51				return tmp->pt;
52		}
53		tmp++;
54	}
55	return LT_PT_UNKNOWN;
56}
57
58static void eat_spaces(char ** str)
59{
60	while(**str==' ') {
61		(*str)++;
62	}
63}
64
65static int line_no;
66static char * filename;
67
68struct function * process_line (char * buf) {
69	struct function fun;
70	struct function * fun_p;
71	char * str = buf;
72	char * tmp;
73	int i;
74
75	line_no++;
76	if (opt_d>2) {
77		output_line(0, "Reading line %d of `%s'", line_no, filename);
78	}
79	eat_spaces(&str);
80	fun.return_type = str2type(&str);
81	if (fun.return_type==LT_PT_UNKNOWN) {
82		if (opt_d>2) {
83			output_line(0, " Skipping line %d", line_no);
84		}
85		return NULL;
86	}
87	if (opt_d>3) {
88		output_line(0, " return_type = %d", fun.return_type);
89	}
90	eat_spaces(&str);
91	tmp = strpbrk(str, " (");
92	if (!tmp) {
93		output_line(0, "Syntax error in `%s', line %d", filename, line_no);
94		return NULL;
95	}
96	*tmp = '\0';
97	fun.name = strdup(str);
98	str = tmp+1;
99	if (opt_d>2) {
100		output_line(0, " name = %s", fun.name);
101	}
102	fun.params_right = 0;
103	for(i=0; i<MAX_ARGS; i++) {
104		eat_spaces(&str);
105		if (*str == ')') {
106			break;
107		}
108		if (str[0]=='+') {
109			fun.params_right++;
110			str++;
111		} else if (fun.params_right) {
112			fun.params_right++;
113		}
114		fun.param_types[i] = str2type(&str);
115		if (fun.return_type==LT_PT_UNKNOWN) {
116			output_line(0, "Syntax error in `%s', line %d", filename, line_no);
117			return NULL;
118		}
119		eat_spaces(&str);
120		if (*str==',') {
121			str++;
122			continue;
123		} else if (*str==')') {
124			continue;
125		} else {
126			output_line(0, "Syntax error in `%s', line %d", filename, line_no);
127			return NULL;
128		}
129	}
130	fun.num_params = i;
131	fun_p = malloc(sizeof(struct function));
132	memcpy(fun_p, &fun, sizeof(struct function));
133	return fun_p;
134}
135
136void read_config_file(char * file)
137{
138	FILE * stream;
139	char buf[1024];
140
141	filename = file;
142
143	if (opt_d) {
144		output_line(0, "Reading config file `%s'...", filename);
145	}
146
147	stream = fopen(filename, "r");
148	if (!stream) {
149		return;
150	}
151	line_no=0;
152	while (fgets(buf, 1024, stream)) {
153		struct function * tmp = process_line(buf);
154
155		if (tmp) {
156			if (opt_d > 1) {
157				output_line(0, "New function: `%s'", tmp->name);
158			}
159			tmp->next = list_of_functions;
160			list_of_functions = tmp;
161		}
162	}
163}
164