b59cff4234b7e61a5f12e47bce549a8955bf44a3
[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                 *packp = NULL;
682                 return -1;
683         }
684
685         expr_init_argno(node, param_num);
686
687         param_pack_init_printf(*packp, node, 1);
688
689         return 0;
690 }
691
692 /* Match and consume KWD if it's next in stream, and return 0.
693  * Otherwise return negative number.  */
694 static int
695 try_parse_kwd(char **str, const char *kwd)
696 {
697         size_t len = strlen(kwd);
698         if (strncmp(*str, kwd, len) == 0
699             && !isalnum(CTYPE_CONV((*str)[len]))) {
700                 (*str) += len;
701                 return 0;
702         }
703         return -1;
704 }
705
706 /* XXX extra_param and param_num are a kludge to get in
707  * backward-compatible support for "format" parameter type.  The
708  * latter is only valid if the former is non-NULL, which is only in
709  * top-level context.  */
710 static int
711 parse_alias(struct protolib *plib, struct locus *loc,
712             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(plib, loc, 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(plib, loc, str, retp, ownp) < 0)
731                         return -1;
732
733                 return build_printf_pack(loc, extra_param, param_num);
734
735         } else if (try_parse_kwd(str, "enum") >=0) {
736
737                 return parse_enum(plib, loc, str, retp, ownp);
738
739         } else {
740                 *retp = NULL;
741                 return 0;
742         }
743 }
744
745 /* Syntax: array ( type, N|argN ) */
746 static int
747 parse_array(struct protolib *plib, struct locus *loc,
748             char **str, struct arg_type_info *info)
749 {
750         eat_spaces(str);
751         if (parse_char(loc, str, '(') < 0)
752                 return -1;
753
754         eat_spaces(str);
755         int own;
756         struct arg_type_info *elt_info
757                 = parse_lens(plib, loc, str, NULL, 0, &own, NULL);
758         if (elt_info == NULL)
759                 return -1;
760
761         eat_spaces(str);
762         parse_char(loc, str, ',');
763
764         eat_spaces(str);
765         int own_length;
766         struct expr_node *length = parse_argnum(loc, str, &own_length, 0);
767         if (length == NULL) {
768                 if (own) {
769                         type_destroy(elt_info);
770                         free(elt_info);
771                 }
772                 return -1;
773         }
774
775         type_init_array(info, elt_info, own, length, own_length);
776
777         eat_spaces(str);
778         parse_char(loc, str, ')');
779         return 0;
780 }
781
782 /* Syntax:
783  *   enum (keyname[=value],keyname[=value],... )
784  *   enum<type> (keyname[=value],keyname[=value],... )
785  */
786 static int
787 parse_enum(struct protolib *plib, struct locus *loc, char **str,
788            struct arg_type_info **retp, int *ownp)
789 {
790         /* Optional type argument.  */
791         eat_spaces(str);
792         if (**str == '[') {
793                 parse_char(loc, str, '[');
794                 eat_spaces(str);
795                 *retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, 0);
796                 if (*retp == NULL)
797                         return -1;
798
799                 if (!type_is_integral((*retp)->type)) {
800                         report_error(loc->filename, loc->line_no,
801                                      "integral type required as enum argument");
802                 fail:
803                         if (*ownp) {
804                                 /* This also releases associated lens
805                                  * if any was set so far.  */
806                                 type_destroy(*retp);
807                                 free(*retp);
808                         }
809                         return -1;
810                 }
811
812                 eat_spaces(str);
813                 if (parse_char(loc, str, ']') < 0)
814                         goto fail;
815
816         } else {
817                 *retp = type_get_simple(ARGTYPE_INT);
818                 *ownp = 0;
819         }
820
821         /* We'll need to set the lens, so unshare.  */
822         if (unshare_type_info(loc, retp, ownp) < 0)
823                 goto fail;
824
825         eat_spaces(str);
826         if (parse_char(loc, str, '(') < 0)
827                 goto fail;
828
829         struct enum_lens *lens = malloc(sizeof(*lens));
830         if (lens == NULL) {
831                 report_error(loc->filename, loc->line_no,
832                              "malloc enum lens: %s", strerror(errno));
833                 return -1;
834         }
835
836         lens_init_enum(lens);
837         (*retp)->lens = &lens->super;
838         (*retp)->own_lens = 1;
839
840         long last_val = 0;
841         while (1) {
842                 eat_spaces(str);
843                 if (**str == 0 || **str == ')') {
844                         parse_char(loc, str, ')');
845                         return 0;
846                 }
847
848                 /* Field delimiter.  XXX should we support the C
849                  * syntax, where the enumeration can end in pending
850                  * comma?  */
851                 if (lens_enum_size(lens) > 0)
852                         parse_char(loc, str, ',');
853
854                 eat_spaces(str);
855                 char *key = parse_ident(loc, str);
856                 if (key == NULL) {
857                 err:
858                         free(key);
859                         goto fail;
860                 }
861
862                 if (**str == '=') {
863                         ++*str;
864                         eat_spaces(str);
865                         if (parse_int(loc, str, &last_val) < 0)
866                                 goto err;
867                 }
868
869                 struct value *value = malloc(sizeof(*value));
870                 if (value == NULL)
871                         goto err;
872                 value_init_detached(value, NULL, *retp, 0);
873                 value_set_word(value, last_val);
874
875                 if (lens_enum_add(lens, key, 1, value, 1) < 0)
876                         goto err;
877
878                 last_val++;
879         }
880
881         return 0;
882 }
883
884 static struct arg_type_info *
885 parse_nonpointer_type(struct protolib *plib, struct locus *loc,
886                       char **str, struct param **extra_param, size_t param_num,
887                       int *ownp, int *forwardp)
888 {
889         const char *orig_str = *str;
890         enum arg_type type;
891         if (parse_arg_type(str, &type) < 0) {
892                 struct arg_type_info *type;
893                 if (parse_alias(plib, loc, str, &type,
894                                 ownp, extra_param, param_num) < 0)
895                         return NULL;
896                 else if (type != NULL)
897                         return type;
898
899                 *ownp = 0;
900                 if ((type = parse_typedef_name(plib, str)) == NULL)
901                         report_error(loc->filename, loc->line_no,
902                                      "unknown type around '%s'", orig_str);
903                 return type;
904         }
905
906         /* For some types that's all we need.  */
907         switch (type) {
908         case ARGTYPE_VOID:
909         case ARGTYPE_INT:
910         case ARGTYPE_UINT:
911         case ARGTYPE_LONG:
912         case ARGTYPE_ULONG:
913         case ARGTYPE_CHAR:
914         case ARGTYPE_SHORT:
915         case ARGTYPE_USHORT:
916         case ARGTYPE_FLOAT:
917         case ARGTYPE_DOUBLE:
918                 *ownp = 0;
919                 return type_get_simple(type);
920
921         case ARGTYPE_ARRAY:
922         case ARGTYPE_STRUCT:
923                 break;
924
925         case ARGTYPE_POINTER:
926                 /* Pointer syntax is not based on keyword, so we
927                  * should never get this type.  */
928                 assert(type != ARGTYPE_POINTER);
929                 abort();
930         }
931
932         struct arg_type_info *info = malloc(sizeof(*info));
933         if (info == NULL) {
934                 report_error(loc->filename, loc->line_no,
935                              "malloc: %s", strerror(errno));
936                 return NULL;
937         }
938         *ownp = 1;
939
940         if (type == ARGTYPE_ARRAY) {
941                 if (parse_array(plib, loc, str, info) < 0) {
942                 fail:
943                         free(info);
944                         return NULL;
945                 }
946         } else {
947                 assert(type == ARGTYPE_STRUCT);
948                 if (parse_struct(plib, loc, str, info, forwardp) < 0)
949                         goto fail;
950         }
951
952         return info;
953 }
954
955 static struct named_lens {
956         const char *name;
957         struct lens *lens;
958 } lenses[] = {
959         { "hide", &blind_lens },
960         { "octal", &octal_lens },
961         { "oct", &octal_lens },
962         { "bitvec", &bitvect_lens },
963         { "hex", &hex_lens },
964         { "bool", &bool_lens },
965         { "guess", &guess_lens },
966 };
967
968 static struct lens *
969 name2lens(char **str, int *own_lensp)
970 {
971         size_t i;
972         for (i = 0; i < sizeof(lenses)/sizeof(*lenses); ++i)
973                 if (try_parse_kwd(str, lenses[i].name) == 0) {
974                         *own_lensp = 0;
975                         return lenses[i].lens;
976                 }
977
978         return NULL;
979 }
980
981 static struct arg_type_info *
982 parse_type(struct protolib *plib, struct locus *loc, char **str,
983            struct param **extra_param, size_t param_num,
984            int *ownp, int *forwardp)
985 {
986         struct arg_type_info *info
987                 = parse_nonpointer_type(plib, loc, str, extra_param,
988                                         param_num, ownp, forwardp);
989         if (info == NULL)
990                 return NULL;
991
992         while (1) {
993                 eat_spaces(str);
994                 if (**str == '*') {
995                         struct arg_type_info *outer = malloc(sizeof(*outer));
996                         if (outer == NULL) {
997                                 if (*ownp) {
998                                         type_destroy(info);
999                                         free(info);
1000                                 }
1001                                 report_error(loc->filename, loc->line_no,
1002                                              "malloc: %s", strerror(errno));
1003                                 return NULL;
1004                         }
1005                         type_init_pointer(outer, info, *ownp);
1006                         *ownp = 1;
1007                         (*str)++;
1008                         info = outer;
1009                 } else
1010                         break;
1011         }
1012         return info;
1013 }
1014
1015 static struct arg_type_info *
1016 parse_lens(struct protolib *plib, struct locus *loc,
1017            char **str, struct param **extra_param,
1018            size_t param_num, int *ownp, int *forwardp)
1019 {
1020         int own_lens;
1021         struct lens *lens = name2lens(str, &own_lens);
1022         int has_args = 1;
1023         struct arg_type_info *info;
1024         if (lens != NULL) {
1025                 eat_spaces(str);
1026
1027                 /* Octal lens gets special treatment, because of
1028                  * backward compatibility.  */
1029                 if (lens == &octal_lens && **str != '(') {
1030                         has_args = 0;
1031                         info = type_get_simple(ARGTYPE_INT);
1032                         *ownp = 0;
1033                 } else if (parse_char(loc, str, '(') < 0) {
1034                         report_error(loc->filename, loc->line_no,
1035                                      "expected type argument after the lens");
1036                         return NULL;
1037                 }
1038         }
1039
1040         if (has_args) {
1041                 eat_spaces(str);
1042                 info = parse_type(plib, loc, str, extra_param, param_num,
1043                                   ownp, forwardp);
1044                 if (info == NULL) {
1045                 fail:
1046                         if (own_lens && lens != NULL)
1047                                 lens_destroy(lens);
1048                         return NULL;
1049                 }
1050         }
1051
1052         if (lens != NULL && has_args) {
1053                 eat_spaces(str);
1054                 parse_char(loc, str, ')');
1055         }
1056
1057         /* We can't modify shared types.  Make a copy if we have a
1058          * lens.  */
1059         if (lens != NULL && unshare_type_info(loc, &info, ownp) < 0)
1060                 goto fail;
1061
1062         if (lens != NULL) {
1063                 info->lens = lens;
1064                 info->own_lens = own_lens;
1065         }
1066
1067         return info;
1068 }
1069
1070 static int
1071 param_is_void(struct param *param)
1072 {
1073         return param->flavor == PARAM_FLAVOR_TYPE
1074                 && param->u.type.type->type == ARGTYPE_VOID;
1075 }
1076
1077 static struct arg_type_info *
1078 get_hidden_int(void)
1079 {
1080         static struct arg_type_info info, *pinfo = NULL;
1081         if (pinfo != NULL)
1082                 return pinfo;
1083
1084         info = *type_get_simple(ARGTYPE_INT);
1085         info.lens = &blind_lens;
1086         pinfo = &info;
1087
1088         return pinfo;
1089 }
1090
1091 static enum callback_status
1092 void_to_hidden_int(struct prototype *proto, struct param *param, void *data)
1093 {
1094         struct locus *loc = data;
1095         if (param_is_void(param)) {
1096                 report_warning(loc->filename, loc->line_no,
1097                                "void parameter assumed to be 'hide(int)'");
1098
1099                 static struct arg_type_info *type = NULL;
1100                 if (type == NULL)
1101                         type = get_hidden_int();
1102                 param_destroy(param);
1103                 param_init_type(param, type, 0);
1104         }
1105         return CBS_CONT;
1106 }
1107
1108 static int
1109 process_line(struct protolib *plib, struct locus *loc, char *buf)
1110 {
1111         char *str = buf;
1112         char *tmp;
1113
1114         debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename);
1115         eat_spaces(&str);
1116
1117         /* A comment or empty line.  */
1118         if (*str == ';' || *str == 0 || *str == '\n' || *str == '#')
1119                 return 0;
1120
1121         if (strncmp(str, "typedef", 7) == 0) {
1122                 parse_typedef(plib, loc, &str);
1123                 return 0;
1124         }
1125
1126         struct prototype fun;
1127         prototype_init(&fun);
1128
1129         struct param *extra_param = NULL;
1130         char *proto_name = NULL;
1131         int own;
1132         fun.return_info = parse_lens(plib, loc, &str, NULL, 0, &own, NULL);
1133         if (fun.return_info == NULL) {
1134         err:
1135                 debug(3, " Skipping line %d", loc->line_no);
1136
1137                 if (extra_param != NULL) {
1138                         param_destroy(extra_param);
1139                         free(extra_param);
1140                 }
1141
1142                 prototype_destroy(&fun);
1143                 free(proto_name);
1144                 return -1;
1145         }
1146         fun.own_return_info = own;
1147         debug(4, " return_type = %d", fun.return_info->type);
1148
1149         eat_spaces(&str);
1150         tmp = start_of_arg_sig(str);
1151         if (tmp == NULL) {
1152                 report_error(loc->filename, loc->line_no, "syntax error");
1153                 goto err;
1154         }
1155         *tmp = '\0';
1156
1157         proto_name = strdup(str);
1158         if (proto_name == NULL) {
1159         oom:
1160                 report_error(loc->filename, loc->line_no,
1161                              "%s", strerror(errno));
1162                 goto err;
1163         }
1164
1165         str = tmp + 1;
1166         debug(3, " name = %s", proto_name);
1167
1168         int have_stop = 0;
1169
1170         while (1) {
1171                 eat_spaces(&str);
1172                 if (*str == ')')
1173                         break;
1174
1175                 if (str[0] == '+') {
1176                         if (have_stop == 0) {
1177                                 struct param param;
1178                                 param_init_stop(&param);
1179                                 if (prototype_push_param(&fun, &param) < 0)
1180                                         goto oom;
1181                                 have_stop = 1;
1182                         }
1183                         str++;
1184                 }
1185
1186                 int own;
1187                 size_t param_num = prototype_num_params(&fun) - have_stop;
1188                 struct arg_type_info *type
1189                         = parse_lens(plib, loc, &str, &extra_param,
1190                                      param_num, &own, NULL);
1191                 if (type == NULL) {
1192                         report_error(loc->filename, loc->line_no,
1193                                      "unknown argument type");
1194                         goto err;
1195                 }
1196
1197                 struct param param;
1198                 param_init_type(&param, type, own);
1199                 if (prototype_push_param(&fun, &param) < 0)
1200                         goto oom;
1201
1202                 eat_spaces(&str);
1203                 if (*str == ',') {
1204                         str++;
1205                         continue;
1206                 } else if (*str == ')') {
1207                         continue;
1208                 } else {
1209                         if (str[strlen(str) - 1] == '\n')
1210                                 str[strlen(str) - 1] = '\0';
1211                         report_error(loc->filename, loc->line_no,
1212                                      "syntax error around \"%s\"", str);
1213                         goto err;
1214                 }
1215         }
1216
1217         /* We used to allow void parameter as a synonym to an argument
1218          * that shouldn't be displayed.  But backends really need to
1219          * know the exact type that they are dealing with.  The proper
1220          * way to do this these days is to use the hide lens.
1221          *
1222          * So if there are any voids in the parameter list, show a
1223          * warning and assume that they are ints.  If there's a sole
1224          * void, assume the function doesn't take any arguments.  The
1225          * latter is conservative, we can drop the argument
1226          * altogether, instead of fetching and then not showing it,
1227          * without breaking any observable behavior.  */
1228         if (prototype_num_params(&fun) == 1
1229             && param_is_void(prototype_get_nth_param(&fun, 0))) {
1230                 if (0)
1231                         /* Don't show this warning.  Pre-0.7.0
1232                          * ltrace.conf often used this idiom.  This
1233                          * should be postponed until much later, when
1234                          * extant uses are likely gone.  */
1235                         report_warning(loc->filename, loc->line_no,
1236                                        "sole void parameter ignored");
1237                 prototype_destroy_nth_param(&fun, 0);
1238         } else {
1239                 prototype_each_param(&fun, NULL, void_to_hidden_int, loc);
1240         }
1241
1242         if (extra_param != NULL) {
1243                 prototype_push_param(&fun, extra_param);
1244                 free(extra_param);
1245                 extra_param = NULL;
1246         }
1247
1248         if (protolib_add_prototype(plib, proto_name, 1, &fun) < 0) {
1249                 report_error(loc->filename, loc->line_no,
1250                              "couldn't add prototype: %s",
1251                              strerror(errno));
1252                 goto err;
1253         }
1254
1255         return 0;
1256 }
1257
1258 int
1259 read_config_file(FILE *stream, const char *path, struct protolib *plib)
1260 {
1261         debug(DEBUG_FUNCTION, "Reading config file `%s'...", path);
1262
1263         struct locus loc = { path, 0 };
1264         char *line = NULL;
1265         size_t len = 0;
1266         while (getline(&line, &len, stream) >= 0) {
1267                 loc.line_no++;
1268                 process_line(plib, &loc, line);
1269         }
1270
1271         free(line);
1272         return 0;
1273 }