From: j8takagi Date: Thu, 21 Feb 2019 15:30:40 +0000 (+0900) Subject: メモリリークの修正 X-Git-Tag: v0.5p9~9 X-Git-Url: https://j8takagi.net/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d650cc4148ccd23f940ac60050c36c89897c168f;p=YACASL2.git メモリリークの修正 --- diff --git a/VERSION b/VERSION index 498e4a9..5d69fd2 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -v0.5p7 +v0.5p8 diff --git a/include/assemble.h b/include/assemble.h index f8faf81..154f8e1 100644 --- a/include/assemble.h +++ b/include/assemble.h @@ -142,13 +142,13 @@ bool assemblefile(const char *file, PASS pass); /** * @brief 指定された1つまたは複数のファイルを2回アセンブル * - * @return なし + * @return アセンブル完了時はtrue、エラー発生時はfalseを返す * * @param filec アセンブルするファイルの数 * @param filev アセンブルするファイル名の配列 * @param adr アセンブル結果を格納するアドレス */ -void assemble(int filec, char *filev[], WORD adr); +bool assemble(int filec, char *filev[], WORD adr); /** * @brief ファイルにアセンブル結果を書き込む diff --git a/include/cmem.h b/include/cmem.h index 134baa8..e8b0aba 100644 --- a/include/cmem.h +++ b/include/cmem.h @@ -75,4 +75,14 @@ char *strndup_chk(const char *s, size_t len, const char *tag); * @param s 文字列 */ char *strip_end(char *s); + +/** + * @brief 文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く + * + * @return コメントを削除した文字列 + * + * @param s 文字列 + */ +char *strip_casl2_comment(char *s); + #endif diff --git a/include/token.h b/include/token.h index 32b1fd7..0c90936 100644 --- a/include/token.h +++ b/include/token.h @@ -51,15 +51,6 @@ typedef struct { */ void addcerrlist_tok(); -/** - * @brief 文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く - * - * @return コメントを削除した文字列 - * - * @param s 文字列 - */ -char *strip_casl2_comment(char *s); - /** * @brief 行から、ラベル・コマンド・オペランドを取得する * diff --git a/src/assemble.c b/src/assemble.c index 10ecb41..5e18000 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -747,11 +747,12 @@ bool assemblefile(const char *file, PASS pass) 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"); @@ -771,7 +772,8 @@ void assemble(int filec, char *filev[], WORD adr) 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; } } @@ -787,6 +789,7 @@ asfin: freelabel(); /* ラベルハッシュ表を解放 */ FREE(asptr->prog); /* アセンブル時のプロパティを解放 */ FREE(asptr); + return stat; } /* assemble.hで定義された関数群 */ diff --git a/src/casl2.c b/src/casl2.c index 68cbb24..da5a45b 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -45,6 +45,7 @@ static struct option longopts[] = { */ CERR cerr_casl2[] = { { 126, "no source file" }, + { 127, "invalid option" }, }; void addcerrlist_casl2() @@ -74,6 +75,12 @@ int main(int argc, char *argv[]) const char *usage = "Usage: %s [-slLaAtTdmvh] [-oO[]] [-M ] [-C ] 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) { @@ -122,51 +129,48 @@ int main(int argc, char *argv[]) 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; } diff --git a/src/cmem.c b/src/cmem.c index e921bb0..722c707 100644 --- a/src/cmem.c +++ b/src/cmem.c @@ -56,3 +56,21 @@ char *strip_end(char *s) } 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; +} diff --git a/src/comet2monitor.c b/src/comet2monitor.c index 3f9ed7a..4154e9c 100644 --- a/src/comet2monitor.c +++ b/src/comet2monitor.c @@ -60,6 +60,7 @@ int main(int argc, char *argv[]) shutdown(); free_cmdtable(HASH_CMDTYPE); + free_cmdtable(HASH_CODE); stat = (cerr->num == 0) ? 0 : 1; freecerr(); /* エラーの解放 */ return stat; diff --git a/src/monitor.c b/src/monitor.c index ec24645..30893b6 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -145,24 +145,29 @@ MONARGS *monargstok(const char *str) 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"); @@ -391,7 +396,7 @@ void monitor() if(cmdtype == MONQUIT) { shutdown(); freebps(); - free_cmdtable(HASH_CODE); + free_cmdtable(HASH_CMDTYPE); freecerr(); exit(0); } diff --git a/src/token.c b/src/token.c index 22f33ba..8c49763 100644 --- a/src/token.c +++ b/src/token.c @@ -94,24 +94,6 @@ void addcerrlist_tok() 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; diff --git a/src/word.c b/src/word.c index df953c5..bae1e82 100644 --- a/src/word.c +++ b/src/word.c @@ -137,14 +137,14 @@ char *word2bit(const WORD word) 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); @@ -153,4 +153,5 @@ void print_dumpword(WORD word, bool logicalmode) } else if(word == '\t') { fprintf(stdout, " = \'\\t\'"); } + FREE(bit); }