casl2、comet2コマンドのエラーや使い方表示を変更
[YACASL2.git] / src / casl2.c
1 #include "casl2.h"
2 #include "assemble.h"
3 #include "exec.h"
4 #define _GNU_SOURCE
5 #include <getopt.h>
6
7 /* casl2コマンドのオプション */
8 static struct option longopts[] = {
9     {"source", no_argument, NULL, 's'},
10     {"label", no_argument, NULL, 'l'},
11     {"labelonly", no_argument, NULL, 'L'},
12     {"assembledetail", no_argument, NULL, 'a'},
13     {"assembledetailonly", no_argument, NULL, 'A'},
14     {"assembleout", optional_argument, NULL, 'o'},
15     {"assembleoutonly", optional_argument, NULL, 'O'},
16     {"trace", no_argument, NULL, 't'},
17     {"tracearithmetic", no_argument, NULL, 't'},
18     {"tracelogical", no_argument, NULL, 'T'},
19     {"dump", no_argument, NULL, 'd'},
20     {"memorysize", required_argument, NULL, 'M'},
21     {"clocks", required_argument, NULL, 'C'},
22     {"help", no_argument, NULL, 'h'},
23     {0, 0, 0, 0},
24 };
25
26 /* casl2のエラー定義 */
27 CERRARRAY cerr_casl2[] = {
28     { 126, "source file is not specified" },
29 };
30 bool addcerrlist_casl2()
31 {
32     return addcerrlist_casl2(ARRAYSIZE(cerr_casl2), cerr_casl2);
33 }
34
35 /* 指定されたファイルにアセンブル結果を書込 */
36 void outassemble(const char *file) {
37     FILE *fp;
38     if((fp = fopen(file, "w")) == NULL) {
39         perror(file);
40         exit(-1);
41     }
42     fwrite(memory, sizeof(WORD), endptr, fp);
43     fclose(fp);
44 }
45
46 /* アセンブル結果を書き込むファイルの名前 */
47 const char *objfile_name(const char *str)
48 {
49     const char *default_name = "a.o";
50
51     if(str == NULL) {
52         return default_name;
53     } else {
54         return str;
55     }
56 }
57
58 /* casl2コマンドのメイン */
59 int main(int argc, char *argv[])
60 {
61     int opt, i;
62     PASS pass;
63     bool status = false;
64     WORD beginptr[argc];
65     char *objfile = NULL;
66     const char *usage =
67         "Usage: %s [-slLaAtTdh] [-oO<OBJECTFILE>] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE ...\n";
68
69     while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:h", longopts, NULL)) != -1) {
70         switch(opt) {
71         case 's':
72             asmode.src = true;
73             break;
74         case 'l':
75             asmode.label = true;
76             break;
77         case 'L':
78             asmode.label = true;
79             asmode.onlylabel = true;
80             break;
81         case 'a':
82             asmode.asdetail = true;
83             break;
84         case 'A':
85             asmode.asdetail = true;
86             asmode.onlyassemble = true;
87             break;
88         case 'o':
89             objfile = strdup(objfile_name(optarg));
90             break;
91         case 'O':
92             asmode.onlyassemble = true;
93             objfile = strdup(objfile_name(optarg));
94             break;
95         case 't':
96             execmode.trace = true;
97             break;
98         case 'T':
99             execmode.trace = true;
100             execmode.logical = true;
101             break;
102         case 'd':
103             execmode.dump = true;
104             break;
105         case 'M':
106             memsize = atoi(optarg);
107             break;
108         case 'C':
109             clocks = atoi(optarg);
110             break;
111         case 'h':
112             fprintf(stdout, usage, argv[0]);
113             return 0;
114         case '?':
115             fprintf(stderr, usage, argv[0]);
116             exit(-1);
117         }
118     }
119
120     #if 0
121     addcerrlist_casl2();
122     #endif
123     /* ソースファイルが指定されていない場合は終了 */
124     if(argv[optind] == NULL) {
125         setcerr(126, NULL);    /* source file is not specified */
126         goto casl2err;
127     }
128     /* COMET II仮想マシンのリセット */
129     reset();
130     /* アセンブル。ラベル表作成のため、2回行う */
131     for(pass = FIRST; pass <= SECOND; pass++) {
132         if(pass == FIRST && create_cmdtype_code() == false) {
133             goto casl2err;
134         }
135         for(i = optind; i < argc; i++) {
136             /* データの格納開始位置 */
137             if(pass == FIRST) {
138                 beginptr[i] = ptr;
139             } else if(pass == SECOND) {
140                 ptr = beginptr[i];
141             }
142             if(execmode.trace == true || execmode.dump == true || asmode.src == true ||
143                asmode.label == true || asmode.asdetail == true)
144             {
145                 fprintf(stdout, "\nAssemble %s (%d)\n", argv[i], pass);
146             }
147             if((status = assemble(argv[i], pass)) == false) {
148                 exit(-1);
149             }
150         }
151         if(pass == FIRST && asmode.label == true) {
152             fprintf(stdout, "\nLabel::::\n");
153             printlabel();
154             if(asmode.onlylabel == true) {
155                 return 0;
156             }
157         }
158     }
159     free_cmdtype_code();    /* 命令表の解放 */
160     freelabel();            /* ラベル表の解放 */
161     if(status == true) {
162         if(objfile != NULL) {
163             outassemble(objfile);
164         }
165         if(asmode.onlyassemble == false) {
166             exec();    /* プログラム実行 */
167         }
168     }
169     if(cerrno > 0) {
170         freecerr();
171         exit(-1);
172     }
173     return 0;
174 casl2err:
175     fprintf(stderr, "CASL2 error - %d: %s\n", cerrno, cerrmsg);
176     exit(-1);
177 }