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