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