メモリリークの修正
authorj8takagi <j8takagi@nifty.com>
Thu, 21 Feb 2019 15:30:40 +0000 (00:30 +0900)
committerj8takagi <j8takagi@nifty.com>
Thu, 21 Feb 2019 15:31:10 +0000 (00:31 +0900)
include/assemble.h
include/cmem.h
include/token.h
src/assemble.c
src/casl2.c
src/cmem.c
src/comet2monitor.c
src/monitor.c
src/token.c
src/word.c

index f8faf81..154f8e1 100644 (file)
@@ -142,13 +142,13 @@ bool assemblefile(const char *file, PASS pass);
 /**
  * @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 ファイルにアセンブル結果を書き込む
index 134baa8..e8b0aba 100644 (file)
@@ -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
index 32b1fd7..0c90936 100644 (file)
@@ -51,15 +51,6 @@ typedef struct {
  */
 void addcerrlist_tok();
 
-/**
- * @brief 文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く
- *
- * @return コメントを削除した文字列
- *
- * @param s 文字列
- */
-char *strip_casl2_comment(char *s);
-
 /**
  * @brief 行から、ラベル・コマンド・オペランドを取得する
  *
index 10ecb41..5e18000 100644 (file)
@@ -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で定義された関数群 */
index 68cbb24..da5a45b 100644 (file)
@@ -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[<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) {
@@ -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;
 }
index e921bb0..722c707 100644 (file)
@@ -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;
+}
index 3f9ed7a..4154e9c 100644 (file)
@@ -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;
index ec24645..30893b6 100644 (file)
@@ -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);
         }
index 22f33ba..8c49763 100644 (file)
@@ -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;
index df953c5..bae1e82 100644 (file)
@@ -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);
 }