/**
* @brief 指定された1つまたは複数のファイルを2回アセンブル
*
- * @return ã\81ªã\81\97
+ * @return ã\82¢ã\82»ã\83³ã\83\96ã\83«å®\8cäº\86æ\99\82ã\81¯trueã\80\81ã\82¨ã\83©ã\83¼ç\99ºç\94\9fæ\99\82ã\81¯falseã\82\92è¿\94ã\81\99
*
* @param filec アセンブルするファイルの数
* @param filev アセンブルするファイル名の配列
* @param adr アセンブル結果を格納するアドレス
*/
-void assemble(int filec, char *filev[], WORD adr);
+bool assemble(int filec, char *filev[], WORD adr);
/**
* @brief ファイルにアセンブル結果を書き込む
* @param s 文字列
*/
char *strip_end(char *s);
+
+/**
+ * @brief 文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く
+ *
+ * @return コメントを削除した文字列
+ *
+ * @param s 文字列
+ */
+char *strip_casl2_comment(char *s);
+
#endif
*/
void addcerrlist_tok();
-/**
- * @brief 文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く
- *
- * @return コメントを削除した文字列
- *
- * @param s 文字列
- */
-char *strip_casl2_comment(char *s);
-
/**
* @brief 行から、ラベル・コマンド・オペランドを取得する
*
return (cerr->num == 0) ? true : false;
}
-void assemble(int filec, char *filev[], WORD adr)
+bool assemble(int filec, char *filev[], WORD adr)
{
int i;
PASS pass;
WORD bp[filec];
+ bool stat = false;
asptr = malloc_chk(sizeof(ASPTR), "asptr"); /* アセンブル時のプロパティ用の領域確保 */
asptr->prog = malloc_chk(LABELSIZE + 1, "asptr.prog");
fprintf(stdout, "\nAssemble %s (%d)\n", filev[i], pass);
}
/* ファイルをアセンブル */
- if(assemblefile(filev[i], pass) == false) {
+ stat = assemblefile(filev[i], pass);
+ if(stat == false) {
goto asfin;
}
}
freelabel(); /* ラベルハッシュ表を解放 */
FREE(asptr->prog); /* アセンブル時のプロパティを解放 */
FREE(asptr);
+ return stat;
}
/* assemble.hで定義された関数群 */
*/
CERR cerr_casl2[] = {
{ 126, "no source file" },
+ { 127, "invalid option" },
};
void addcerrlist_casl2()
const char *usage =
"Usage: %s [-slLaAtTdmvh] [-oO[<OBJECTFILE>]] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE1[ FILE2 ...]\n";
+ /* エラーの定義 */
+ cerr_init();
+ addcerrlist_casl2();
+ addcerrlist_assemble();
+ addcerrlist_exec();
+
/* オプションの処理 */
while((opt = getopt_long(argc, argv, "tTdslLmao::O::AM:C:vh", longopts, NULL)) != -1) {
switch(opt) {
break;
case 'v':
fprintf(stdout, cmdversion, version);
- return 0;
+ goto casl2fin;
case 'h':
fprintf(stdout, usage, argv[0]);
- return 0;
+ goto casl2fin;
case '?':
fprintf(stderr, usage, argv[0]);
- exit(1);
+ setcerr(127, ""); /* invalid option */
+ goto casl2fin;
}
}
- /* エラーの定義 */
- cerr_init();
- addcerrlist_casl2();
- addcerrlist_assemble();
- addcerrlist_exec();
-
/* ソースファイルが指定されていない場合は終了 */
if(argv[optind] == NULL) {
setcerr(126, ""); /* no source file */
fprintf(stderr, "CASL2 error - %d: %s\n", cerr->num, cerr->msg);
- freecerr(); /* エラーの解放 */
- exit(1);
+ goto casl2fin;
}
create_cmdtable(HASH_CMDTYPE); /* 命令の名前とタイプがキーのハッシュ表を作成 */
reset(memsize, clocks); /* 仮想マシンCOMET IIのリセット */
for(i = 0; i < argc - optind; i++) { /* 引数からファイル名配列を取得 */
af[i] = argv[optind + i];
}
- assemble(i, af, 0); /* アセンブル */
- if(asmode.onlylabel == true || cerr->num > 0) {
- goto casl2fin;
+ /* アセンブル */
+ if(assemble(i, af, 0) == false || asmode.onlylabel == true) {
+ goto freecmdtable;
}
/* オブジェクトファイル名が指定されている場合は、アセンブル結果をオブジェクトファイルに出力 */
if(objfile != NULL) {
outassemble(objfile);
- FREE(objfile);
}
/* onlyassembleモード以外の場合、仮想マシンCOMET IIを実行 */
if(asmode.onlyassemble == false) {
exec(); /* 仮想マシンCOMET IIの実行 */
}
-casl2fin:
+freecmdtable:
shutdown(); /* 仮想マシンCOMET IIのシャットダウン */
free_cmdtable(HASH_CMDTYPE);
- stat = (cerr->num == 0) ? 0 : 1;
+casl2fin:
+ FREE(objfile);
+ if(cerr->num > 0) {
+ stat = 1;
+ }
freecerr(); /* エラーの解放 */
return stat;
}
}
return s;
}
+
+char *strip_casl2_comment(char *s)
+{
+ int i;
+ bool quoting = false;
+
+ for(i = 0; s[i]; i++) {
+ /* 「'」で囲まれた文字列の場合。「''」は無視 */
+ if(s[i] == '\'' && s[i+1] != '\'' && (quoting == false || s[i-1] != '\'')) {
+ quoting = !quoting;
+ /* 「'」で囲まれた文字列でない場合、文字列末尾の「;」以降を削除 */
+ } else if(quoting == false && s[i] == ';') {
+ s[i] = '\0';
+ break;
+ }
+ }
+ return s;
+}
shutdown();
free_cmdtable(HASH_CMDTYPE);
+ free_cmdtable(HASH_CODE);
stat = (cerr->num == 0) ? 0 : 1;
freecerr(); /* エラーの解放 */
return stat;
MONCMDLINE *monlinetok(const char *line)
{
char *tokens, *p;
- long l;
+ int i;
MONCMDLINE *moncmdl = NULL;
if(!line[0] || line[0] == '\n') {
return NULL;
}
p = tokens = strdup_chk(line, "tokens");
+ /* コメントを削除 */
+ strip_casl2_comment(p);
+ /* 文字列末尾の改行と空白を削除 */
+ strip_end(p);
+
moncmdl = malloc_chk(sizeof(MONCMDLINE), "moncmdl");
/* コマンドの取得 */
- moncmdl->cmd = malloc_chk((l = strcspn(p, " \t\n")) + 1, "moncmdl.cmd");
- strncpy(moncmdl->cmd, p, l);
+ i = strcspn(p, " \t\n");
+ moncmdl->cmd = strndup_chk(p, i, "moncmdl->cmd");
/* コマンドと引数の間の空白をスキップ */
- p += l;
+ p += i;
while(*p == ' ' || *p == '\t') {
p++;
}
/* 引数として、改行までの文字列を取得 */
- if((l = strcspn(p, "\n")) > 0) {
+ if(strcspn(p, "\n") > 0) {
moncmdl->args = monargstok(p);
} else {
moncmdl->args = malloc_chk(sizeof(MONARGS), "moncmdl.args");
if(cmdtype == MONQUIT) {
shutdown();
freebps();
- free_cmdtable(HASH_CODE);
+ free_cmdtable(HASH_CMDTYPE);
freecerr();
exit(0);
}
addcerrlist(ARRAYSIZE(cerr_opdtok), cerr_opdtok);
}
-char *strip_casl2_comment(char *s)
-{
- int i;
- bool quoting = false;
-
- for(i = 0; s[i]; i++) {
- /* 「'」で囲まれた文字列の場合。「''」は無視 */
- if(s[i] == '\'' && s[i+1] != '\'' && (quoting == false || s[i-1] != '\'')) {
- quoting = !quoting;
- /* 「'」で囲まれた文字列でない場合、文字列末尾の「;」以降を削除 */
- } else if(quoting == false && s[i] == ';') {
- s[i] = '\0';
- break;
- }
- }
- return s;
-}
-
CMDLINE *linetok(const char *line)
{
char *tok = NULL, *p = NULL;
void print_dumpword(WORD word, bool logicalmode)
{
- const char *bit = word2bit(word);
+ char *bit = NULL;
if(logicalmode == true) {
fprintf(stdout, "%6d", word);
} else {
fprintf(stdout, "%6d", (signed short)word);
}
- fprintf(stdout, " = #%04X = %s", word, bit);
+ fprintf(stdout, " = #%04X = %s", word, (bit = word2bit(word)));
/* 「文字の組」の符号表に記載された文字と、改行(CR)/タブを表示 */
if(word >= 0x20 && word <= 0x7E) {
fprintf(stdout, " = \'%c\'", word);
} else if(word == '\t') {
fprintf(stdout, " = \'\\t\'");
}
+ FREE(bit);
}