summaryrefslogtreecommitdiff
path: root/muse/muse.c
blob: 77fdb991da8be23f0412d7e7534997099d574c02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "parse.h"

#include "../config.h"

/* FIXME: move into one place...? */
Node *file;
char *outfile;
int merge;
int debug;
char debugopt[128];
char **incpaths;
size_t nincpaths;

static void usage(char *prog)
{
    printf("%s [-hIdos] [-o outfile] [-m] inputs\n", prog);
    printf("\t-h\tprint this help\n");
    printf("\t-m\ttreat the inputs as usefiles and merge them into outfile\n");
    printf("\t\tThe outfile must be the same name as each package merged.\n");
    printf("\t-I path\tAdd 'path' to use search path\n");
    printf("\t-d\tPrint debug dumps\n");
    printf("\t-o out\tOutput to outfile\n");
    printf("\t-s\tShow the contents of usefiles `inputs`\n");
}

static void dumpuse(char *path)
{
    Stab *globls;
    FILE *f;

    globls = file->file.globls;
    f = fopen(path, "r");
    loaduse(f, globls);
    fclose(f);
    dumpstab(globls, stdout);
}

static void genuse(char *path)
{
    Stab *globls;
    char *p;
    FILE *f;
    char buf[1024];

    globls = file->file.globls;
    tyinit(globls);
    tokinit(path);
    yyparse();

    infer(file);
    if (outfile) {
        p = outfile;
    } else {
        swapsuffix(buf, sizeof buf, path, ".myr", ".use");
        p = buf;
    }
    f = fopen(p, "w");
    writeuse(f, file);
    fclose(f);
}

static void mergeuse(char *path)
{
    FILE *f;
    Stab *st;

    st = file->file.exports;
    f = fopen(path, "r");
    if (!f)
        die("Couldn't open %s\n", path);
    loaduse(f, st);
    fclose(f);
}

int main(int argc, char **argv)
{
    FILE *f;
    int opt;
    int i;

    while ((opt = getopt(argc, argv, "d::hmo:I:")) != -1) {
        switch (opt) {
            case 'h':
                usage(argv[0]);
                exit(0);
                break;
            case 'm':
                merge = 1;
                break;
            case 'o':
                outfile = optarg;
                break;
            case 'd':
                debug = 1;
                while (optarg && *optarg)
                    debugopt[*optarg++ & 0x7f] = 1;
                break;
            case 'I':
                lappend(&incpaths, &nincpaths, optarg);
                break;
            default:
                usage(argv[0]);
                exit(0);
                break;
        }
    }

    lappend(&incpaths, &nincpaths, Instroot "/lib/myr");
    if (merge) {
        if (!outfile) {
            fprintf(stderr, "Output file needed when merging usefiles.");
            exit(1);
        }

        file = mkfile("internal");
        file->file.exports = mkstab();
        file->file.globls = mkstab();
        updatens(file->file.exports, outfile);
        for (i = optind; i < argc; i++)
            mergeuse(argv[i]);
        f = fopen(outfile, "w");
        writeuse(f, file);
        fclose(f);
    } else {
        for (i = optind; i < argc; i++) {
            file = mkfile(argv[i]);
            file->file.exports = mkstab();
            file->file.globls = mkstab();
            if (debugopt['s'])
                dumpuse(argv[i]);
            else
                genuse(argv[i]);
        }
    }

    return 0;
}