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