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