read_config_file.c revision 307b90b158b79ba3aae61d5c6612b4769b10be5f
1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
4 * Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes
5 * Copyright (C) 2006 Ian Wienand
6 * Copyright (C) 2006 Steve Fink
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include "config.h"
25
26#include <string.h>
27#include <stdlib.h>
28#include <ctype.h>
29#include <errno.h>
30#include <error.h>
31#include <assert.h>
32
33#include "common.h"
34#include "output.h"
35#include "expr.h"
36#include "param.h"
37#include "printf.h"
38#include "zero.h"
39#include "type.h"
40#include "lens.h"
41#include "lens_default.h"
42#include "lens_enum.h"
43
44static int line_no;
45static char *filename;
46struct typedef_node_t;
47
48static struct arg_type_info *parse_nonpointer_type(char **str,
49						   struct param **extra_param,
50						   size_t param_num, int *ownp,
51						   struct typedef_node_t *td);
52static struct arg_type_info *parse_type(char **str, struct param **extra_param,
53					size_t param_num, int *ownp,
54					struct typedef_node_t *in_typedef);
55static struct arg_type_info *parse_lens(char **str, struct param **extra_param,
56					size_t param_num, int *ownp,
57					struct typedef_node_t *in_typedef);
58static int parse_enum(char **str, struct arg_type_info **retp, int *ownp);
59
60Function *list_of_functions = NULL;
61
62static int
63parse_arg_type(char **name, enum arg_type *ret)
64{
65	char *rest = NULL;
66	enum arg_type candidate;
67
68#define KEYWORD(KWD, TYPE)						\
69	do {								\
70		if (strncmp(*name, KWD, sizeof(KWD) - 1) == 0) {	\
71			rest = *name + sizeof(KWD) - 1;			\
72			candidate = TYPE;				\
73			goto ok;					\
74		}							\
75	} while (0)
76
77	KEYWORD("void", ARGTYPE_VOID);
78	KEYWORD("int", ARGTYPE_INT);
79	KEYWORD("uint", ARGTYPE_UINT);
80	KEYWORD("long", ARGTYPE_LONG);
81	KEYWORD("ulong", ARGTYPE_ULONG);
82	KEYWORD("char", ARGTYPE_CHAR);
83	KEYWORD("short", ARGTYPE_SHORT);
84	KEYWORD("ushort", ARGTYPE_USHORT);
85	KEYWORD("float", ARGTYPE_FLOAT);
86	KEYWORD("double", ARGTYPE_DOUBLE);
87	KEYWORD("array", ARGTYPE_ARRAY);
88	KEYWORD("struct", ARGTYPE_STRUCT);
89
90	/* Misspelling of int used in ltrace.conf that we used to
91	 * ship.  */
92	KEYWORD("itn", ARGTYPE_INT);
93
94	assert(rest == NULL);
95	return -1;
96
97#undef KEYWORD
98
99ok:
100	if (isalnum(*rest))
101		return -1;
102
103	*name = rest;
104	*ret = candidate;
105	return 0;
106}
107
108static void
109eat_spaces(char **str) {
110	while (**str == ' ') {
111		(*str)++;
112	}
113}
114
115static char *
116xstrndup(char *str, size_t len) {
117	char *ret = (char *) malloc(len + 1);
118	if (ret == NULL) {
119		report_global_error("malloc: %s", strerror(errno));
120		return NULL;
121	}
122	strncpy(ret, str, len);
123	ret[len] = 0;
124	return ret;
125}
126
127static char *
128parse_ident(char **str) {
129	char *ident = *str;
130
131	if (!isalpha(**str) && **str != '_') {
132		report_error(filename, line_no, "bad identifier");
133		return NULL;
134	}
135
136	while (**str && (isalnum(**str) || **str == '_')) {
137		++(*str);
138	}
139
140	return xstrndup(ident, *str - ident);
141}
142
143/*
144  Returns position in string at the left parenthesis which starts the
145  function's argument signature. Returns NULL on error.
146*/
147static char *
148start_of_arg_sig(char *str) {
149	char *pos;
150	int stacked = 0;
151
152	if (!strlen(str))
153		return NULL;
154
155	pos = &str[strlen(str)];
156	do {
157		pos--;
158		if (pos < str)
159			return NULL;
160		while ((pos > str) && (*pos != ')') && (*pos != '('))
161			pos--;
162
163		if (*pos == ')')
164			stacked++;
165		else if (*pos == '(')
166			stacked--;
167		else
168			return NULL;
169
170	} while (stacked > 0);
171
172	return (stacked == 0) ? pos : NULL;
173}
174
175static int
176parse_int(char **str, long *ret)
177{
178	char *end;
179	long n = strtol(*str, &end, 0);
180	if (end == *str) {
181		report_error(filename, line_no, "bad number");
182		return -1;
183	}
184
185	*str = end;
186	if (ret != NULL)
187		*ret = n;
188	return 0;
189}
190
191static int
192check_nonnegative(long l)
193{
194	if (l < 0) {
195		report_error(filename, line_no,
196			     "expected non-negative value, got %ld", l);
197		return -1;
198	}
199	return 0;
200}
201
202static int
203check_int(long l)
204{
205	int i = l;
206	if ((long)i != l) {
207		report_error(filename, line_no,
208			     "Number too large: %ld", l);
209		return -1;
210	}
211	return 0;
212}
213
214static int
215parse_char(char **str, char expected)
216{
217	if (**str != expected) {
218		report_error(filename, line_no,
219			     "expected '%c', got '%c'", expected, **str);
220		return -1;
221	}
222
223	++*str;
224	return 0;
225}
226
227static struct expr_node *parse_argnum(char **str, int *ownp, int zero);
228
229static struct expr_node *
230parse_zero(char **str, struct expr_node *ret, int *ownp)
231{
232	eat_spaces(str);
233	if (**str == '(') {
234		++*str;
235		int own;
236		struct expr_node *arg = parse_argnum(str, &own, 0);
237		if (arg == NULL)
238			return NULL;
239		if (parse_char(str, ')') < 0) {
240		fail:
241			expr_destroy(arg);
242			free(arg);
243			return NULL;
244		}
245
246		struct expr_node *ret = build_zero_w_arg(arg, own);
247		if (ret == NULL)
248			goto fail;
249		*ownp = 1;
250		return ret;
251
252	} else {
253		free(ret);
254		*ownp = 0;
255		return expr_node_zero();
256	}
257}
258
259static int
260wrap_in_zero(struct expr_node **nodep)
261{
262	struct expr_node *n = build_zero_w_arg(*nodep, 1);
263	if (n == NULL)
264		return -1;
265	*nodep = n;
266	return 0;
267}
268
269/*
270 * Input:
271 *  argN   : The value of argument #N, counting from 1
272 *  eltN   : The value of element #N of the containing structure
273 *  retval : The return value
274 *  N      : The numeric value N
275 */
276static struct expr_node *
277parse_argnum(char **str, int *ownp, int zero)
278{
279	struct expr_node *expr = malloc(sizeof(*expr));
280	if (expr == NULL)
281		return NULL;
282
283	if (isdigit(**str)) {
284		long l;
285		if (parse_int(str, &l) < 0
286		    || check_nonnegative(l) < 0
287		    || check_int(l) < 0)
288			goto fail;
289
290		expr_init_const_word(expr, l, type_get_simple(ARGTYPE_LONG), 0);
291
292		if (zero && wrap_in_zero(&expr) < 0)
293			goto fail;
294
295		*ownp = 1;
296		return expr;
297
298	} else {
299		char *const name = parse_ident(str);
300		if (name == NULL) {
301		fail_ident:
302			free(name);
303			goto fail;
304		}
305
306		int is_arg = strncmp(name, "arg", 3) == 0;
307		if (is_arg || strncmp(name, "elt", 3) == 0) {
308			long l;
309			char *num = name + 3;
310			if (parse_int(&num, &l) < 0 || check_int(l) < 0)
311				goto fail_ident;
312
313			if (is_arg) {
314				if (l == 0)
315					expr_init_named(expr, "retval", 0);
316				else
317					expr_init_argno(expr, l - 1);
318			} else {
319				struct expr_node *e_up = malloc(sizeof(*e_up));
320				struct expr_node *e_ix = malloc(sizeof(*e_ix));
321				if (e_up == NULL || e_ix == NULL) {
322					free(e_up);
323					free(e_ix);
324					goto fail_ident;
325				}
326
327				expr_init_up(e_up, expr_self(), 0);
328				struct arg_type_info *ti
329					= type_get_simple(ARGTYPE_LONG);
330				expr_init_const_word(e_ix, l - 1, ti, 0);
331				expr_init_index(expr, e_up, 1, e_ix, 1);
332			}
333
334		} else if (strcmp(name, "retval") == 0) {
335			expr_init_named(expr, "retval", 0);
336
337		} else if (strcmp(name, "zero") == 0) {
338			struct expr_node *ret = parse_zero(str, expr, ownp);
339			if (ret == NULL)
340				goto fail_ident;
341			return ret;
342
343		} else {
344			report_error(filename, line_no,
345				     "Unknown length specifier: '%s'", name);
346			goto fail_ident;
347		}
348
349		if (zero && wrap_in_zero(&expr) < 0)
350			goto fail_ident;
351
352		free(name);
353		*ownp = 1;
354		return expr;
355	}
356
357fail:
358	free(expr);
359	return NULL;
360}
361
362struct typedef_node_t {
363	char *name;
364	struct arg_type_info *info;
365	int own_type;
366	int forward : 1;
367	struct typedef_node_t *next;
368} *typedefs = NULL;
369
370static struct typedef_node_t *
371lookup_typedef(const char *name)
372{
373	struct typedef_node_t *node;
374	for (node = typedefs; node != NULL; node = node->next)
375		if (strcmp(name, node->name) == 0)
376			return node;
377	return NULL;
378}
379
380static struct arg_type_info *
381parse_typedef_name(char **str)
382{
383	char *end = *str;
384	while (*end && (isalnum(*end) || *end == '_'))
385		++end;
386	if (end == *str)
387		return NULL;
388
389	size_t len = end - *str;
390	char buf[len + 1];
391	memcpy(buf, *str, len);
392	*str += len;
393	buf[len] = 0;
394
395	struct typedef_node_t *td = lookup_typedef(buf);
396	if (td == NULL)
397		return NULL;
398	return td->info;
399}
400
401static void
402insert_typedef(struct typedef_node_t *td)
403{
404	if (td == NULL)
405		return;
406	td->next = typedefs;
407	typedefs = td;
408}
409
410static struct typedef_node_t *
411new_typedef(char *name, struct arg_type_info *info, int own_type)
412{
413	struct typedef_node_t *binding = malloc(sizeof(*binding));
414	binding->name = name;
415	binding->info = info;
416	binding->own_type = own_type;
417	binding->forward = 0;
418	binding->next = NULL;
419	return binding;
420}
421
422static void
423parse_typedef(char **str)
424{
425	(*str) += strlen("typedef");
426	eat_spaces(str);
427	char *name = parse_ident(str);
428
429	/* Look through the typedef list whether we already have a
430	 * forward of this type.  If we do, it must be forward
431	 * structure.  */
432	struct typedef_node_t *forward = lookup_typedef(name);
433	if (forward != NULL
434	    && (forward->info->type != ARGTYPE_STRUCT
435		|| !forward->forward)) {
436		report_error(filename, line_no,
437			     "Redefinition of typedef '%s'", name);
438		return;
439	}
440
441	// Skip = sign
442	eat_spaces(str);
443	if (parse_char(str, '=') < 0)
444		return;
445	eat_spaces(str);
446
447	struct typedef_node_t *this_td = new_typedef(name, NULL, 0);
448	this_td->info = parse_type(str, NULL, 0, &this_td->own_type, this_td);
449
450	if (this_td->info == NULL) {
451		free(this_td);
452		return;
453	}
454
455	if (forward == NULL) {
456		insert_typedef(this_td);
457		return;
458	}
459
460	/* If we are defining a forward, make sure the definition is a
461	 * structure as well.  */
462	if (this_td->info->type != ARGTYPE_STRUCT) {
463		report_error(filename, line_no,
464			     "Definition of forward '%s' must be a structure.",
465			     name);
466		if (this_td->own_type) {
467			type_destroy(this_td->info);
468			free(this_td->info);
469		}
470		return;
471	}
472
473	/* Now move guts of the actual type over to the
474	 * forward type.  We can't just move pointers around,
475	 * because references to forward must stay intact.  */
476	assert(this_td->own_type);
477	type_destroy(forward->info);
478	*forward->info = *this_td->info;
479	forward->forward = 0;
480	free(this_td->info);
481	free(name);
482	free(this_td);
483}
484
485static void
486destroy_fun(Function *fun)
487{
488	size_t i;
489	if (fun == NULL)
490		return;
491	if (fun->own_return_info) {
492		type_destroy(fun->return_info);
493		free(fun->return_info);
494	}
495	for (i = 0; i < fun->num_params; ++i)
496		param_destroy(&fun->params[i]);
497	free(fun->params);
498}
499
500/* Syntax: struct ( type,type,type,... ) */
501static int
502parse_struct(char **str, struct arg_type_info *info,
503	     struct typedef_node_t *in_typedef)
504{
505	eat_spaces(str);
506
507	if (**str == ';') {
508		if (in_typedef == NULL) {
509			report_error(filename, line_no,
510				     "Forward struct can be declared only "
511				     "directly after a typedef.");
512			return -1;
513		}
514
515		/* Forward declaration is currently handled as an
516		 * empty struct.  */
517		type_init_struct(info);
518		in_typedef->forward = 1;
519		return 0;
520	}
521
522	if (parse_char(str, '(') < 0)
523		return -1;
524
525	eat_spaces(str); // Empty arg list with whitespace inside
526
527	type_init_struct(info);
528
529	while (1) {
530		eat_spaces(str);
531		if (**str == 0 || **str == ')') {
532			parse_char(str, ')');
533			return 0;
534		}
535
536		/* Field delimiter.  */
537		if (type_struct_size(info) > 0)
538			parse_char(str, ',');
539
540		eat_spaces(str);
541		int own;
542		struct arg_type_info *field = parse_lens(str, NULL, 0, &own,
543							 NULL);
544		if (field == NULL || type_struct_add(info, field, own)) {
545			type_destroy(info);
546			return -1;
547		}
548	}
549}
550
551static int
552parse_string(char **str, struct arg_type_info **retp, int *ownp)
553{
554	struct arg_type_info *info = malloc(sizeof(*info) * 2);
555	if (info == NULL) {
556	fail:
557		free(info);
558		return -1;
559	}
560
561	struct expr_node *length;
562	int own_length;
563	int with_arg = 0;
564
565	if (isdigit(**str)) {
566		/* string0 is string[retval], length is zero(retval)
567		 * stringN is string[argN], length is zero(argN) */
568		long l;
569		if (parse_int(str, &l) < 0
570		    || check_int(l) < 0)
571			goto fail;
572
573		struct expr_node *length_arg = malloc(sizeof(*length_arg));
574		if (length_arg == NULL)
575			goto fail;
576
577		if (l == 0)
578			expr_init_named(length_arg, "retval", 0);
579		else
580			expr_init_argno(length_arg, l - 1);
581
582		length = build_zero_w_arg(length_arg, 1);
583		if (length == NULL) {
584			expr_destroy(length_arg);
585			free(length_arg);
586			goto fail;
587		}
588		own_length = 1;
589
590	} else {
591		eat_spaces(str);
592		if (**str == '[') {
593			(*str)++;
594			eat_spaces(str);
595
596			length = parse_argnum(str, &own_length, 1);
597			if (length == NULL)
598				goto fail;
599
600			eat_spaces(str);
601			parse_char(str, ']');
602
603		} else if (**str == '(') {
604			/* Usage of "string" as lens.  */
605			++*str;
606
607			free(info);
608
609			eat_spaces(str);
610			info = parse_type(str, NULL, 0, ownp, NULL);
611			if (info == NULL)
612				goto fail;
613
614			eat_spaces(str);
615			parse_char(str, ')');
616
617			with_arg = 1;
618
619		} else {
620			/* It was just a simple string after all.  */
621			length = expr_node_zero();
622			own_length = 0;
623		}
624	}
625
626	/* String is a pointer to array of chars.  */
627	if (!with_arg) {
628		type_init_array(&info[1], type_get_simple(ARGTYPE_CHAR), 0,
629				length, own_length);
630
631		type_init_pointer(&info[0], &info[1], 0);
632		*ownp = 1;
633	}
634
635	info->lens = &string_lens;
636	info->own_lens = 0;
637
638	*retp = info;
639	return 0;
640}
641
642static int
643build_printf_pack(struct param **packp, size_t param_num)
644{
645	if (packp == NULL) {
646		report_error(filename, line_no,
647			     "'format' type in unexpected context");
648		return -1;
649	}
650	if (*packp != NULL) {
651		report_error(filename, line_no,
652			     "only one 'format' type per function supported");
653		return -1;
654	}
655
656	*packp = malloc(sizeof(**packp));
657	if (*packp == NULL)
658		return -1;
659
660	struct expr_node *node = malloc(sizeof(*node));
661	if (node == NULL) {
662		free(*packp);
663		return -1;
664	}
665
666	expr_init_argno(node, param_num);
667
668	param_pack_init_printf(*packp, node, 1);
669
670	return 0;
671}
672
673/* Match and consume KWD if it's next in stream, and return 0.
674 * Otherwise return negative number.  */
675static int
676try_parse_kwd(char **str, const char *kwd)
677{
678	size_t len = strlen(kwd);
679	if (strncmp(*str, kwd, len) == 0
680	    && !isalnum((*str)[len])) {
681		(*str) += len;
682		return 0;
683	}
684	return -1;
685}
686
687/* Make a copy of INFO and set the *OWN bit if it's not already
688 * owned.  */
689static int
690unshare_type_info(struct arg_type_info **infop, int *ownp)
691{
692	if (*ownp)
693		return 0;
694
695	struct arg_type_info *ninfo = malloc(sizeof(*ninfo));
696	if (ninfo == NULL) {
697		report_error(filename, line_no,
698			     "malloc: %s", strerror(errno));
699		return -1;
700	}
701	*ninfo = **infop;
702	*infop = ninfo;
703	*ownp = 1;
704	return 0;
705}
706
707/* XXX extra_param and param_num are a kludge to get in
708 * backward-compatible support for "format" parameter type.  The
709 * latter is only valid if the former is non-NULL, which is only in
710 * top-level context.  */
711static int
712parse_alias(char **str, struct arg_type_info **retp, int *ownp,
713	    struct param **extra_param, size_t param_num)
714{
715	/* For backward compatibility, we need to support things like
716	 * stringN (which is like string[argN], string[N], and also
717	 * bare string.  We might, in theory, replace this by
718	 * preprocessing configure file sources with M4, but for now,
719	 * "string" is syntax.  */
720	if (strncmp(*str, "string", 6) == 0) {
721		(*str) += 6;
722		return parse_string(str, retp, ownp);
723
724	} else if (try_parse_kwd(str, "format") >= 0
725		   && extra_param != NULL) {
726		/* For backward compatibility, format is parsed as
727		 * "string", but it smuggles to the parameter list of
728		 * a function a "printf" argument pack with this
729		 * parameter as argument.  */
730		if (parse_string(str, retp, ownp) < 0)
731			return -1;
732
733		return build_printf_pack(extra_param, param_num);
734
735	} else if (try_parse_kwd(str, "enum") >=0) {
736
737		return parse_enum(str, retp, ownp);
738
739	} else {
740		*retp = NULL;
741		return 0;
742	}
743}
744
745/* Syntax: array ( type, N|argN ) */
746static int
747parse_array(char **str, struct arg_type_info *info)
748{
749	eat_spaces(str);
750	if (parse_char(str, '(') < 0)
751		return -1;
752
753	eat_spaces(str);
754	int own;
755	struct arg_type_info *elt_info = parse_lens(str, NULL, 0, &own, NULL);
756	if (elt_info == NULL)
757		return -1;
758
759	eat_spaces(str);
760	parse_char(str, ',');
761
762	eat_spaces(str);
763	int own_length;
764	struct expr_node *length = parse_argnum(str, &own_length, 0);
765	if (length == NULL) {
766		if (own) {
767			type_destroy(elt_info);
768			free(elt_info);
769		}
770		return -1;
771	}
772
773	type_init_array(info, elt_info, own, length, own_length);
774
775	eat_spaces(str);
776	parse_char(str, ')');
777	return 0;
778}
779
780/* Syntax:
781 *   enum (keyname[=value],keyname[=value],... )
782 *   enum<type> (keyname[=value],keyname[=value],... )
783 */
784static int
785parse_enum(char **str, struct arg_type_info **retp, int *ownp)
786{
787	/* Optional type argument.  */
788	eat_spaces(str);
789	if (**str == '[') {
790		parse_char(str, '[');
791		eat_spaces(str);
792		*retp = parse_nonpointer_type(str, NULL, 0, ownp, 0);
793		if (*retp == NULL)
794			return -1;
795
796		if (!type_is_integral((*retp)->type)) {
797			report_error(filename, line_no,
798				     "integral type required as enum argument");
799		fail:
800			if (*ownp) {
801				/* This also releases associated lens
802				 * if any was set so far.  */
803				type_destroy(*retp);
804				free(*retp);
805			}
806			return -1;
807		}
808
809		eat_spaces(str);
810		if (parse_char(str, ']') < 0)
811			goto fail;
812
813	} else {
814		*retp = type_get_simple(ARGTYPE_INT);
815		*ownp = 0;
816	}
817
818	/* We'll need to set the lens, so unshare.  */
819	if (unshare_type_info(retp, ownp) < 0)
820		goto fail;
821
822	eat_spaces(str);
823	if (parse_char(str, '(') < 0)
824		goto fail;
825
826	struct enum_lens *lens = malloc(sizeof(*lens));
827	if (lens == NULL) {
828		report_error(filename, line_no,
829			     "malloc enum lens: %s", strerror(errno));
830		return -1;
831	}
832
833	lens_init_enum(lens);
834	(*retp)->lens = &lens->super;
835	(*retp)->own_lens = 1;
836
837	long last_val = 0;
838	while (1) {
839		eat_spaces(str);
840		if (**str == 0 || **str == ')') {
841			parse_char(str, ')');
842			return 0;
843		}
844
845		/* Field delimiter.  XXX should we support the C
846		 * syntax, where the enumeration can end in pending
847		 * comma?  */
848		if (lens_enum_size(lens) > 0)
849			parse_char(str, ',');
850
851		eat_spaces(str);
852		char *key = parse_ident(str);
853		if (key == NULL) {
854		err:
855			free(key);
856			goto fail;
857		}
858
859		if (**str == '=') {
860			++*str;
861			eat_spaces(str);
862			if (parse_int(str, &last_val) < 0)
863				goto err;
864		}
865
866		struct value *value = malloc(sizeof(*value));
867		if (value == NULL)
868			goto err;
869		value_init_detached(value, NULL, *retp, 0);
870		value_set_word(value, last_val);
871
872		if (lens_enum_add(lens, key, 1, value, 1) < 0)
873			goto err;
874
875		last_val++;
876	}
877
878	return 0;
879}
880
881static struct arg_type_info *
882parse_nonpointer_type(char **str, struct param **extra_param, size_t param_num,
883		      int *ownp, struct typedef_node_t *in_typedef)
884{
885	enum arg_type type;
886	if (parse_arg_type(str, &type) < 0) {
887		struct arg_type_info *simple;
888		if (parse_alias(str, &simple, ownp, extra_param, param_num) < 0)
889			return NULL;
890		if (simple == NULL)
891			simple = parse_typedef_name(str);
892		if (simple != NULL) {
893			*ownp = 0;
894			return simple;
895		}
896
897		report_error(filename, line_no,
898			     "unknown type around '%s'", *str);
899		return NULL;
900	}
901
902	/* For some types that's all we need.  */
903	switch (type) {
904	case ARGTYPE_VOID:
905	case ARGTYPE_INT:
906	case ARGTYPE_UINT:
907	case ARGTYPE_LONG:
908	case ARGTYPE_ULONG:
909	case ARGTYPE_CHAR:
910	case ARGTYPE_SHORT:
911	case ARGTYPE_USHORT:
912	case ARGTYPE_FLOAT:
913	case ARGTYPE_DOUBLE:
914		*ownp = 0;
915		return type_get_simple(type);
916
917	case ARGTYPE_ARRAY:
918	case ARGTYPE_STRUCT:
919		break;
920
921	case ARGTYPE_POINTER:
922		/* Pointer syntax is not based on keyword, so we
923		 * should never get this type.  */
924		assert(type != ARGTYPE_POINTER);
925		abort();
926	}
927
928	struct arg_type_info *info = malloc(sizeof(*info));
929	if (info == NULL) {
930		report_error(filename, line_no,
931			     "malloc: %s", strerror(errno));
932		return NULL;
933	}
934	*ownp = 1;
935
936	if (type == ARGTYPE_ARRAY) {
937		if (parse_array(str, info) < 0) {
938		fail:
939			free(info);
940			return NULL;
941		}
942	} else {
943		assert(type == ARGTYPE_STRUCT);
944		if (parse_struct(str, info, in_typedef) < 0)
945			goto fail;
946	}
947
948	return info;
949}
950
951static struct named_lens {
952	const char *name;
953	struct lens *lens;
954} lenses[] = {
955	{ "hide", &blind_lens },
956	{ "octal", &octal_lens },
957	{ "hex", &hex_lens },
958	{ "bool", &bool_lens },
959	{ "guess", &guess_lens },
960};
961
962static struct lens *
963name2lens(char **str, int *own_lensp)
964{
965	size_t i;
966	for (i = 0; i < sizeof(lenses)/sizeof(*lenses); ++i)
967		if (try_parse_kwd(str, lenses[i].name) == 0) {
968			*own_lensp = 0;
969			return lenses[i].lens;
970		}
971
972	return NULL;
973}
974
975static struct arg_type_info *
976parse_type(char **str, struct param **extra_param, size_t param_num, int *ownp,
977	   struct typedef_node_t *in_typedef)
978{
979	struct arg_type_info *info
980		= parse_nonpointer_type(str, extra_param,
981					param_num, ownp, in_typedef);
982	if (info == NULL)
983		return NULL;
984
985	while (1) {
986		eat_spaces(str);
987		if (**str == '*') {
988			struct arg_type_info *outer = malloc(sizeof(*outer));
989			if (outer == NULL) {
990				if (*ownp) {
991					type_destroy(info);
992					free(info);
993				}
994				report_error(filename, line_no,
995					     "malloc: %s", strerror(errno));
996				return NULL;
997			}
998			type_init_pointer(outer, info, *ownp);
999			*ownp = 1;
1000			(*str)++;
1001			info = outer;
1002		} else
1003			break;
1004	}
1005	return info;
1006}
1007
1008static struct arg_type_info *
1009parse_lens(char **str, struct param **extra_param, size_t param_num, int *ownp,
1010	   struct typedef_node_t *in_typedef)
1011{
1012	int own_lens;
1013	struct lens *lens = name2lens(str, &own_lens);
1014	int has_args = 1;
1015	struct arg_type_info *info;
1016	if (lens != NULL) {
1017		eat_spaces(str);
1018
1019		/* Octal lens gets special treatment, because of
1020		 * backward compatibility.  */
1021		if (lens == &octal_lens && **str != '(') {
1022			has_args = 0;
1023			info = type_get_simple(ARGTYPE_INT);
1024			*ownp = 0;
1025		} else if (parse_char(str, '(') < 0) {
1026			report_error(filename, line_no,
1027				     "expected type argument after the lens");
1028			return NULL;
1029		}
1030	}
1031
1032	if (has_args) {
1033		eat_spaces(str);
1034		info = parse_type(str, extra_param, param_num, ownp,
1035				  in_typedef);
1036		if (info == NULL) {
1037		fail:
1038			if (own_lens && lens != NULL)
1039				lens_destroy(lens);
1040			return NULL;
1041		}
1042	}
1043
1044	if (lens != NULL && has_args) {
1045		eat_spaces(str);
1046		parse_char(str, ')');
1047	}
1048
1049	/* We can't modify shared types.  Make a copy if we have a
1050	 * lens.  */
1051	if (lens != NULL && unshare_type_info(&info, ownp) < 0)
1052		goto fail;
1053
1054	if (lens != NULL) {
1055		info->lens = lens;
1056		info->own_lens = own_lens;
1057	}
1058
1059	return info;
1060}
1061
1062static int
1063add_param(Function *fun, size_t *allocdp)
1064{
1065	size_t allocd = *allocdp;
1066	/* XXX +1 is for the extra_param handling hack.  */
1067	if ((fun->num_params + 1) >= allocd) {
1068		allocd = allocd > 0 ? 2 * allocd : 8;
1069		void *na = realloc(fun->params, sizeof(*fun->params) * allocd);
1070		if (na == NULL)
1071			return -1;
1072
1073		fun->params = na;
1074		*allocdp = allocd;
1075	}
1076	return 0;
1077}
1078
1079static int
1080param_is_void(struct param *param)
1081{
1082	return param->flavor == PARAM_FLAVOR_TYPE
1083		&& param->u.type.type->type == ARGTYPE_VOID;
1084}
1085
1086static struct arg_type_info *
1087get_hidden_int(void)
1088{
1089	char *str = strdup("hide(int)");
1090	char *ptr = str;
1091	assert(str != NULL);
1092	int own;
1093	struct arg_type_info *info = parse_lens(&ptr, NULL, 0, &own, NULL);
1094	assert(info != NULL);
1095	free(str);
1096	return info;
1097}
1098
1099static Function *
1100process_line(char *buf) {
1101	char *str = buf;
1102	char *tmp;
1103
1104	line_no++;
1105	debug(3, "Reading line %d of `%s'", line_no, filename);
1106	eat_spaces(&str);
1107
1108	/* A comment or empty line.  */
1109	if (*str == ';' || *str == 0 || *str == '\n')
1110		return NULL;
1111
1112	if (strncmp(str, "typedef", 7) == 0) {
1113		parse_typedef(&str);
1114		return NULL;
1115	}
1116
1117	Function *fun = calloc(1, sizeof(*fun));
1118	if (fun == NULL) {
1119		report_error(filename, line_no,
1120			     "alloc function: %s", strerror(errno));
1121		return NULL;
1122	}
1123
1124	fun->return_info = parse_lens(&str, NULL, 0,
1125				      &fun->own_return_info, NULL);
1126	if (fun->return_info == NULL) {
1127	err:
1128		debug(3, " Skipping line %d", line_no);
1129		destroy_fun(fun);
1130		return NULL;
1131	}
1132	debug(4, " return_type = %d", fun->return_info->type);
1133
1134	eat_spaces(&str);
1135	tmp = start_of_arg_sig(str);
1136	if (tmp == NULL) {
1137		report_error(filename, line_no, "syntax error");
1138		goto err;
1139	}
1140	*tmp = '\0';
1141	fun->name = strdup(str);
1142	str = tmp + 1;
1143	debug(3, " name = %s", fun->name);
1144
1145	size_t allocd = 0;
1146	struct param *extra_param = NULL;
1147
1148	int have_stop = 0;
1149
1150	while (1) {
1151		eat_spaces(&str);
1152		if (*str == ')')
1153			break;
1154
1155		if (str[0] == '+') {
1156			if (have_stop == 0) {
1157				if (add_param(fun, &allocd) < 0)
1158					goto add_err;
1159				param_init_stop
1160					(&fun->params[fun->num_params++]);
1161				have_stop = 1;
1162			}
1163			str++;
1164		}
1165
1166		if (add_param(fun, &allocd) < 0) {
1167		add_err:
1168			report_error(filename, line_no, "(re)alloc params: %s",
1169				     strerror(errno));
1170			goto err;
1171		}
1172
1173		int own;
1174		struct arg_type_info *type
1175			= parse_lens(&str, &extra_param,
1176				     fun->num_params - have_stop, &own, NULL);
1177		if (type == NULL) {
1178			report_error(filename, line_no,
1179				     "unknown argument type");
1180			goto err;
1181		}
1182
1183		param_init_type(&fun->params[fun->num_params++], type, own);
1184
1185		eat_spaces(&str);
1186		if (*str == ',') {
1187			str++;
1188			continue;
1189		} else if (*str == ')') {
1190			continue;
1191		} else {
1192			if (str[strlen(str) - 1] == '\n')
1193				str[strlen(str) - 1] = '\0';
1194			report_error(filename, line_no,
1195				     "syntax error around \"%s\"", str);
1196			goto err;
1197		}
1198	}
1199
1200	/* We used to allow void parameter as a synonym to an argument
1201	 * that shouldn't be displayed.  But backends really need to
1202	 * know the exact type that they are dealing with.  The proper
1203	 * way to do this these days is to use the hide lens.
1204	 *
1205	 * So if there are any voids in the parameter list, show a
1206	 * warning and assume that they are ints.  If there's a sole
1207	 * void, assume the function doesn't take any arguments.  The
1208	 * latter is conservative, we can drop the argument
1209	 * altogether, instead of fetching and then not showing it,
1210	 * without breaking any observable behavior.  */
1211	if (fun->num_params == 1 && param_is_void(&fun->params[0])) {
1212		if (0)
1213			/* Don't show this warning.  Pre-0.7.0
1214			 * ltrace.conf often used this idiom.  This
1215			 * should be postponed until much later, when
1216			 * extant uses are likely gone.  */
1217			report_warning(filename, line_no,
1218				       "sole void parameter ignored");
1219		param_destroy(&fun->params[0]);
1220		fun->num_params = 0;
1221	} else {
1222		size_t i;
1223		for (i = 0; i < fun->num_params; ++i) {
1224			if (param_is_void(&fun->params[i])) {
1225				report_warning
1226					(filename, line_no,
1227					 "void parameter assumed to be "
1228					 "'hide(int)'");
1229
1230				static struct arg_type_info *type = NULL;
1231				if (type == NULL)
1232					type = get_hidden_int();
1233				param_destroy(&fun->params[i]);
1234				param_init_type(&fun->params[i], type, 0);
1235			}
1236		}
1237	}
1238
1239	if (extra_param != NULL) {
1240		assert(fun->num_params < allocd);
1241		memcpy(&fun->params[fun->num_params++], extra_param,
1242		       sizeof(*extra_param));
1243		free(extra_param);
1244	}
1245
1246	return fun;
1247}
1248
1249void
1250init_global_config(void)
1251{
1252	struct arg_type_info *info = malloc(2 * sizeof(*info));
1253	if (info == NULL)
1254		error(1, errno, "malloc in init_global_config");
1255
1256	memset(info, 0, 2 * sizeof(*info));
1257	info[0].type = ARGTYPE_POINTER;
1258	info[0].u.ptr_info.info = &info[1];
1259	info[1].type = ARGTYPE_VOID;
1260
1261	insert_typedef(new_typedef(strdup("addr"), info, 0));
1262	insert_typedef(new_typedef(strdup("file"), info, 1));
1263}
1264
1265void
1266read_config_file(char *file) {
1267	FILE *stream;
1268	char buf[1024];
1269
1270	filename = file;
1271	stream = fopen(filename, "r");
1272	if (!stream) {
1273		return;
1274	}
1275
1276	debug(1, "Reading config file `%s'...", filename);
1277
1278	line_no = 0;
1279	while (fgets(buf, 1024, stream)) {
1280		Function *tmp;
1281
1282		tmp = process_line(buf);
1283
1284		if (tmp) {
1285			debug(2, "New function: `%s'", tmp->name);
1286			tmp->next = list_of_functions;
1287			list_of_functions = tmp;
1288		}
1289	}
1290	fclose(stream);
1291}
1292