Coverage Report

Created: 2023-09-23 07:04

/src/augeas/src/syntax.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * syntax.c:
3
 *
4
 * Copyright (C) 2007-2016 David Lutterkort
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19
 *
20
 * Author: David Lutterkort <dlutter@redhat.com>
21
 */
22
23
#include <config.h>
24
25
#include <assert.h>
26
#include <stdarg.h>
27
#include <limits.h>
28
#include <ctype.h>
29
#include <glob.h>
30
#include <argz.h>
31
#include <sys/types.h>
32
#include <sys/stat.h>
33
#include <unistd.h>
34
35
#include "memory.h"
36
#include "syntax.h"
37
#include "augeas.h"
38
#include "transform.h"
39
#include "errcode.h"
40
41
/* Extension of source files */
42
#define AUG_EXT ".aug"
43
44
0
#define LNS_TYPE_CHECK(ctx) ((ctx)->aug->flags & AUG_TYPE_CHECK)
45
46
static const char *const builtin_module = "Builtin";
47
48
static const struct type string_type    = { .ref = UINT_MAX, .tag = T_STRING };
49
static const struct type regexp_type    = { .ref = UINT_MAX, .tag = T_REGEXP };
50
static const struct type lens_type      = { .ref = UINT_MAX, .tag = T_LENS };
51
static const struct type tree_type      = { .ref = UINT_MAX, .tag = T_TREE };
52
static const struct type filter_type    = { .ref = UINT_MAX, .tag = T_FILTER };
53
static const struct type transform_type =
54
                                       { .ref = UINT_MAX, .tag = T_TRANSFORM };
55
static const struct type unit_type      = { .ref = UINT_MAX, .tag = T_UNIT };
56
57
const struct type *const t_string    = &string_type;
58
const struct type *const t_regexp    = &regexp_type;
59
const struct type *const t_lens      = &lens_type;
60
const struct type *const t_tree      = &tree_type;
61
const struct type *const t_filter    = &filter_type;
62
const struct type *const t_transform = &transform_type;
63
const struct type *const t_unit      = &unit_type;
64
65
static const char *const type_names[] = {
66
    "string", "regexp", "lens", "tree", "filter",
67
    "transform", "function", "unit", NULL
68
};
69
70
/* The anonymous identifier which we will never bind */
71
static const char anon_ident[] = "_";
72
73
static void print_value(FILE *out, struct value *v);
74
75
/* The evaluation context with all loaded modules and the bindings for the
76
 * module we are working on in LOCAL
77
 */
78
struct ctx {
79
    const char     *name;     /* The module we are working on */
80
    struct augeas  *aug;
81
    struct binding *local;
82
};
83
84
1.52k
static int init_fatal_exn(struct error *error) {
85
1.52k
    if (error->exn != NULL)
86
0
        return 0;
87
1.52k
    error->exn = make_exn_value(ref(error->info), "Error during evaluation");
88
1.52k
    if (error->exn == NULL)
89
0
        return -1;
90
1.52k
    error->exn->exn->seen = 1;
91
1.52k
    error->exn->exn->error = 1;
92
1.52k
    error->exn->exn->lines = NULL;
93
1.52k
    error->exn->exn->nlines = 0;
94
1.52k
    error->exn->ref = REF_MAX;
95
1.52k
    return 0;
96
1.52k
}
97
98
static void format_error(struct info *info, aug_errcode_t code,
99
0
                         const char *format, va_list ap) {
100
0
    struct error *error = info->error;
101
0
    char *si = NULL, *sf = NULL, *sd = NULL;
102
0
    int r;
103
104
0
    error->code = code;
105
    /* Only syntax errors are cumulative */
106
0
    if (code != AUG_ESYNTAX)
107
0
        FREE(error->details);
108
109
0
    si = format_info(info);
110
0
    r = vasprintf(&sf, format, ap);
111
0
    if (r < 0)
112
0
        sf = NULL;
113
0
    if (error->details != NULL) {
114
0
        r = xasprintf(&sd, "%s\n%s%s", error->details,
115
0
                      (si == NULL) ? "(no location)" : si,
116
0
                      (sf == NULL) ? "(no details)" : sf);
117
0
    } else {
118
0
        r = xasprintf(&sd, "%s%s",
119
0
                      (si == NULL) ? "(no location)" : si,
120
0
                      (sf == NULL) ? "(no details)" : sf);
121
0
    }
122
0
    if (r >= 0) {
123
0
        free(error->details);
124
0
        error->details = sd;
125
0
    }
126
0
    free(si);
127
0
    free(sf);
128
0
}
129
130
0
void syntax_error(struct info *info, const char *format, ...) {
131
0
    struct error *error = info->error;
132
0
    va_list ap;
133
134
0
    if (error->code != AUG_NOERROR && error->code != AUG_ESYNTAX)
135
0
        return;
136
137
0
    va_start(ap, format);
138
0
    format_error(info, AUG_ESYNTAX, format, ap);
139
0
    va_end(ap);
140
0
}
141
142
0
void fatal_error(struct info *info, const char *format, ...) {
143
0
    struct error *error = info->error;
144
0
    va_list ap;
145
146
0
    if (error->code == AUG_EINTERNAL)
147
0
        return;
148
149
0
    va_start(ap, format);
150
0
    format_error(info, AUG_EINTERNAL, format, ap);
151
0
    va_end(ap);
152
0
}
153
154
74.6k
static void free_param(struct param *param) {
155
74.6k
    if (param == NULL)
156
0
        return;
157
74.6k
    assert(param->ref == 0);
158
74.6k
    unref(param->info, info);
159
74.6k
    unref(param->name, string);
160
74.6k
    unref(param->type, type);
161
74.6k
    free(param);
162
74.6k
}
163
164
123k
void free_term(struct term *term) {
165
123k
    if (term == NULL)
166
0
        return;
167
123k
    assert(term->ref == 0);
168
123k
    switch(term->tag) {
169
0
    case A_MODULE:
170
0
        free(term->mname);
171
0
        free(term->autoload);
172
0
        unref(term->decls, term);
173
0
        break;
174
0
    case A_BIND:
175
0
        free(term->bname);
176
0
        unref(term->exp, term);
177
0
        break;
178
0
    case A_COMPOSE:
179
0
    case A_UNION:
180
0
    case A_MINUS:
181
0
    case A_CONCAT:
182
0
    case A_APP:
183
0
    case A_LET:
184
0
        unref(term->left, term);
185
0
        unref(term->right, term);
186
0
        break;
187
48.7k
    case A_VALUE:
188
48.7k
        unref(term->value, value);
189
48.7k
        break;
190
48.7k
    case A_IDENT:
191
0
        unref(term->ident, string);
192
0
        break;
193
0
    case A_BRACKET:
194
0
        unref(term->brexp, term);
195
0
        break;
196
74.6k
    case A_FUNC:
197
74.6k
        unref(term->param, param);
198
74.6k
        unref(term->body, term);
199
74.6k
        break;
200
74.6k
    case A_REP:
201
0
        unref(term->rexp, term);
202
0
        break;
203
0
    case A_TEST:
204
0
        unref(term->test, term);
205
0
        unref(term->result, term);
206
0
        break;
207
0
    default:
208
0
        assert(0);
209
0
        break;
210
123k
    }
211
123k
    unref(term->next, term);
212
123k
    unref(term->info, info);
213
123k
    unref(term->type, type);
214
123k
    free(term);
215
123k
}
216
217
123k
static void free_binding(struct binding *binding) {
218
123k
    if (binding == NULL)
219
0
        return;
220
123k
    assert(binding->ref == 0);
221
123k
    unref(binding->next, binding);
222
123k
    unref(binding->ident, string);
223
123k
    unref(binding->type, type);
224
123k
    unref(binding->value, value);
225
123k
    free(binding);
226
123k
}
227
228
3.04k
void free_module(struct module *module) {
229
3.04k
    if (module == NULL)
230
0
        return;
231
3.04k
    assert(module->ref == 0);
232
3.04k
    free(module->name);
233
3.04k
    unref(module->next, module);
234
3.04k
    unref(module->bindings, binding);
235
3.04k
    unref(module->autoload, transform);
236
3.04k
    free(module);
237
3.04k
}
238
239
74.6k
void free_type(struct type *type) {
240
74.6k
    if (type == NULL)
241
0
        return;
242
74.6k
    assert(type->ref == 0);
243
244
74.6k
    if (type->tag == T_ARROW) {
245
74.6k
        unref(type->dom, type);
246
74.6k
        unref(type->img, type);
247
74.6k
    }
248
74.6k
    free(type);
249
74.6k
}
250
251
1.52k
static void free_exn(struct exn *exn) {
252
1.52k
    if (exn == NULL)
253
0
        return;
254
255
1.52k
    unref(exn->info, info);
256
1.52k
    free(exn->message);
257
1.52k
    for (int i=0; i < exn->nlines; i++) {
258
0
        free(exn->lines[i]);
259
0
    }
260
1.52k
    free(exn->lines);
261
1.52k
    free(exn);
262
1.52k
}
263
264
99.0k
void free_value(struct value *v) {
265
99.0k
    if (v == NULL)
266
0
        return;
267
99.0k
    assert(v->ref == 0);
268
269
99.0k
    switch(v->tag) {
270
0
    case V_STRING:
271
0
        unref(v->string, string);
272
0
        break;
273
0
    case V_REGEXP:
274
0
        unref(v->regexp, regexp);
275
0
        break;
276
0
    case V_LENS:
277
0
        unref(v->lens, lens);
278
0
        break;
279
0
    case V_TREE:
280
0
        free_tree(v->origin);
281
0
        break;
282
0
    case V_FILTER:
283
0
        unref(v->filter, filter);
284
0
        break;
285
0
    case V_TRANSFORM:
286
0
        unref(v->transform, transform);
287
0
        break;
288
48.7k
    case V_NATIVE:
289
48.7k
        if (v->native)
290
48.7k
            unref(v->native->type, type);
291
48.7k
        free(v->native);
292
48.7k
        break;
293
48.7k
    case V_CLOS:
294
48.7k
        unref(v->func, term);
295
48.7k
        unref(v->bindings, binding);
296
48.7k
        break;
297
48.7k
    case V_EXN:
298
1.52k
        free_exn(v->exn);
299
1.52k
        break;
300
0
    case V_UNIT:
301
0
        break;
302
0
    default:
303
0
        assert(0);
304
99.0k
    }
305
99.0k
    unref(v->info, info);
306
99.0k
    free(v);
307
99.0k
}
308
309
/*
310
 * Creation of (some) terms. Others are in parser.y
311
 * Reference counted arguments are now owned by the returned object, i.e.
312
 * the make_* functions do not increment the count.
313
 * Returned objects have a referece count of 1.
314
 */
315
74.6k
struct term *make_term(enum term_tag tag, struct info *info) {
316
74.6k
  struct term *term;
317
74.6k
  if (make_ref(term) < 0) {
318
0
      unref(info, info);
319
74.6k
  } else {
320
74.6k
      term->tag = tag;
321
74.6k
      term->info = info;
322
74.6k
  }
323
74.6k
  return term;
324
74.6k
}
325
326
74.6k
struct term *make_param(char *name, struct type *type, struct info *info) {
327
74.6k
  struct term *term = make_term(A_FUNC, info);
328
74.6k
  if (term == NULL)
329
0
      goto error;
330
74.6k
  make_ref_err(term->param);
331
74.6k
  term->param->info = ref(term->info);
332
74.6k
  make_ref_err(term->param->name);
333
74.6k
  term->param->name->str = name;
334
74.6k
  term->param->type = type;
335
74.6k
  return term;
336
0
 error:
337
0
  unref(term, term);
338
0
  return NULL;
339
0
}
340
341
1.52k
struct value *make_value(enum value_tag tag, struct info *info) {
342
1.52k
    struct value *value = NULL;
343
1.52k
    if (make_ref(value) < 0) {
344
0
        unref(info, info);
345
1.52k
    } else {
346
1.52k
        value->tag = tag;
347
1.52k
        value->info = info;
348
1.52k
    }
349
1.52k
    return value;
350
1.52k
}
351
352
0
struct value *make_unit(struct info *info) {
353
0
    return make_value(V_UNIT, info);
354
0
}
355
356
struct term *make_app_term(struct term *lambda, struct term *arg,
357
0
                           struct info *info) {
358
0
  struct term *app = make_term(A_APP, info);
359
0
  if (app == NULL) {
360
0
      unref(lambda, term);
361
0
      unref(arg, term);
362
0
  } else {
363
0
      app->left = lambda;
364
0
      app->right = arg;
365
0
  }
366
0
  return app;
367
0
}
368
369
0
struct term *make_app_ident(char *id, struct term *arg, struct info *info) {
370
0
    struct term *ident = make_term(A_IDENT, ref(info));
371
0
    ident->ident = make_string(id);
372
0
    if (ident->ident == NULL) {
373
0
        unref(arg, term);
374
0
        unref(info, info);
375
0
        unref(ident, term);
376
0
        return NULL;
377
0
    }
378
0
    return make_app_term(ident, arg, info);
379
0
}
380
381
74.6k
struct term *build_func(struct term *params, struct term *exp) {
382
74.6k
  assert(params->tag == A_FUNC);
383
74.6k
  if (params->next != NULL)
384
25.9k
    exp = build_func(params->next, exp);
385
386
74.6k
  params->body = exp;
387
74.6k
  params->next = NULL;
388
74.6k
  return params;
389
74.6k
}
390
391
/* Ownership is taken as needed */
392
48.7k
static struct value *make_closure(struct term *func, struct binding *bnds) {
393
48.7k
    struct value *v = NULL;
394
48.7k
    if (make_ref(v) == 0) {
395
48.7k
        v->tag  = V_CLOS;
396
48.7k
        v->info = ref(func->info);
397
48.7k
        v->func = ref(func);
398
48.7k
        v->bindings = ref(bnds);
399
48.7k
    }
400
48.7k
    return v;
401
48.7k
}
402
403
struct value *make_exn_value(struct info *info,
404
1.52k
                             const char *format, ...) {
405
1.52k
    va_list ap;
406
1.52k
    int r;
407
1.52k
    struct value *v;
408
1.52k
    char *message;
409
410
1.52k
    va_start(ap, format);
411
1.52k
    r = vasprintf(&message, format, ap);
412
1.52k
    va_end(ap);
413
1.52k
    if (r == -1)
414
0
        return NULL;
415
416
1.52k
    v = make_value(V_EXN, ref(info));
417
1.52k
    if (ALLOC(v->exn) < 0)
418
0
        return info->error->exn;
419
1.52k
    v->exn->info = info;
420
1.52k
    v->exn->message = message;
421
422
1.52k
    return v;
423
1.52k
}
424
425
0
void exn_add_lines(struct value *v, int nlines, ...) {
426
0
    assert(v->tag == V_EXN);
427
428
0
    va_list ap;
429
0
    if (REALLOC_N(v->exn->lines, v->exn->nlines + nlines) == -1)
430
0
        return;
431
0
    va_start(ap, nlines);
432
0
    for (int i=0; i < nlines; i++) {
433
0
        char *line = va_arg(ap, char *);
434
0
        v->exn->lines[v->exn->nlines + i] = line;
435
0
    }
436
0
    va_end(ap);
437
0
    v->exn->nlines += nlines;
438
0
}
439
440
0
void exn_printf_line(struct value *exn, const char *format, ...) {
441
0
    va_list ap;
442
0
    int r;
443
0
    char *line;
444
445
0
    va_start(ap, format);
446
0
    r = vasprintf(&line, format, ap);
447
0
    va_end(ap);
448
0
    if (r >= 0)
449
0
        exn_add_lines(exn, 1, line);
450
0
}
451
452
/*
453
 * Modules
454
 */
455
static int load_module(struct augeas *aug, const char *name);
456
static char *module_basename(const char *modname);
457
458
3.04k
struct module *module_create(const char *name) {
459
3.04k
    struct module *module;
460
3.04k
    make_ref(module);
461
3.04k
    module->name = strdup(name);
462
3.04k
    return module;
463
3.04k
}
464
465
0
static struct module *module_find(struct module *module, const char *name) {
466
0
    list_for_each(e, module) {
467
0
        if (STRCASEEQ(e->name, name))
468
0
            return e;
469
0
    }
470
0
    return NULL;
471
0
}
472
473
0
static struct binding *bnd_lookup(struct binding *bindings, const char *name) {
474
0
    list_for_each(b, bindings) {
475
0
        if (STREQ(b->ident->str, name))
476
0
            return b;
477
0
    }
478
0
    return NULL;
479
0
}
480
481
0
static char *modname_of_qname(const char *qname) {
482
0
    char *dot = strchr(qname, '.');
483
0
    if (dot == NULL)
484
0
        return NULL;
485
486
0
    return strndup(qname, dot - qname);
487
0
}
488
489
static int lookup_internal(struct augeas *aug, const char *ctx_modname,
490
0
                           const char *name, struct binding **bnd) {
491
0
    char *modname = modname_of_qname(name);
492
493
0
    *bnd = NULL;
494
495
0
    if (modname == NULL) {
496
0
        struct module *builtin =
497
0
            module_find(aug->modules, builtin_module);
498
0
        assert(builtin != NULL);
499
0
        *bnd = bnd_lookup(builtin->bindings, name);
500
0
        return 0;
501
0
    }
502
503
0
 qual_lookup:
504
0
    list_for_each(module, aug->modules) {
505
0
        if (STRCASEEQ(module->name, modname)) {
506
0
            *bnd = bnd_lookup(module->bindings, name + strlen(modname) + 1);
507
0
            free(modname);
508
0
            return 0;
509
0
        }
510
0
    }
511
    /* Try to load the module */
512
0
    if (streqv(modname, ctx_modname)) {
513
0
        free(modname);
514
0
        return 0;
515
0
    }
516
0
    int loaded = load_module(aug, modname) == 0;
517
0
    if (loaded)
518
0
        goto qual_lookup;
519
520
0
    free(modname);
521
0
    return -1;
522
0
}
523
524
0
struct lens *lens_lookup(struct augeas *aug, const char *qname) {
525
0
    struct binding *bnd = NULL;
526
527
0
    if (lookup_internal(aug, NULL, qname, &bnd) < 0)
528
0
        return NULL;
529
0
    if (bnd == NULL || bnd->value->tag != V_LENS)
530
0
        return NULL;
531
0
    return bnd->value->lens;
532
0
}
533
534
static struct binding *ctx_lookup_bnd(struct info *info,
535
0
                                      struct ctx *ctx, const char *name) {
536
0
    struct binding *b = NULL;
537
0
    int nlen = strlen(ctx->name);
538
539
0
    if (STREQLEN(ctx->name, name, nlen) && name[nlen] == '.')
540
0
        name += nlen + 1;
541
542
0
    b = bnd_lookup(ctx->local, name);
543
0
    if (b != NULL)
544
0
        return b;
545
546
0
    if (ctx->aug != NULL) {
547
0
        int r;
548
0
        r = lookup_internal(ctx->aug, ctx->name, name, &b);
549
0
        if (r == 0)
550
0
            return b;
551
0
        char *modname = modname_of_qname(name);
552
0
        syntax_error(info, "Could not load module %s for %s",
553
0
                     modname, name);
554
0
        free(modname);
555
0
        return NULL;
556
0
    }
557
0
    return NULL;
558
0
}
559
560
static struct value *ctx_lookup(struct info *info,
561
0
                                struct ctx *ctx, struct string *ident) {
562
0
    struct binding *b = ctx_lookup_bnd(info, ctx, ident->str);
563
0
    return b == NULL ? NULL : b->value;
564
0
}
565
566
static struct type *ctx_lookup_type(struct info *info,
567
0
                                    struct ctx *ctx, struct string *ident) {
568
0
    struct binding *b = ctx_lookup_bnd(info, ctx, ident->str);
569
0
    return b == NULL ? NULL : b->type;
570
0
}
571
572
/* Takes ownership as needed */
573
static struct binding *bind_type(struct binding **bnds,
574
48.7k
                                 const char *name, struct type *type) {
575
48.7k
    struct binding *binding;
576
577
48.7k
    if (STREQ(name, anon_ident))
578
0
        return NULL;
579
48.7k
    make_ref(binding);
580
48.7k
    make_ref(binding->ident);
581
48.7k
    binding->ident->str = strdup(name);
582
48.7k
    binding->type = ref(type);
583
48.7k
    list_cons(*bnds, binding);
584
585
48.7k
    return binding;
586
48.7k
}
587
588
/* Takes ownership as needed */
589
static void bind_param(struct binding **bnds, struct param *param,
590
74.6k
                       struct value *v) {
591
74.6k
    struct binding *b;
592
74.6k
    make_ref(b);
593
74.6k
    b->ident = ref(param->name);
594
74.6k
    b->type  = ref(param->type);
595
74.6k
    b->value = ref(v);
596
74.6k
    ref(*bnds);
597
74.6k
    list_cons(*bnds, b);
598
74.6k
}
599
600
74.6k
static void unbind_param(struct binding **bnds, ATTRIBUTE_UNUSED struct param *param) {
601
74.6k
    struct binding *b = *bnds;
602
74.6k
    assert(b->ident == param->name);
603
74.6k
    assert(b->next != *bnds);
604
74.6k
    *bnds = b->next;
605
74.6k
    unref(b, binding);
606
74.6k
}
607
608
/* Takes ownership of VALUE */
609
static void bind(struct binding **bnds,
610
48.7k
                 const char *name, struct type *type, struct value *value) {
611
48.7k
    struct binding *b = NULL;
612
613
48.7k
    if (STRNEQ(name, anon_ident)) {
614
48.7k
        b = bind_type(bnds, name, type);
615
48.7k
        b->value = ref(value);
616
48.7k
    }
617
48.7k
}
618
619
/*
620
 * Some debug printing
621
 */
622
623
static char *type_string(struct type *t);
624
625
0
static void dump_bindings(struct binding *bnds) {
626
0
    list_for_each(b, bnds) {
627
0
        char *st = type_string(b->type);
628
0
        fprintf(stderr, "    %s: %s", b->ident->str, st);
629
0
        fprintf(stderr, " = ");
630
0
        print_value(stderr, b->value);
631
0
        fputc('\n', stderr);
632
0
        free(st);
633
0
    }
634
0
}
635
636
0
static void dump_module(struct module *module) {
637
0
    if (module == NULL)
638
0
        return;
639
0
    fprintf(stderr, "Module %s\n:", module->name);
640
0
    dump_bindings(module->bindings);
641
0
    dump_module(module->next);
642
0
}
643
644
ATTRIBUTE_UNUSED
645
0
static void dump_ctx(struct ctx *ctx) {
646
0
    fprintf(stderr, "Context: %s\n", ctx->name);
647
0
    dump_bindings(ctx->local);
648
0
    if (ctx->aug != NULL) {
649
0
        list_for_each(m, ctx->aug->modules)
650
0
            dump_module(m);
651
0
    }
652
0
}
653
654
/*
655
 * Values
656
 */
657
0
void print_tree_braces(FILE *out, int indent, struct tree *tree) {
658
0
    if (tree == NULL) {
659
0
        fprintf(out, "(null tree)\n");
660
0
        return;
661
0
    }
662
0
    list_for_each(t, tree) {
663
0
        for (int i=0; i < indent; i++) fputc(' ', out);
664
0
        fprintf(out, "{ ");
665
0
        if (t->label != NULL)
666
0
            fprintf(out, "\"%s\"", t->label);
667
0
        if (t->value != NULL)
668
0
            fprintf(out, " = \"%s\"", t->value);
669
0
        if (t->children != NULL) {
670
0
            fputc('\n', out);
671
0
            print_tree_braces(out, indent + 2, t->children);
672
0
            for (int i=0; i < indent; i++) fputc(' ', out);
673
0
        } else {
674
0
            fputc(' ', out);
675
0
        }
676
0
        fprintf(out, "}\n");
677
0
    }
678
0
}
679
680
0
static void print_value(FILE *out, struct value *v) {
681
0
    if (v == NULL) {
682
0
        fprintf(out, "<null>");
683
0
        return;
684
0
    }
685
686
0
    switch(v->tag) {
687
0
    case V_STRING:
688
0
        fprintf(out, "\"%s\"", v->string->str);
689
0
        break;
690
0
    case V_REGEXP:
691
0
        fprintf(out, "/%s/", v->regexp->pattern->str);
692
0
        break;
693
0
    case V_LENS:
694
0
        fprintf(out, "<lens:");
695
0
        print_info(out, v->lens->info);
696
0
        fprintf(out, ">");
697
0
        break;
698
0
    case V_TREE:
699
0
        print_tree_braces(out, 0, v->origin);
700
0
        break;
701
0
    case V_FILTER:
702
0
        fprintf(out, "<filter:");
703
0
        list_for_each(f, v->filter) {
704
0
            fprintf(out, "%c%s%c", f->include ? '+' : '-', f->glob->str,
705
0
                   (f->next != NULL) ? ':' : '>');
706
0
        }
707
0
        break;
708
0
    case V_TRANSFORM:
709
0
        fprintf(out, "<transform:");
710
0
        print_info(out, v->transform->lens->info);
711
0
        fprintf(out, ">");
712
0
        break;
713
0
    case V_NATIVE:
714
0
        fprintf(out, "<native:");
715
0
        print_info(out, v->info);
716
0
        fprintf(out, ">");
717
0
        break;
718
0
    case V_CLOS:
719
0
        fprintf(out, "<closure:");
720
0
        print_info(out, v->func->info);
721
0
        fprintf(out, ">");
722
0
        break;
723
0
    case V_EXN:
724
0
        if (! v->exn->seen) {
725
0
            print_info(out, v->exn->info);
726
0
            fprintf(out, "exception: %s\n", v->exn->message);
727
0
            for (int i=0; i < v->exn->nlines; i++) {
728
0
                fprintf(out, "    %s\n", v->exn->lines[i]);
729
0
            }
730
0
            v->exn->seen = 1;
731
0
        }
732
0
        break;
733
0
    case V_UNIT:
734
0
        fprintf(out, "()");
735
0
        break;
736
0
    default:
737
0
        assert(0);
738
0
        break;
739
0
    }
740
0
}
741
742
0
static int value_equal(struct value *v1, struct value *v2) {
743
0
    if (v1 == NULL && v2 == NULL)
744
0
        return 1;
745
0
    if (v1 == NULL || v2 == NULL)
746
0
        return 0;
747
0
    if (v1->tag != v2->tag)
748
0
        return 0;
749
0
    switch (v1->tag) {
750
0
    case V_STRING:
751
0
        return STREQ(v1->string->str, v2->string->str);
752
0
        break;
753
0
    case V_REGEXP:
754
        // FIXME: Should probably build FA's and compare them
755
0
        return STREQ(v1->regexp->pattern->str, v2->regexp->pattern->str);
756
0
        break;
757
0
    case V_LENS:
758
0
        return v1->lens == v2->lens;
759
0
        break;
760
0
    case V_TREE:
761
0
        return tree_equal(v1->origin->children, v2->origin->children);
762
0
        break;
763
0
    case V_FILTER:
764
0
        return v1->filter == v2->filter;
765
0
        break;
766
0
    case V_TRANSFORM:
767
0
        return v1->transform == v2->transform;
768
0
        break;
769
0
    case V_NATIVE:
770
0
        return v1->native == v2->native;
771
0
        break;
772
0
    case V_CLOS:
773
0
        return v1->func == v2->func && v1->bindings == v2->bindings;
774
0
        break;
775
0
    default:
776
0
        assert(0);
777
0
        abort();
778
0
        break;
779
0
    }
780
0
}
781
782
/*
783
 * Types
784
 */
785
74.6k
struct type *make_arrow_type(struct type *dom, struct type *img) {
786
74.6k
  struct type *type;
787
74.6k
  make_ref(type);
788
74.6k
  type->tag = T_ARROW;
789
74.6k
  type->dom = ref(dom);
790
74.6k
  type->img = ref(img);
791
74.6k
  return type;
792
74.6k
}
793
794
123k
struct type *make_base_type(enum type_tag tag) {
795
123k
    if (tag == T_STRING)
796
44.1k
        return (struct type *) t_string;
797
79.2k
    else if (tag == T_REGEXP)
798
13.7k
        return (struct type *) t_regexp;
799
65.5k
    else if (tag == T_LENS)
800
33.5k
        return (struct type *) t_lens;
801
32.0k
    else if (tag == T_TREE)
802
21.3k
        return (struct type *) t_tree;
803
10.6k
    else if (tag == T_FILTER)
804
4.57k
        return (struct type *) t_filter;
805
6.09k
    else if (tag == T_TRANSFORM)
806
1.52k
        return (struct type *) t_transform;
807
4.57k
    else if (tag == T_UNIT)
808
4.57k
        return (struct type *) t_unit;
809
0
    assert(0);
810
0
    abort();
811
0
}
812
813
0
static const char *type_name(struct type *t) {
814
0
    for (int i = 0; type_names[i] != NULL; i++)
815
0
        if (i == t->tag)
816
0
            return type_names[i];
817
0
    assert(0);
818
0
    abort();
819
0
}
820
821
0
static char *type_string(struct type *t) {
822
0
    if (t->tag == T_ARROW) {
823
0
        char *s = NULL;
824
0
        int r;
825
0
        char *sd = type_string(t->dom);
826
0
        char *si = type_string(t->img);
827
0
        if (t->dom->tag == T_ARROW)
828
0
            r = asprintf(&s, "(%s) -> %s", sd, si);
829
0
        else
830
0
            r = asprintf(&s, "%s -> %s", sd, si);
831
0
        free(sd);
832
0
        free(si);
833
0
        return (r == -1) ? NULL : s;
834
0
    } else {
835
0
        return strdup(type_name(t));
836
0
    }
837
0
}
838
839
/* Decide whether T1 is a subtype of T2. The only subtype relations are
840
 * T_STRING <: T_REGEXP and the usual subtyping of functions based on
841
 * comparing domains/images
842
 *
843
 * Return 1 if T1 is a subtype of T2, 0 otherwise
844
 */
845
0
static int subtype(struct type *t1, struct type *t2) {
846
0
    if (t1 == t2)
847
0
        return 1;
848
    /* We only promote T_STRING => T_REGEXP, no automatic conversion
849
       of strings/regexps to lenses (yet) */
850
0
    if (t1->tag == T_STRING)
851
0
        return (t2->tag == T_STRING || t2->tag == T_REGEXP);
852
0
    if (t1->tag == T_ARROW && t2->tag == T_ARROW) {
853
0
        return subtype(t2->dom, t1->dom)
854
0
            && subtype(t1->img, t2->img);
855
0
    }
856
0
    return t1->tag == t2->tag;
857
0
}
858
859
0
static int type_equal(struct type *t1, struct type *t2) {
860
0
    return (t1 == t2) || (subtype(t1, t2) && subtype(t2, t1));
861
0
}
862
863
/* Return a type T with subtype(T, T1) && subtype(T, T2) */
864
static struct type *type_meet(struct type *t1, struct type *t2);
865
866
/* Return a type T with subtype(T1, T) && subtype(T2, T) */
867
0
static struct type *type_join(struct type *t1, struct type *t2) {
868
0
    if (t1->tag == T_STRING) {
869
0
        if (t2->tag == T_STRING)
870
0
            return ref(t1);
871
0
        else if (t2->tag == T_REGEXP)
872
0
            return ref(t2);
873
0
    } else if (t1->tag == T_REGEXP) {
874
0
        if (t2->tag == T_STRING || t2->tag == T_REGEXP)
875
0
            return ref(t1);
876
0
    } else if (t1->tag == T_ARROW) {
877
0
        if (t2->tag != T_ARROW)
878
0
            return NULL;
879
0
        struct type *dom = type_meet(t1->dom, t2->dom);
880
0
        struct type *img = type_join(t1->img, t2->img);
881
0
        if (dom == NULL || img == NULL) {
882
0
            unref(dom, type);
883
0
            unref(img, type);
884
0
            return NULL;
885
0
        }
886
0
        return make_arrow_type(dom, img);
887
0
    } else if (type_equal(t1, t2)) {
888
0
        return ref(t1);
889
0
    }
890
0
    return NULL;
891
0
}
892
893
/* Return a type T with subtype(T, T1) && subtype(T, T2) */
894
0
static struct type *type_meet(struct type *t1, struct type *t2) {
895
0
    if (t1->tag == T_STRING) {
896
0
        if (t2->tag == T_STRING || t2->tag == T_REGEXP)
897
0
            return ref(t1);
898
0
    } else if (t1->tag == T_REGEXP) {
899
0
        if (t2->tag == T_STRING || t2->tag == T_REGEXP)
900
0
            return ref(t2);
901
0
    } else if (t1->tag == T_ARROW) {
902
0
        if (t2->tag != T_ARROW)
903
0
            return NULL;
904
0
        struct type *dom = type_join(t1->dom, t2->dom);
905
0
        struct type *img = type_meet(t1->img, t2->img);
906
0
        if (dom == NULL || img == NULL) {
907
0
            unref(dom, type);
908
0
            unref(img, type);
909
0
            return NULL;
910
0
        }
911
0
        return make_arrow_type(dom, img);
912
0
    } else if (type_equal(t1, t2)) {
913
0
        return ref(t1);
914
0
    }
915
0
    return NULL;
916
0
}
917
918
0
static struct type *value_type(struct value *v) {
919
0
    switch(v->tag) {
920
0
    case V_STRING:
921
0
        return make_base_type(T_STRING);
922
0
    case V_REGEXP:
923
0
        return make_base_type(T_REGEXP);
924
0
    case V_LENS:
925
0
        return make_base_type(T_LENS);
926
0
    case V_TREE:
927
0
        return make_base_type(T_TREE);
928
0
    case V_FILTER:
929
0
        return make_base_type(T_FILTER);
930
0
    case V_TRANSFORM:
931
0
        return make_base_type(T_TRANSFORM);
932
0
    case V_UNIT:
933
0
        return make_base_type(T_UNIT);
934
0
    case V_NATIVE:
935
0
        return ref(v->native->type);
936
0
    case V_CLOS:
937
0
        return ref(v->func->type);
938
0
    case V_EXN:   /* Fail on exceptions */
939
0
    default:
940
0
        assert(0);
941
0
        abort();
942
0
    }
943
0
}
944
945
/* Coerce V to the type T. Currently, only T_STRING can be coerced to
946
 * T_REGEXP. Returns a value that is owned by the caller. Trying to perform
947
 * an impossible coercion is a fatal error. Receives ownership of V.
948
 */
949
0
static struct value *coerce(struct value *v, struct type *t) {
950
0
    struct type *vt = value_type(v);
951
0
    if (type_equal(vt, t)) {
952
0
        unref(vt, type);
953
0
        return v;
954
0
    }
955
0
    if (vt->tag == T_STRING && t->tag == T_REGEXP) {
956
0
        struct value *rxp = make_value(V_REGEXP, ref(v->info));
957
0
        rxp->regexp = make_regexp_literal(v->info, v->string->str);
958
0
        if (rxp->regexp == NULL) {
959
0
            report_error(v->info->error, AUG_ENOMEM, NULL);
960
0
        };
961
0
        unref(v, value);
962
0
        unref(vt, type);
963
0
        return rxp;
964
0
    }
965
0
    return make_exn_value(v->info, "Type %s can not be coerced to %s",
966
0
                          type_name(vt), type_name(t));
967
0
}
968
969
/* Return one of the expected types (passed as ...).
970
   Does not give ownership of the returned type */
971
static struct type *expect_types_arr(struct info *info,
972
                                     struct type *act,
973
0
                                     int ntypes, struct type *allowed[]) {
974
0
    struct type *result = NULL;
975
976
0
    for (int i=0; i < ntypes; i++) {
977
0
        if (subtype(act, allowed[i])) {
978
0
            result = allowed[i];
979
0
            break;
980
0
        }
981
0
    }
982
0
    if (result == NULL) {
983
0
        int len = 0;
984
0
        for (int i=0; i < ntypes; i++) {
985
0
            len += strlen(type_name(allowed[i]));
986
0
        }
987
0
        len += (ntypes - 1) * 4 + 1;
988
0
        char *allowed_names;
989
0
        if (ALLOC_N(allowed_names, len) < 0)
990
0
            return NULL;
991
0
        for (int i=0; i < ntypes; i++) {
992
0
            if (i > 0)
993
0
                strcat(allowed_names, (i == ntypes - 1) ? ", or " : ", ");
994
0
            strcat(allowed_names, type_name(allowed[i]));
995
0
        }
996
0
        char *act_str = type_string(act);
997
0
        syntax_error(info, "type error: expected %s but found %s",
998
0
                     allowed_names, act_str);
999
0
        free(act_str);
1000
0
        free(allowed_names);
1001
0
    }
1002
0
    return result;
1003
0
}
1004
1005
static struct type *expect_types(struct info *info,
1006
0
                                 struct type *act, int ntypes, ...) {
1007
0
    va_list ap;
1008
0
    struct type *allowed[ntypes];
1009
1010
0
    va_start(ap, ntypes);
1011
0
    for (int i=0; i < ntypes; i++)
1012
0
        allowed[i] = va_arg(ap, struct type *);
1013
0
    va_end(ap);
1014
0
    return expect_types_arr(info, act, ntypes, allowed);
1015
0
}
1016
1017
static struct value *apply(struct term *app, struct ctx *ctx);
1018
1019
typedef struct value *(*impl0)(struct info *);
1020
typedef struct value *(*impl1)(struct info *, struct value *);
1021
typedef struct value *(*impl2)(struct info *, struct value *, struct value *);
1022
typedef struct value *(*impl3)(struct info *, struct value *, struct value *,
1023
                               struct value *);
1024
typedef struct value *(*impl4)(struct info *, struct value *, struct value *,
1025
                               struct value *, struct value *);
1026
typedef struct value *(*impl5)(struct info *, struct value *, struct value *,
1027
                               struct value *, struct value *, struct value *);
1028
1029
static struct value *native_call(struct info *info,
1030
0
                                 struct native *func, struct ctx *ctx) {
1031
0
    struct value *argv[func->argc + 1];
1032
0
    struct binding *b = ctx->local;
1033
1034
0
    for (int i = func->argc - 1; i >= 0; i--) {
1035
0
        argv[i] = b->value;
1036
0
        b = b->next;
1037
0
    }
1038
0
    argv[func->argc] = NULL;
1039
1040
0
    return func->impl(info, argv);
1041
0
}
1042
1043
0
static void type_error1(struct info *info, const char *msg, struct type *type) {
1044
0
    char *s = type_string(type);
1045
0
    syntax_error(info, "Type error: ");
1046
0
    syntax_error(info, msg, s);
1047
0
    free(s);
1048
0
}
1049
1050
static void type_error2(struct info *info, const char *msg,
1051
0
                        struct type *type1, struct type *type2) {
1052
0
    char *s1 = type_string(type1);
1053
0
    char *s2 = type_string(type2);
1054
0
    syntax_error(info, "Type error: ");
1055
0
    syntax_error(info, msg, s1, s2);
1056
0
    free(s1);
1057
0
    free(s2);
1058
0
}
1059
1060
static void type_error_binop(struct info *info, const char *opname,
1061
0
                             struct type *type1, struct type *type2) {
1062
0
    char *s1 = type_string(type1);
1063
0
    char *s2 = type_string(type2);
1064
0
    syntax_error(info, "Type error: ");
1065
0
    syntax_error(info, "%s of %s and %s is not possible", opname, s1, s2);
1066
0
    free(s1);
1067
0
    free(s2);
1068
0
}
1069
1070
static int check_exp(struct term *term, struct ctx *ctx);
1071
1072
static struct type *require_exp_type(struct term *term, struct ctx *ctx,
1073
0
                                     int ntypes, struct type *allowed[]) {
1074
0
    int r = 1;
1075
1076
0
    if (term->type == NULL) {
1077
0
        r = check_exp(term, ctx);
1078
0
        if (! r)
1079
0
            return NULL;
1080
0
    }
1081
1082
0
    return expect_types_arr(term->info, term->type, ntypes, allowed);
1083
0
}
1084
1085
0
static int check_compose(struct term *term, struct ctx *ctx) {
1086
0
    struct type *tl = NULL, *tr = NULL;
1087
1088
0
    if (! check_exp(term->left, ctx))
1089
0
        return 0;
1090
0
    tl = term->left->type;
1091
1092
0
    if (tl->tag == T_ARROW) {
1093
        /* Composition of functions f: a -> b and g: c -> d is defined as
1094
           (f . g) x = g (f x) and is type correct if b <: c yielding a
1095
           function with type a -> d */
1096
0
        if (! check_exp(term->right, ctx))
1097
0
            return 0;
1098
0
        tr = term->right->type;
1099
0
        if (tr->tag != T_ARROW)
1100
0
            goto print_error;
1101
0
        if (! subtype(tl->img, tr->dom))
1102
0
            goto print_error;
1103
0
        term->type = make_arrow_type(tl->dom, tr->img);
1104
0
    } else if (tl->tag == T_UNIT) {
1105
0
        if (! check_exp(term->right, ctx))
1106
0
            return 0;
1107
0
        term->type = ref(term->right->type);
1108
0
    } else {
1109
0
        goto print_error;
1110
0
    }
1111
0
    return 1;
1112
0
 print_error:
1113
0
    type_error_binop(term->info,
1114
0
                     "composition", term->left->type, term->right->type);
1115
0
    return 0;
1116
0
}
1117
1118
static int check_binop(const char *opname, struct term *term,
1119
0
                       struct ctx *ctx, int ntypes, ...) {
1120
0
    va_list ap;
1121
0
    struct type *allowed[ntypes];
1122
0
    struct type *tl = NULL, *tr = NULL;
1123
1124
0
    va_start(ap, ntypes);
1125
0
    for (int i=0; i < ntypes; i++)
1126
0
        allowed[i] = va_arg(ap, struct type *);
1127
0
    va_end(ap);
1128
1129
0
    tl = require_exp_type(term->left, ctx, ntypes, allowed);
1130
0
    if (tl == NULL)
1131
0
        return 0;
1132
1133
0
    tr = require_exp_type(term->right, ctx, ntypes, allowed);
1134
0
    if (tr == NULL)
1135
0
        return 0;
1136
1137
0
    term->type = type_join(tl, tr);
1138
0
    if (term->type == NULL)
1139
0
        goto print_error;
1140
0
    return 1;
1141
0
 print_error:
1142
0
    type_error_binop(term->info, opname, term->left->type, term->right->type);
1143
0
    return 0;
1144
0
}
1145
1146
48.7k
static int check_value(struct term *term) {
1147
48.7k
    const char *msg;
1148
48.7k
    struct value *v = term->value;
1149
1150
48.7k
    if (v->tag == V_REGEXP) {
1151
        /* The only literal that needs checking are regular expressions,
1152
           where we need to make sure the regexp is syntactically
1153
           correct */
1154
0
        if (regexp_check(v->regexp, &msg) == -1) {
1155
0
            syntax_error(v->info, "Invalid regular expression: %s", msg);
1156
0
            return 0;
1157
0
        }
1158
0
        term->type = make_base_type(T_REGEXP);
1159
48.7k
    } else if (v->tag == V_EXN) {
1160
        /* Exceptions can't be typed */
1161
0
        return 0;
1162
48.7k
    } else {
1163
        /* There are cases where we generate values internally, and
1164
           those have their type already set; we don't want to
1165
           overwrite that */
1166
48.7k
        if (term->type == NULL) {
1167
0
            term->type = value_type(v);
1168
0
        }
1169
48.7k
    }
1170
48.7k
    return 1;
1171
48.7k
}
1172
1173
/* Return 1 if TERM passes, 0 otherwise */
1174
123k
static int check_exp(struct term *term, struct ctx *ctx) {
1175
123k
    int result = 1;
1176
123k
    assert(term->type == NULL || term->tag == A_VALUE || term->ref > 1);
1177
123k
    if (term->type != NULL && term->tag != A_VALUE)
1178
0
        return 1;
1179
1180
123k
    switch (term->tag) {
1181
0
    case A_UNION:
1182
0
        result = check_binop("union", term, ctx, 2, t_regexp, t_lens);
1183
0
        break;
1184
0
    case A_MINUS:
1185
0
        result = check_binop("minus", term, ctx, 1, t_regexp);
1186
0
        break;
1187
0
    case A_COMPOSE:
1188
0
        result = check_compose(term, ctx);
1189
0
        break;
1190
0
    case A_CONCAT:
1191
0
        result = check_binop("concatenation", term, ctx,
1192
0
                             4, t_string, t_regexp, t_lens, t_filter);
1193
0
        break;
1194
0
    case A_LET:
1195
0
        {
1196
0
            result = check_exp(term->right, ctx);
1197
0
            if (result) {
1198
0
                struct term *func = term->left;
1199
0
                assert(func->tag == A_FUNC);
1200
0
                assert(func->param->type == NULL);
1201
0
                func->param->type = ref(term->right->type);
1202
1203
0
                result = check_exp(func, ctx);
1204
0
                if (result) {
1205
0
                    term->tag = A_APP;
1206
0
                    term->type = ref(func->type->img);
1207
0
                }
1208
0
            }
1209
0
        }
1210
0
        break;
1211
0
    case A_APP:
1212
0
        result = check_exp(term->left, ctx) & check_exp(term->right, ctx);
1213
0
        if (result) {
1214
0
            if (term->left->type->tag != T_ARROW) {
1215
0
                type_error1(term->info,
1216
0
                            "expected function in application but found %s",
1217
0
                            term->left->type);
1218
0
                result = 0;
1219
0
            };
1220
0
        }
1221
0
        if (result) {
1222
0
            result = expect_types(term->info,
1223
0
                                  term->right->type,
1224
0
                                  1, term->left->type->dom) != NULL;
1225
0
            if (! result) {
1226
0
                type_error_binop(term->info, "application",
1227
0
                                 term->left->type, term->right->type);
1228
0
                result = 0;
1229
0
            }
1230
0
        }
1231
0
        if (result)
1232
0
            term->type = ref(term->left->type->img);
1233
0
        break;
1234
48.7k
    case A_VALUE:
1235
48.7k
        result = check_value(term);
1236
48.7k
        break;
1237
0
    case A_IDENT:
1238
0
        {
1239
0
            struct type *t = ctx_lookup_type(term->info, ctx, term->ident);
1240
0
            if (t == NULL) {
1241
0
                syntax_error(term->info, "Undefined variable %s",
1242
0
                             term->ident->str);
1243
0
                result = 0;
1244
0
            } else {
1245
0
                term->type = ref(t);
1246
0
            }
1247
0
        }
1248
0
        break;
1249
0
    case A_BRACKET:
1250
0
        result = check_exp(term->brexp, ctx);
1251
0
        if (result) {
1252
0
            term->type = ref(expect_types(term->info, term->brexp->type,
1253
0
                                          1, t_lens));
1254
0
            if (term->type == NULL) {
1255
0
                type_error1(term->info,
1256
0
                             "[..] is only defined for lenses, not for %s",
1257
0
                            term->brexp->type);
1258
0
                result = 0;
1259
0
            }
1260
0
        }
1261
0
        break;
1262
74.6k
    case A_FUNC:
1263
74.6k
        {
1264
74.6k
            bind_param(&ctx->local, term->param, NULL);
1265
74.6k
            result = check_exp(term->body, ctx);
1266
74.6k
            if (result) {
1267
74.6k
                term->type =
1268
74.6k
                    make_arrow_type(term->param->type, term->body->type);
1269
74.6k
            }
1270
74.6k
            unbind_param(&ctx->local, term->param);
1271
74.6k
        }
1272
74.6k
        break;
1273
0
    case A_REP:
1274
0
        result = check_exp(term->exp, ctx);
1275
0
        if (result) {
1276
0
            term->type = ref(expect_types(term->info, term->exp->type, 2,
1277
0
                                          t_regexp, t_lens));
1278
0
            if (term->type == NULL) {
1279
0
                type_error1(term->info,
1280
0
                            "Incompatible types: repetition is only defined"
1281
0
                            " for regexp and lens, not for %s",
1282
0
                            term->exp->type);
1283
0
                result = 0;
1284
0
            }
1285
0
        }
1286
0
        break;
1287
0
    default:
1288
0
        assert(0);
1289
0
        break;
1290
123k
    }
1291
123k
    assert(!result || term->type != NULL);
1292
123k
    return result;
1293
123k
}
1294
1295
0
static int check_decl(struct term *term, struct ctx *ctx) {
1296
0
    assert(term->tag == A_BIND || term->tag == A_TEST);
1297
1298
0
    if (term->tag == A_BIND) {
1299
0
        if (!check_exp(term->exp, ctx))
1300
0
            return 0;
1301
0
        term->type = ref(term->exp->type);
1302
1303
0
        if (bnd_lookup(ctx->local, term->bname) != NULL) {
1304
0
            syntax_error(term->info,
1305
0
                         "the name %s is already defined", term->bname);
1306
0
            return 0;
1307
0
        }
1308
0
        bind_type(&ctx->local, term->bname, term->type);
1309
0
    } else if (term->tag == A_TEST) {
1310
0
        if (!check_exp(term->test, ctx))
1311
0
            return 0;
1312
0
        if (term->result != NULL) {
1313
0
            if (!check_exp(term->result, ctx))
1314
0
                return 0;
1315
0
            if (! type_equal(term->test->type, term->result->type)) {
1316
0
                type_error2(term->info,
1317
0
                            "expected test result of type %s but got %s",
1318
0
                            term->result->type, term->test->type);
1319
0
                return 0;
1320
0
            }
1321
0
        } else {
1322
0
            if (expect_types(term->info, term->test->type, 2,
1323
0
                             t_string, t_tree) == NULL)
1324
0
                return 0;
1325
0
        }
1326
0
        term->type = ref(term->test->type);
1327
0
    } else {
1328
0
        assert(0);
1329
0
    }
1330
0
    return 1;
1331
0
}
1332
1333
0
static int typecheck(struct term *term, struct augeas *aug) {
1334
0
    int ok = 1;
1335
0
    struct ctx ctx;
1336
0
    char *fname;
1337
0
    const char *basenam;
1338
1339
0
    assert(term->tag == A_MODULE);
1340
1341
    /* Check that the module name is consistent with the filename */
1342
0
    fname = module_basename(term->mname);
1343
1344
0
    basenam = strrchr(term->info->filename->str, SEP);
1345
0
    if (basenam == NULL)
1346
0
        basenam = term->info->filename->str;
1347
0
    else
1348
0
        basenam += 1;
1349
0
    if (STRNEQ(fname, basenam)) {
1350
0
        syntax_error(term->info,
1351
0
                     "The module %s must be in a file named %s",
1352
0
                     term->mname, fname);
1353
0
        free(fname);
1354
0
        return 0;
1355
0
    }
1356
0
    free(fname);
1357
1358
0
    ctx.aug = aug;
1359
0
    ctx.local = NULL;
1360
0
    ctx.name = term->mname;
1361
0
    list_for_each(dcl, term->decls) {
1362
0
        ok &= check_decl(dcl, &ctx);
1363
0
    }
1364
0
    unref(ctx.local, binding);
1365
0
    return ok;
1366
0
}
1367
1368
static struct value *compile_exp(struct info *, struct term *, struct ctx *);
1369
1370
0
static struct value *compile_union(struct term *exp, struct ctx *ctx) {
1371
0
    struct value *v1 = compile_exp(exp->info, exp->left, ctx);
1372
0
    if (EXN(v1))
1373
0
        return v1;
1374
0
    struct value *v2 = compile_exp(exp->info, exp->right, ctx);
1375
0
    if (EXN(v2)) {
1376
0
        unref(v1, value);
1377
0
        return v2;
1378
0
    }
1379
1380
0
    struct type *t = exp->type;
1381
0
    struct info *info = exp->info;
1382
0
    struct value *v = NULL;
1383
1384
0
    v1 = coerce(v1, t);
1385
0
    if (EXN(v1))
1386
0
        return v1;
1387
0
    v2 = coerce(v2, t);
1388
0
    if (EXN(v2)) {
1389
0
        unref(v1, value);
1390
0
        return v2;
1391
0
    }
1392
1393
0
    if (t->tag == T_REGEXP) {
1394
0
        v = make_value(V_REGEXP, ref(info));
1395
0
        v->regexp = regexp_union(info, v1->regexp, v2->regexp);
1396
0
    } else if (t->tag == T_LENS) {
1397
0
        struct lens *l1 = v1->lens;
1398
0
        struct lens *l2 = v2->lens;
1399
0
        v = lns_make_union(ref(info), ref(l1), ref(l2), LNS_TYPE_CHECK(ctx));
1400
0
    } else {
1401
0
        fatal_error(info, "Tried to union a %s and a %s to yield a %s",
1402
0
                    type_name(exp->left->type), type_name(exp->right->type),
1403
0
                    type_name(t));
1404
0
    }
1405
0
    unref(v1, value);
1406
0
    unref(v2, value);
1407
0
    return v;
1408
0
}
1409
1410
0
static struct value *compile_minus(struct term *exp, struct ctx *ctx) {
1411
0
    struct value *v1 = compile_exp(exp->info, exp->left, ctx);
1412
0
    if (EXN(v1))
1413
0
        return v1;
1414
0
    struct value *v2 = compile_exp(exp->info, exp->right, ctx);
1415
0
    if (EXN(v2)) {
1416
0
        unref(v1, value);
1417
0
        return v2;
1418
0
    }
1419
1420
0
    struct type *t = exp->type;
1421
0
    struct info *info = exp->info;
1422
0
    struct value *v;
1423
1424
0
    v1 = coerce(v1, t);
1425
0
    v2 = coerce(v2, t);
1426
0
    if (t->tag == T_REGEXP) {
1427
0
        struct regexp *re1 = v1->regexp;
1428
0
        struct regexp *re2 = v2->regexp;
1429
0
        struct regexp *re = regexp_minus(info, re1, re2);
1430
0
        if (re == NULL) {
1431
0
            v = make_exn_value(ref(info),
1432
0
                   "Regular expression subtraction 'r1 - r2' failed");
1433
0
            exn_printf_line(v, "r1: /%s/", re1->pattern->str);
1434
0
            exn_printf_line(v, "r2: /%s/", re2->pattern->str);
1435
0
        } else {
1436
0
            v = make_value(V_REGEXP, ref(info));
1437
0
            v->regexp = re;
1438
0
        }
1439
0
    } else {
1440
0
        v = NULL;
1441
0
        fatal_error(info, "Tried to subtract a %s and a %s to yield a %s",
1442
0
                    type_name(exp->left->type), type_name(exp->right->type),
1443
0
                    type_name(t));
1444
0
    }
1445
0
    unref(v1, value);
1446
0
    unref(v2, value);
1447
0
    return v;
1448
0
}
1449
1450
0
static struct value *compile_compose(struct term *exp, struct ctx *ctx) {
1451
0
    struct info *info = exp->info;
1452
0
    struct value *v;
1453
1454
0
    if (exp->left->type->tag == T_ARROW) {
1455
        // FIXME: This is really crufty, and should be desugared in the
1456
        // parser so that we don't have to do all this manual type
1457
        // computation. Should we write function compostion as
1458
        // concatenation instead of using a separate syntax ?
1459
1460
        /* Build lambda x: exp->right (exp->left x) as a closure */
1461
0
        char *var = strdup("@0");
1462
0
        struct term *func = make_param(var, ref(exp->left->type->dom),
1463
0
                                       ref(info));
1464
0
        func->type = make_arrow_type(exp->left->type->dom,
1465
0
                                     exp->right->type->img);
1466
0
        struct term *ident = make_term(A_IDENT, ref(info));
1467
0
        ident->ident = ref(func->param->name);
1468
0
        ident->type = ref(func->param->type);
1469
0
        struct term *app = make_app_term(ref(exp->left), ident, ref(info));
1470
0
        app->type = ref(app->left->type->img);
1471
0
        app = make_app_term(ref(exp->right), app, ref(info));
1472
0
        app->type = ref(app->right->type->img);
1473
1474
0
        build_func(func, app);
1475
1476
0
        if (!type_equal(func->type, exp->type)) {
1477
0
            char *f = type_string(func->type);
1478
0
            char *e = type_string(exp->type);
1479
0
            fatal_error(info,
1480
0
              "Composition has type %s but should have type %s", f, e);
1481
0
            free(f);
1482
0
            free(e);
1483
0
            unref(func, term);
1484
0
            return info->error->exn;
1485
0
        }
1486
0
        v = make_closure(func, ctx->local);
1487
0
        unref(func, term);
1488
0
    } else {
1489
0
        v = compile_exp(exp->info, exp->left, ctx);
1490
0
        unref(v, value);
1491
0
        v = compile_exp(exp->info, exp->right, ctx);
1492
0
    }
1493
0
    return v;
1494
0
}
1495
1496
0
static struct value *compile_concat(struct term *exp, struct ctx *ctx) {
1497
0
    struct value *v1 = compile_exp(exp->info, exp->left, ctx);
1498
0
    if (EXN(v1))
1499
0
        return v1;
1500
0
    struct value *v2 = compile_exp(exp->info, exp->right, ctx);
1501
0
    if (EXN(v2)) {
1502
0
        unref(v1, value);
1503
0
        return v2;
1504
0
    }
1505
1506
0
    struct type *t = exp->type;
1507
0
    struct info *info = exp->info;
1508
0
    struct value *v;
1509
1510
0
    v1 = coerce(v1, t);
1511
0
    v2 = coerce(v2, t);
1512
0
    if (t->tag == T_STRING) {
1513
0
        const char *s1 = v1->string->str;
1514
0
        const char *s2 = v2->string->str;
1515
0
        v = make_value(V_STRING, ref(info));
1516
0
        make_ref(v->string);
1517
0
        if (ALLOC_N(v->string->str, strlen(s1) + strlen(s2) + 1) < 0)
1518
0
            goto error;
1519
0
        char *s = v->string->str;
1520
0
        strcpy(s, s1);
1521
0
        strcat(s, s2);
1522
0
    } else if (t->tag == T_REGEXP) {
1523
0
        v = make_value(V_REGEXP, ref(info));
1524
0
        v->regexp = regexp_concat(info, v1->regexp, v2->regexp);
1525
0
    } else if (t->tag == T_FILTER) {
1526
0
        struct filter *f1 = v1->filter;
1527
0
        struct filter *f2 = v2->filter;
1528
0
        v = make_value(V_FILTER, ref(info));
1529
0
        if (v2->ref == 1 && f2->ref == 1) {
1530
0
            list_append(f2, ref(f1));
1531
0
            v->filter = ref(f2);
1532
0
        } else if (v1->ref == 1 && f1->ref == 1) {
1533
0
            list_append(f1, ref(f2));
1534
0
            v->filter = ref(f1);
1535
0
        } else {
1536
0
            struct filter *cf1, *cf2;
1537
0
            cf1 = make_filter(ref(f1->glob), f1->include);
1538
0
            cf2 = make_filter(ref(f2->glob), f2->include);
1539
0
            cf1->next = ref(f1->next);
1540
0
            cf2->next = ref(f2->next);
1541
0
            list_append(cf1, cf2);
1542
0
            v->filter = cf1;
1543
0
        }
1544
0
    } else if (t->tag == T_LENS) {
1545
0
        struct lens *l1 = v1->lens;
1546
0
        struct lens *l2 = v2->lens;
1547
0
        v = lns_make_concat(ref(info), ref(l1), ref(l2), LNS_TYPE_CHECK(ctx));
1548
0
    } else {
1549
0
        v = NULL;
1550
0
        fatal_error(info, "Tried to concat a %s and a %s to yield a %s",
1551
0
                    type_name(exp->left->type), type_name(exp->right->type),
1552
0
                    type_name(t));
1553
0
    }
1554
0
    unref(v1, value);
1555
0
    unref(v2, value);
1556
0
    return v;
1557
0
 error:
1558
0
    return exp->info->error->exn;
1559
0
}
1560
1561
0
static struct value *apply(struct term *app, struct ctx *ctx) {
1562
0
    struct value *f = compile_exp(app->info, app->left, ctx);
1563
0
    struct value *result = NULL;
1564
0
    struct ctx lctx;
1565
1566
0
    if (EXN(f))
1567
0
        return f;
1568
1569
0
    struct value *arg = compile_exp(app->info, app->right, ctx);
1570
0
    if (EXN(arg)) {
1571
0
        unref(f, value);
1572
0
        return arg;
1573
0
    }
1574
1575
0
    assert(f->tag == V_CLOS);
1576
1577
0
    lctx.aug = ctx->aug;
1578
0
    lctx.local = ref(f->bindings);
1579
0
    lctx.name = ctx->name;
1580
1581
0
    arg = coerce(arg, f->func->param->type);
1582
0
    if (arg == NULL)
1583
0
        goto done;
1584
1585
0
    bind_param(&lctx.local, f->func->param, arg);
1586
0
    result = compile_exp(app->info, f->func->body, &lctx);
1587
0
    unref(result->info, info);
1588
0
    result->info = ref(app->info);
1589
0
    unbind_param(&lctx.local, f->func->param);
1590
1591
0
 done:
1592
0
    unref(lctx.local, binding);
1593
0
    unref(arg, value);
1594
0
    unref(f, value);
1595
0
    return result;
1596
0
}
1597
1598
0
static struct value *compile_bracket(struct term *exp, struct ctx *ctx) {
1599
0
    struct value *arg = compile_exp(exp->info, exp->brexp, ctx);
1600
0
    if (EXN(arg))
1601
0
        return arg;
1602
0
    assert(arg->tag == V_LENS);
1603
1604
0
    struct value *v = lns_make_subtree(ref(exp->info), ref(arg->lens));
1605
0
    unref(arg, value);
1606
1607
0
    return v;
1608
0
}
1609
1610
0
static struct value *compile_rep(struct term *rep, struct ctx *ctx) {
1611
0
    struct value *arg = compile_exp(rep->info, rep->rexp, ctx);
1612
0
    struct value *v = NULL;
1613
1614
0
    if (EXN(arg))
1615
0
        return arg;
1616
1617
0
    arg = coerce(arg, rep->type);
1618
0
    if (rep->type->tag == T_REGEXP) {
1619
0
        int min, max;
1620
0
        if (rep->quant == Q_STAR) {
1621
0
            min = 0; max = -1;
1622
0
        } else if (rep->quant == Q_PLUS) {
1623
0
            min = 1; max = -1;
1624
0
        } else if (rep->quant == Q_MAYBE) {
1625
0
            min = 0; max = 1;
1626
0
        } else {
1627
0
            assert(0);
1628
0
            abort();
1629
0
        }
1630
0
        v = make_value(V_REGEXP, ref(rep->info));
1631
0
        v->regexp = regexp_iter(rep->info, arg->regexp, min, max);
1632
0
    } else if (rep->type->tag == T_LENS) {
1633
0
        int c = LNS_TYPE_CHECK(ctx);
1634
0
        if (rep->quant == Q_STAR) {
1635
0
            v = lns_make_star(ref(rep->info), ref(arg->lens), c);
1636
0
        } else if (rep->quant == Q_PLUS) {
1637
0
            v = lns_make_plus(ref(rep->info), ref(arg->lens), c);
1638
0
        } else if (rep->quant == Q_MAYBE) {
1639
0
            v = lns_make_maybe(ref(rep->info), ref(arg->lens), c);
1640
0
        } else {
1641
0
            assert(0);
1642
0
        }
1643
0
    } else {
1644
0
        fatal_error(rep->info, "Tried to repeat a %s to yield a %s",
1645
0
                    type_name(rep->rexp->type), type_name(rep->type));
1646
0
    }
1647
0
    unref(arg, value);
1648
0
    return v;
1649
0
}
1650
1651
static struct value *compile_exp(struct info *info,
1652
0
                                 struct term *exp, struct ctx *ctx) {
1653
0
    struct value *v = NULL;
1654
1655
0
    switch (exp->tag) {
1656
0
    case A_COMPOSE:
1657
0
        v = compile_compose(exp, ctx);
1658
0
        break;
1659
0
    case A_UNION:
1660
0
        v = compile_union(exp, ctx);
1661
0
        break;
1662
0
    case A_MINUS:
1663
0
        v = compile_minus(exp, ctx);
1664
0
        break;
1665
0
    case A_CONCAT:
1666
0
        v = compile_concat(exp, ctx);
1667
0
        break;
1668
0
    case A_APP:
1669
0
        v = apply(exp, ctx);
1670
0
        break;
1671
0
    case A_VALUE:
1672
0
        if (exp->value->tag == V_NATIVE) {
1673
0
            v = native_call(info, exp->value->native, ctx);
1674
0
        } else {
1675
0
            v = ref(exp->value);
1676
0
        }
1677
0
        break;
1678
0
    case A_IDENT:
1679
0
        v = ref(ctx_lookup(exp->info, ctx, exp->ident));
1680
0
        break;
1681
0
    case A_BRACKET:
1682
0
        v = compile_bracket(exp, ctx);
1683
0
        break;
1684
0
    case A_FUNC:
1685
0
        v = make_closure(exp, ctx->local);
1686
0
        break;
1687
0
    case A_REP:
1688
0
        v = compile_rep(exp, ctx);
1689
0
        break;
1690
0
    default:
1691
0
        assert(0);
1692
0
        break;
1693
0
    }
1694
1695
0
    return v;
1696
0
}
1697
1698
0
static int compile_test(struct term *term, struct ctx *ctx) {
1699
0
    struct value *actual = compile_exp(term->info, term->test, ctx);
1700
0
    struct value *expect = NULL;
1701
0
    int ret = 1;
1702
1703
0
    if (term->tr_tag == TR_EXN) {
1704
0
        if (!EXN(actual)) {
1705
0
            print_info(stdout, term->info);
1706
0
            printf("Test run should have produced exception, but produced\n");
1707
0
            print_value(stdout, actual);
1708
0
            printf("\n");
1709
0
            ret = 0;
1710
0
        }
1711
0
    } else {
1712
0
        if (EXN(actual)) {
1713
0
            print_info(stdout, term->info);
1714
0
            printf("exception thrown in test\n");
1715
0
            print_value(stdout, actual);
1716
0
            printf("\n");
1717
0
            ret = 0;
1718
0
        } else if (term->tr_tag == TR_CHECK) {
1719
0
            expect = compile_exp(term->info, term->result, ctx);
1720
0
            if (EXN(expect))
1721
0
                goto done;
1722
0
            if (! value_equal(actual, expect)) {
1723
0
                printf("Test failure:");
1724
0
                print_info(stdout, term->info);
1725
0
                printf("\n");
1726
0
                printf(" Expected:\n");
1727
0
                print_value(stdout, expect);
1728
0
                printf("\n");
1729
0
                printf(" Actual:\n");
1730
0
                print_value(stdout, actual);
1731
0
                printf("\n");
1732
0
                ret = 0;
1733
0
            }
1734
0
        } else {
1735
0
            printf("Test result: ");
1736
0
            print_info(stdout, term->info);
1737
0
            printf("\n");
1738
0
            if (actual->tag == V_TREE) {
1739
0
                print_tree_braces(stdout, 2, actual->origin->children);
1740
0
            } else {
1741
0
                print_value(stdout, actual);
1742
0
            }
1743
0
            printf("\n");
1744
0
        }
1745
0
    }
1746
0
 done:
1747
0
    reset_error(term->info->error);
1748
0
    unref(actual, value);
1749
0
    unref(expect, value);
1750
0
    return ret;
1751
0
}
1752
1753
0
static int compile_decl(struct term *term, struct ctx *ctx) {
1754
0
    if (term->tag == A_BIND) {
1755
0
        int result;
1756
1757
0
        struct value *v = compile_exp(term->info, term->exp, ctx);
1758
0
        bind(&ctx->local, term->bname, term->type, v);
1759
1760
0
        if (EXN(v) && !v->exn->seen) {
1761
0
            struct error *error = term->info->error;
1762
0
            struct memstream ms;
1763
1764
0
            init_memstream(&ms);
1765
1766
0
            syntax_error(term->info, "Failed to compile %s",
1767
0
                         term->bname);
1768
0
            fprintf(ms.stream, "%s\n", error->details);
1769
0
            print_value(ms.stream, v);
1770
0
            close_memstream(&ms);
1771
1772
0
            v->exn->seen = 1;
1773
0
            free(error->details);
1774
0
            error->details = ms.buf;
1775
0
        }
1776
0
        result = !(EXN(v) || HAS_ERR(ctx->aug));
1777
0
        unref(v, value);
1778
0
        return result;
1779
0
    } else if (term->tag == A_TEST) {
1780
0
        return compile_test(term, ctx);
1781
0
    }
1782
0
    assert(0);
1783
0
    abort();
1784
0
}
1785
1786
0
static struct module *compile(struct term *term, struct augeas *aug) {
1787
0
    struct ctx ctx;
1788
0
    struct transform *autoload = NULL;
1789
0
    assert(term->tag == A_MODULE);
1790
1791
0
    ctx.aug = aug;
1792
0
    ctx.local = NULL;
1793
0
    ctx.name = term->mname;
1794
0
    list_for_each(dcl, term->decls) {
1795
0
        if (!compile_decl(dcl, &ctx))
1796
0
            goto error;
1797
0
    }
1798
1799
0
    if (term->autoload != NULL) {
1800
0
        struct binding *bnd = bnd_lookup(ctx.local, term->autoload);
1801
0
        if (bnd == NULL) {
1802
0
            syntax_error(term->info, "Undefined transform in autoload %s",
1803
0
                         term->autoload);
1804
0
            goto error;
1805
0
        }
1806
0
        if (expect_types(term->info, bnd->type, 1, t_transform) == NULL)
1807
0
            goto error;
1808
0
        autoload = bnd->value->transform;
1809
0
    }
1810
0
    struct module *module = module_create(term->mname);
1811
0
    module->bindings = ctx.local;
1812
0
    module->autoload = ref(autoload);
1813
0
    return module;
1814
0
 error:
1815
0
    unref(ctx.local, binding);
1816
0
    return NULL;
1817
0
}
1818
1819
/*
1820
 * Defining native functions
1821
 */
1822
static struct info *
1823
48.7k
make_native_info(struct error *error, const char *fname, int line) {
1824
48.7k
    struct info *info;
1825
48.7k
    if (make_ref(info) < 0)
1826
0
        goto error;
1827
48.7k
    info->first_line = info->last_line = line;
1828
48.7k
    info->first_column = info->last_column = 0;
1829
48.7k
    info->error = error;
1830
48.7k
    if (make_ref(info->filename) < 0)
1831
0
        goto error;
1832
48.7k
    info->filename->str = strdup(fname);
1833
48.7k
    return info;
1834
0
 error:
1835
0
    unref(info, info);
1836
0
    return NULL;
1837
0
}
1838
1839
int define_native_intl(const char *file, int line,
1840
                       struct error *error,
1841
                       struct module *module, const char *name,
1842
48.7k
                       int argc, func_impl impl, ...) {
1843
48.7k
    assert(argc > 0);  /* We have no unit type */
1844
48.7k
    assert(argc <= 5);
1845
48.7k
    va_list ap;
1846
48.7k
    enum type_tag tag;
1847
48.7k
    struct term *params = NULL, *body = NULL, *func = NULL;
1848
48.7k
    struct type *type;
1849
48.7k
    struct value *v = NULL;
1850
48.7k
    struct info *info = NULL;
1851
48.7k
    struct ctx ctx;
1852
1853
48.7k
    info = make_native_info(error, file, line);
1854
48.7k
    if (info == NULL)
1855
0
        goto error;
1856
1857
48.7k
    va_start(ap, impl);
1858
123k
    for (int i=0; i < argc; i++) {
1859
74.6k
        struct term *pterm;
1860
74.6k
        char ident[10];
1861
74.6k
        tag = va_arg(ap, enum type_tag);
1862
74.6k
        type = make_base_type(tag);
1863
74.6k
        snprintf(ident, 10, "@%d", i);
1864
74.6k
        pterm = make_param(strdup(ident), type, ref(info));
1865
74.6k
        list_append(params, pterm);
1866
74.6k
    }
1867
48.7k
    tag = va_arg(ap, enum type_tag);
1868
48.7k
    va_end(ap);
1869
1870
48.7k
    type = make_base_type(tag);
1871
1872
48.7k
    make_ref(v);
1873
48.7k
    if (v == NULL)
1874
0
        goto error;
1875
48.7k
    v->tag = V_NATIVE;
1876
48.7k
    v->info = info;
1877
48.7k
    info = NULL;
1878
1879
48.7k
    if (ALLOC(v->native) < 0)
1880
0
        goto error;
1881
48.7k
    v->native->argc = argc;
1882
48.7k
    v->native->type = type;
1883
48.7k
    v->native->impl = impl;
1884
1885
48.7k
    make_ref(body);
1886
48.7k
    if (body == NULL)
1887
0
        goto error;
1888
48.7k
    body->info = ref(info);
1889
48.7k
    body->type = ref(type);
1890
48.7k
    body->tag = A_VALUE;
1891
48.7k
    body->value = v;
1892
48.7k
    v = NULL;
1893
1894
48.7k
    func = build_func(params, body);
1895
48.7k
    params = NULL;
1896
48.7k
    body = NULL;
1897
1898
48.7k
    ctx.aug = NULL;
1899
48.7k
    ctx.local = ref(module->bindings);
1900
48.7k
    ctx.name = module->name;
1901
48.7k
    if (! check_exp(func, &ctx)) {
1902
0
        fatal_error(info, "Typechecking native %s failed",
1903
0
                    name);
1904
0
        abort();
1905
0
    }
1906
48.7k
    v = make_closure(func, ctx.local);
1907
48.7k
    if (v == NULL) {
1908
0
        unref(module->bindings, binding);
1909
0
        goto error;
1910
0
    }
1911
48.7k
    bind(&ctx.local, name, func->type, v);
1912
48.7k
    unref(v, value);
1913
48.7k
    unref(func, term);
1914
48.7k
    unref(module->bindings, binding);
1915
1916
48.7k
    module->bindings = ctx.local;
1917
48.7k
    return 0;
1918
0
 error:
1919
0
    list_for_each(p, params) {
1920
0
        unref(p, term);
1921
0
    }
1922
0
    unref(v, value);
1923
0
    unref(body, term);
1924
0
    unref(func, term);
1925
0
    return -1;
1926
0
}
1927
1928
1929
/* Defined in parser.y */
1930
int augl_parse_file(struct augeas *aug, const char *name, struct term **term);
1931
1932
0
static char *module_basename(const char *modname) {
1933
0
    char *fname;
1934
1935
0
    if (asprintf(&fname, "%s" AUG_EXT, modname) == -1)
1936
0
        return NULL;
1937
0
    for (int i=0; i < strlen(modname); i++)
1938
0
        fname[i] = tolower(fname[i]);
1939
0
    return fname;
1940
0
}
1941
1942
0
static char *module_filename(struct augeas *aug, const char *modname) {
1943
0
    char *dir = NULL;
1944
0
    char *filename = NULL;
1945
0
    char *name = module_basename(modname);
1946
1947
    /* Module names that contain slashes can fool us into finding and
1948
     * loading a module in another directory, but once loaded we won't find
1949
     * it under MODNAME so that we will later try and load it over and
1950
     * over */
1951
0
    if (index(modname, '/') != NULL)
1952
0
        goto error;
1953
1954
0
    while ((dir = argz_next(aug->modpathz, aug->nmodpath, dir)) != NULL) {
1955
0
        int len = strlen(name) + strlen(dir) + 2;
1956
0
        struct stat st;
1957
1958
0
        if (REALLOC_N(filename, len) == -1)
1959
0
            goto error;
1960
0
        sprintf(filename, "%s/%s", dir, name);
1961
0
        if (stat(filename, &st) == 0)
1962
0
            goto done;
1963
0
    }
1964
0
 error:
1965
0
    FREE(filename);
1966
0
 done:
1967
0
    free(name);
1968
0
    return filename;
1969
0
}
1970
1971
int load_module_file(struct augeas *aug, const char *filename,
1972
0
                     const char *name) {
1973
0
    struct term *term = NULL;
1974
0
    int result = -1;
1975
1976
0
    if (aug->flags & AUG_TRACE_MODULE_LOADING)
1977
0
        printf("Module %s", filename);
1978
0
    augl_parse_file(aug, filename, &term);
1979
0
    if (aug->flags & AUG_TRACE_MODULE_LOADING)
1980
0
        printf(HAS_ERR(aug) ? " failed\n" : " loaded\n");
1981
0
    ERR_BAIL(aug);
1982
1983
0
    if (! typecheck(term, aug))
1984
0
        goto error;
1985
1986
0
    struct module *module = compile(term, aug);
1987
0
    bool bad_module = (module == NULL);
1988
0
    if (bad_module && name != NULL) {
1989
        /* Put an empty placeholder on the module list so that
1990
         * we don't retry loading this module everytime its mentioned
1991
         */
1992
0
        module = module_create(name);
1993
0
    }
1994
0
    if (module != NULL) {
1995
0
        list_append(aug->modules, module);
1996
0
        list_for_each(bnd, module->bindings) {
1997
0
            if (bnd->value->tag == V_LENS) {
1998
0
                lens_release(bnd->value->lens);
1999
0
            }
2000
0
        }
2001
0
    }
2002
0
    ERR_THROW(bad_module, aug, AUG_ESYNTAX, "Failed to load %s", filename);
2003
2004
0
    result = 0;
2005
0
 error:
2006
    // FIXME: This leads to a bad free of a string used in a del lens
2007
    // To reproduce run lenses/tests/test_yum.aug
2008
0
    unref(term, term);
2009
0
    return result;
2010
0
}
2011
2012
0
static int load_module(struct augeas *aug, const char *name) {
2013
0
    char *filename = NULL;
2014
2015
0
    if (module_find(aug->modules, name) != NULL)
2016
0
        return 0;
2017
2018
0
    if ((filename = module_filename(aug, name)) == NULL)
2019
0
        return -1;
2020
2021
0
    if (load_module_file(aug, filename, name) == -1)
2022
0
        goto error;
2023
2024
0
    free(filename);
2025
0
    return 0;
2026
2027
0
 error:
2028
0
    free(filename);
2029
0
    return -1;
2030
0
}
2031
2032
1.52k
int interpreter_init(struct augeas *aug) {
2033
1.52k
    int r;
2034
2035
1.52k
    r = init_fatal_exn(aug->error);
2036
1.52k
    if (r < 0)
2037
0
        return -1;
2038
2039
1.52k
    aug->modules = builtin_init(aug->error);
2040
1.52k
    if (aug->flags & AUG_NO_MODL_AUTOLOAD)
2041
0
        return 0;
2042
2043
    // For now, we just load every file on the search path
2044
1.52k
    const char *dir = NULL;
2045
1.52k
    glob_t globbuf;
2046
1.52k
    int gl_flags = GLOB_NOSORT;
2047
2048
1.52k
    MEMZERO(&globbuf, 1);
2049
2050
4.57k
    while ((dir = argz_next(aug->modpathz, aug->nmodpath, dir)) != NULL) {
2051
3.04k
        char *globpat;
2052
3.04k
        r = asprintf(&globpat, "%s/*.aug", dir);
2053
3.04k
        ERR_NOMEM(r < 0, aug);
2054
2055
3.04k
        r = glob(globpat, gl_flags, NULL, &globbuf);
2056
3.04k
        if (r != 0 && r != GLOB_NOMATCH) {
2057
            /* This really has to be an allocation failure; glob is not
2058
             * supposed to return GLOB_ABORTED here */
2059
0
            aug_errcode_t code =
2060
0
                r == GLOB_NOSPACE ? AUG_ENOMEM : AUG_EINTERNAL;
2061
0
            ERR_REPORT(aug, code, "glob failure for %s", globpat);
2062
0
            free(globpat);
2063
0
            goto error;
2064
0
        }
2065
3.04k
        gl_flags |= GLOB_APPEND;
2066
3.04k
        free(globpat);
2067
3.04k
    }
2068
2069
1.52k
    for (int i=0; i < globbuf.gl_pathc; i++) {
2070
0
        char *name, *p, *q;
2071
0
        int res;
2072
0
        p = strrchr(globbuf.gl_pathv[i], SEP);
2073
0
        if (p == NULL)
2074
0
            p = globbuf.gl_pathv[i];
2075
0
        else
2076
0
            p += 1;
2077
0
        q = strchr(p, '.');
2078
0
        name = strndup(p, q - p);
2079
0
        name[0] = toupper(name[0]);
2080
0
        res = load_module(aug, name);
2081
0
        free(name);
2082
0
        if (res == -1)
2083
0
            goto error;
2084
0
    }
2085
1.52k
    globfree(&globbuf);
2086
1.52k
    return 0;
2087
0
 error:
2088
0
    globfree(&globbuf);
2089
0
    return -1;
2090
1.52k
}
2091
2092
/*
2093
 * Local variables:
2094
 *  indent-tabs-mode: nil
2095
 *  c-indent-level: 4
2096
 *  c-basic-offset: 4
2097
 *  tab-width: 4
2098
 * End:
2099
 */