ソースの推敲
[YACASL2.git] / src / casl2.c
1 #include "package.h"
2 #include "assemble.h"
3
4 /**
5  * @brief CASL IIのエラーをエラーリストに追加
6  *
7  * @return なし
8  */
9 void addcerrlist_casl2();
10
11 /**
12  * @brief アセンブル結果を書き込むファイルの名前
13  *
14  * @return ファイル名
15  *
16  * @param *str ファイル名
17  */
18 char *objfile_name(const char *str);
19
20 /**
21  * @brief casl2コマンドのオプション
22  */
23 static struct option longopts[] = {
24     { "source", no_argument, NULL, 's' },
25     { "label", no_argument, NULL, 'l' },
26     { "labelonly", no_argument, NULL, 'L' },
27     { "assembledetail", no_argument, NULL, 'a' },
28     { "assembledetailonly", no_argument, NULL, 'A' },
29     { "assembleout", optional_argument, NULL, 'o' },
30     { "assembleoutonly", optional_argument, NULL, 'O' },
31     { "trace", no_argument, NULL, 't' },
32     { "tracearithmetic", no_argument, NULL, 't' },
33     { "tracelogical", no_argument, NULL, 'T' },
34     { "dump", no_argument, NULL, 'd' },
35     { "monitor", no_argument, NULL, 'm' },
36     { "memorysize", required_argument, NULL, 'M' },
37     { "clocks", required_argument, NULL, 'C' },
38     { "version", no_argument, NULL, 'v' },
39     { "help", no_argument, NULL, 'h' },
40     { 0, 0, 0, 0 },
41 };
42
43 /**
44  * @brief casl2のエラー定義
45  */
46 CERR cerr_casl2[] = {
47     { 126, "no source file" },
48     { 127, "invalid option" },
49 };
50
51 void addcerrlist_casl2()
52 {
53     addcerrlist(ARRAYSIZE(cerr_casl2), cerr_casl2);
54 }
55
56 char *objfile_name(const char *name)
57 {
58     const char *default_name = "a.o";
59     return strdup_chk(
60         (name == NULL || !name[0]) ? default_name : name,
61         "objfile_name"
62         );
63 }
64
65 /**
66  * @brief casl2コマンドのメイン
67  *
68  * @return 正常終了時は0、エラー発生時は1
69  *
70  * @param argc コマンドライン引数の数
71  * @param *argv[] コマンドライン引数の配列
72  */
73 int main(int argc, char *argv[])
74 {
75     int memsize = DEFAULT_MEMSIZE;
76     int clocks = DEFAULT_CLOCKS;
77     int opt = 0;
78     int stat = 0;
79     int asfilecnt = 0;
80     char **asfile = NULL;
81     char *objfile = NULL;
82     const char *version = PACKAGE_VERSION;
83     const char *cmdversion = "casl2 of YACASL2 version %s\n";
84     const char *usage =
85         "Usage: %s [-slLaAtTdmvh] [-oO[<OBJECTFILE>]] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE1[ FILE2  ...]\n";
86
87     /* エラーの定義 */
88     cerr_init();
89     addcerrlist_casl2();
90     addcerrlist_assemble();
91     addcerrlist_exec();
92
93     /* オプションの処理 */
94     while((opt = getopt_long(argc, argv, "tTdslLmao::O::AM:C:vh", longopts, NULL)) != -1) {
95         switch(opt) {
96         case 's':
97             asmode.src = true;
98             break;
99         case 'l':
100             asmode.label = true;
101             break;
102         case 'L':
103             asmode.label = true;
104             asmode.onlylabel = true;
105             break;
106         case 'a':
107             asmode.asdetail = true;
108             break;
109         case 'A':
110             asmode.asdetail = true;
111             asmode.onlyassemble = true;
112             break;
113         case 'o':
114             objfile = objfile_name(optarg);
115             break;
116         case 'O':
117             asmode.onlyassemble = true;
118             objfile = objfile_name(optarg);
119             break;
120         case 't':
121             execmode.trace = true;
122             break;
123         case 'T':
124             execmode.trace = true;
125             execmode.logical = true;
126             break;
127         case 'd':
128             execmode.dump = true;
129             break;
130         case 'm':
131             execmode.step = true;
132             break;
133         case 'M':
134             memsize = atoi(optarg);
135             break;
136         case 'C':
137             clocks = atoi(optarg);
138             break;
139         case 'v':
140             fprintf(stdout, cmdversion, version);
141             goto casl2fin;
142         case 'h':
143             fprintf(stdout, usage, argv[0]);
144             goto casl2fin;
145         case '?':
146             fprintf(stderr, usage, argv[0]);
147             setcerr(212, "");    /* invalid option */
148             goto casl2fin;
149         }
150     }
151
152     /* ソースファイルが指定されていない場合は終了 */
153     if(argv[optind] == NULL) {
154         setcerr(126, "");    /* no source file */
155         fprintf(stderr, "casl2 error - %d: %s\n", cerr->num, cerr->msg);
156         goto casl2fin;
157     }
158     create_cmdtable(HASH_CMDTYPE);                 /* 命令の名前とタイプがキーのハッシュ表を作成 */
159     reset(memsize, clocks);                        /* 仮想マシンCOMET IIのリセット */
160     asfilecnt = argc - optind;
161     asfile = calloc_chk(asfilecnt, sizeof(char *), "asfile");
162     for(int i = 0; i < asfilecnt; i++) {           /* 引数からファイル名配列を取得 */
163         asfile[i] = argv[optind + i];
164     }
165     /* アセンブル */
166     if(assemble(asfilecnt, asfile, 0) == false || asmode.onlylabel == true) {
167         goto shutdown;
168     }
169     /* オブジェクトファイル名が指定されている場合は、アセンブル結果をオブジェクトファイルに出力 */
170     if(objfile != NULL) {
171         outassemble(objfile);
172     }
173     /* onlyassembleモード以外の場合、仮想マシンCOMET IIを実行 */
174     if(asmode.onlyassemble == false) {
175         exec();                                    /* 仮想マシンCOMET IIの実行 */
176     }
177 shutdown:
178     shutdown();                                   /* 仮想マシンCOMET IIのシャットダウン */
179 casl2fin:
180     FREE(objfile);
181     FREE(asfile);
182     free_cmdtable(HASH_CMDTYPE);
183     if(cerr->num > 0) {
184         stat = 1;
185     }
186     freecerr();                                    /* エラーの解放 */
187     return stat;
188 }