malloc周辺を中心としたリファクタリング
authorj8takagi <j8takagi@nifty.com>
Sun, 21 Mar 2010 17:42:38 +0000 (02:42 +0900)
committerj8takagi <j8takagi@nifty.com>
Sun, 21 Mar 2010 17:42:38 +0000 (02:42 +0900)
12 files changed:
include/assemble.h
include/cerr.h
src/assemble.c
src/casl2.c
src/cerr.c
src/cmd.c
src/comet2.c
src/dumpword.c
src/exec.c
src/label.c
src/struct.c
src/token.c

index deb83eb..eb0ab28 100644 (file)
@@ -33,25 +33,37 @@ typedef struct {
 
 extern ASPROP *asprop;
 
-/* ã\82¢ã\82»ã\83³ã\83\96ã\83©å\91½ä»¤ã\81¨ã\83\9eã\82¯ã\83­å\91½ä»¤ã\82\92表ã\81\99ç\95ªå\8f· */
+/* アセンブラ命令を表す番号 */
 typedef enum {
     START = 01,
     END = 02,
     DS = 03,
     DC = 04,
+} ASCMDID;
+
+/* アセンブラ命令を表す配列 */
+typedef struct {
+    ASCMDID cmdid;
+    int opdc_min;
+    int opdc_max;
+    char *cmd;
+} ASCMD;
+
+/* マクロ命令を表す番号 */
+typedef enum {
     IN = 011,
     OUT = 012,
     RPUSH = 013,
     RPOP = 014,
-} CASLCMD;
+} MACROCMDID;
 
-/* ã\82¢ã\82»ã\83³ã\83\96ã\83©å\91½ä»¤ã\81¨ã\83\9eã\82¯ã\83­å\91½ä»¤ã\82\92表ã\81\99é\85\8då\88\97 */
+/* マクロ命令を表す配列 */
 typedef struct {
-    CASLCMD cmdid;
+    MACROCMDID cmdid;
     int opdc_min;
     int opdc_max;
     char *cmd;
-} CMDARRAY;
+} MACROCMD;
 
 /* ラベル配列 */
 typedef struct {
@@ -148,16 +160,16 @@ void writestr(const char *str, bool literal, PASS pass);
 /* アセンブラ命令DCをメモリに書込 */
 void writeDC(const char *str, PASS pass);
 
-/* 命令がアセンブラ命令の場合は処理を実行する。
-   実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
+/* 命令がアセンブラ命令の場合は処理を実行する。 */
+/* 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
 bool assemblecmd(const CMDLINE *cmdl, PASS pass);
 
 /* 命令のコードを返す
    命令が無効な場合は0xFFFF */
 WORD getcmd(CMDTYPE type, const char *cmd);
 
-/* 命令が機械語命令の場合は処理を実行
-   実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
+/* 命令が機械語命令の場合は処理を実行 */
+/* 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
 bool cometcmd(const CMDLINE *cmdl, PASS pass);
 
 /* 1行のアセンブル */
index 7265b0e..e6e8ddf 100644 (file)
 /* エラーを出力して終了 */
 void *malloc_chk(size_t size, char *tag);
 
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag);
+
 /* エラーの構造体 */
 typedef struct {
     int num;        /* エラー番号 */
index c9f1345..7dcd888 100644 (file)
@@ -47,7 +47,7 @@ WORD getgr(const char *str, bool is_x)
     WORD r;
     /* 「GR[0-7]」以外の文字列では、0xFFFFを返して終了 */
     if(!(strlen(str) == 3 && strncmp(str, "GR", 2) == 0 &&
-         (*(str+2) >= '0' && *(str+2) <= '0' + GRSIZE)))
+         (*(str+2) >= '0' && *(str+2) <= '0' + (GRSIZE - 1))))
     {
         return 0xFFFF;
     }
@@ -167,9 +167,9 @@ void writeDC(const char *str, PASS pass)
 bool assemblecmd(const CMDLINE *cmdl, PASS pass)
 {
     int i = 0;
-    CASLCMD cmd = 0;
+    ASCMDID cmdid = 0;
     bool status = false;
-    CMDARRAY ascmd[] = {
+    ASCMD ascmd[] = {
         { START, 0, 1, "START" },
         { END, 0, 0, "END" },
         { DC, 1, OPDSIZE, "DC" },
@@ -183,12 +183,12 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass)
                 setcerr(106, NULL);    /* operand count mismatch */
                 return false;
             }
-            cmd = ascmd[i].cmdid;
+            cmdid = ascmd[i].cmdid;
             break;
         }
     } while(ascmd[++i].cmdid != 0);
     /* アセンブラ命令 */
-    switch(cmd)
+    switch(cmdid)
     {
     case START:
         if(cmdl->label == NULL) {
@@ -196,7 +196,7 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass)
             return false;
         }
         /* プログラム名の設定 */
-        asprop->prog = strdup(cmdl->label);
+        asprop->prog = strdup_chk(cmdl->label, "asprop.prog");
         /* オペランドがある場合、実行開始番地を設定 */
         if(pass == SECOND && cmdl->opd->opdc == 1) {
             if((progprop->start = getlabel(asprop->prog, cmdl->opd->opdv[0])) == 0xFFFF) {
@@ -249,9 +249,9 @@ bool assemblecmd(const CMDLINE *cmdl, PASS pass)
 bool macrocmd(const CMDLINE *cmdl, PASS pass)
 {
     int i = 0;
-    CASLCMD cmd;
+    MACROCMDID cmdid;
     bool status = false;
-    CMDARRAY macrocmd[] = {
+    MACROCMD macrocmd[] = {
         { IN, 2, 2, "IN" },
         { OUT, 2, 2, "OUT" },
         { RPUSH, 0, 0, "RPUSH" },
@@ -261,15 +261,17 @@ bool macrocmd(const CMDLINE *cmdl, PASS pass)
 
     do {
         if(strcmp(cmdl->cmd, macrocmd[i].cmd) == 0) {
-            if(cmdl->opd->opdc < macrocmd[i].opdc_min || cmdl->opd->opdc > macrocmd[i].opdc_max) {
+            if(cmdl->opd->opdc < macrocmd[i].opdc_min ||
+               cmdl->opd->opdc > macrocmd[i].opdc_max)
+            {
                 setcerr(106, NULL);    /* operand count mismatch */
                 return false;
             }
-            cmd = macrocmd[i].cmdid;
+            cmdid = macrocmd[i].cmdid;
             break;
         }
     } while(macrocmd[++i].cmdid != 0);
-    switch(cmd)
+    switch(cmdid)
     {
     case IN:
         status = writeIN(cmdl->opd->opdv[0], cmdl->opd->opdv[1], pass);
index d75650d..139e6b9 100644 (file)
@@ -6,21 +6,21 @@
 
 /* casl2コマンドのオプション */
 static struct option longopts[] = {
-    {"source", no_argument, NULL, 's'},
-    {"label", no_argument, NULL, 'l'},
-    {"labelonly", no_argument, NULL, 'L'},
-    {"assembledetail", no_argument, NULL, 'a'},
-    {"assembledetailonly", no_argument, NULL, 'A'},
-    {"assembleout", optional_argument, NULL, 'o'},
-    {"assembleoutonly", optional_argument, NULL, 'O'},
-    {"trace", no_argument, NULL, 't'},
-    {"tracearithmetic", no_argument, NULL, 't'},
-    {"tracelogical", no_argument, NULL, 'T'},
-    {"dump", no_argument, NULL, 'd'},
-    {"memorysize", required_argument, NULL, 'M'},
-    {"clocks", required_argument, NULL, 'C'},
-    {"help", no_argument, NULL, 'h'},
-    {0, 0, 0, 0},
+    { "source", no_argument, NULL, 's' },
+    { "label", no_argument, NULL, 'l' },
+    { "labelonly", no_argument, NULL, 'L' },
+    { "assembledetail", no_argument, NULL, 'a' },
+    { "assembledetailonly", no_argument, NULL, 'A' },
+    { "assembleout", optional_argument, NULL, 'o' },
+    { "assembleoutonly", optional_argument, NULL, 'O' },
+    { "trace", no_argument, NULL, 't' },
+    { "tracearithmetic", no_argument, NULL, 't' },
+    { "tracelogical", no_argument, NULL, 'T' },
+    { "dump", no_argument, NULL, 'd' },
+    { "memorysize", required_argument, NULL, 'M' },
+    { "clocks", required_argument, NULL, 'C' },
+    { "help", no_argument, NULL, 'h' },
+    { 0, 0, 0, 0 },
 };
 
 /* casl2のエラー定義 */
@@ -35,6 +35,7 @@ bool addcerrlist_casl2()
 /* 指定されたファイルにアセンブル結果を書込 */
 void outassemble(const char *file) {
     FILE *fp;
+
     if((fp = fopen(file, "w")) == NULL) {
         perror(file);
         exit(-1);
@@ -47,20 +48,15 @@ void outassemble(const char *file) {
 const char *objfile_name(const char *str)
 {
     const char *default_name = "a.o";
-
-    if(str == NULL) {
-        return default_name;
-    } else {
-        return str;
-    }
+    return (str == NULL) ? default_name : str;
 }
 
 /* casl2コマンドのメイン */
 int main(int argc, char *argv[])
 {
-    int opt, i, retval = 0;
+    int opt, i, status = 0;
     PASS pass;
-    bool status = false;
+    bool res = false;
     WORD beginptr[argc];
     char *objfile = NULL;
     const char *usage =
@@ -90,11 +86,11 @@ int main(int argc, char *argv[])
             asmode.onlyassemble = true;
             break;
         case 'o':
-            objfile = strdup(objfile_name(optarg));
+            objfile = strdup_chk(objfile_name(optarg), "objfile");
             break;
         case 'O':
             asmode.onlyassemble = true;
-            objfile = strdup(objfile_name(optarg));
+            objfile = strdup_chk(objfile_name(optarg), "objfile");
             break;
         case 't':
             execmode.trace = true;
@@ -146,7 +142,7 @@ int main(int argc, char *argv[])
             {
                 fprintf(stdout, "\nAssemble %s (%d)\n", argv[i], pass);
             }
-            if((status = assemble(argv[i], pass)) == false) {
+            if((res = assemble(argv[i], pass)) == false) {
                 exit(-1);
             }
         }
@@ -162,22 +158,22 @@ int main(int argc, char *argv[])
             freelabel();            /* ラベルハッシュ表を解放 */
         }
     }
-    if(status == true) {
+    if(res == true) {
         if(objfile != NULL) {
             outassemble(objfile);
         }
         if(asmode.onlyassemble == false) {
             create_code_type();    /* 命令と命令タイプがキーのハッシュ表を作成 */
-            status = exec();       /* プログラム実行 */
+            res = exec();          /* プログラム実行 */
             free_code_type();      /* 命令と命令タイプがキーのハッシュ表を解放 */
         }
     }
     /* COMET II仮想マシンのシャットダウン */
     shutdown();
     if(cerr->num > 0) {
-        retval = -1;
+        status = -1;
     }
     /* エラーの解放 */
     freecerr();
-    return retval;
+    return status;
 }
index 3f7887b..db5ca2f 100644 (file)
@@ -13,6 +13,18 @@ void *malloc_chk(size_t size, char *tag)
     return p;
 }
 
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag)
+{
+    assert(s != NULL);
+    char *t;
+
+    t = malloc_chk(strlen(s) + 1, tag);
+    strcpy(t, s);
+    return t;
+}
+
 /* 現在のエラー */
 CERR *cerr;
 
index 67d7c2a..04d32aa 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -52,7 +52,7 @@ unsigned hash_cmdtype(const char *cmd, CMDTYPE type) {
     /* 命令をセット */
     keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
     keys[0]->type = CHARS;
-    keys[0]->val.s = strdup(cmd);
+    keys[0]->val.s = strdup_chk(cmd, "keys[0].val");
     /* 命令タイプをセット */
     keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
     keys[1]->type = INT;
index 8233613..6ab8693 100644 (file)
@@ -48,7 +48,7 @@ bool loadassemble(char *file) {
 /* comet2コマンド */
 int main(int argc, char *argv[])
 {
-    int opt, retval = 0;
+    int opt, status = 0;
     const char *usage = "Usage: %s [-tTdh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n";
 
     /* エラーの初期化 */
@@ -96,9 +96,9 @@ int main(int argc, char *argv[])
     /* COMET II仮想マシンのシャットダウン */
     shutdown();
     if(cerr->num > 0) {
-        retval = -1;
+        status = -1;
     }
     /* エラーの解放 */
     freecerr();
-    return retval;
+    return status;
 }
index 073dd3e..5ce0ec4 100644 (file)
@@ -3,10 +3,10 @@
 #include <getopt.h>
 
 static struct option longopts[] = {
-    {"arithmetic", no_argument, NULL, 'a'},
-    {"logical", no_argument, NULL, 'l'},
-    {"help", no_argument, NULL, 'h'},
-    {0, 0, 0, 0},
+    { "arithmetic", no_argument, NULL, 'a' },
+    { "logical", no_argument, NULL, 'l' },
+    { "help", no_argument, NULL, 'h' },
+    { 0, 0, 0, 0 },
 };
 
 int main(int argc, char *argv[])
index 07e4fcd..0d3863b 100644 (file)
@@ -274,10 +274,11 @@ bool exec()
     clock_t clock_begin, clock_end;
 
     addcerrlist_exec();
-    if(execmode.trace) {
+    if(execmode.trace == true) {
         fprintf(stdout, "\nExecuting machine codes\n");
     }
-    /* レジスタの初期化 */
+    /* フラグレジスタの初期値設定 */
+    cpu->fr = 0x0;
     cpu->sp = memsize;
     cpu->pr = progprop->start;
     /* 機械語の実行 */
@@ -447,7 +448,7 @@ bool exec()
         case 0x8100:    /* RET */
             assert(cpu->sp > progprop->end && cpu->sp <= memsize);
             if(cpu->sp == memsize) {
-                return false;
+                return true;
             } else {
                 cpu->pr = memory[(cpu->sp)++];
                 break;
index a65e293..c76c3a7 100644 (file)
@@ -9,14 +9,15 @@ unsigned labelhash(const char *prog, const char *label)
 {
     HKEY *keys[2];
     int i = 0;
+
     if(prog != NULL) {
-        keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+        keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key[]");
         keys[i]->type = CHARS;
-        keys[i++]->val.s = strdup(prog);
+        keys[i]->val.s = strdup_chk(prog, "labelhash.key[].val");
     }
-    keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+    keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key[]");
     keys[i]->type = CHARS;
-    keys[i]->val.s = strdup(label);
+    keys[i]->val.s = strdup_chk(label, "labelhash.key[].val");
     /* ハッシュ値を返す */
     return hash(i+1, keys, LABELTABSIZE);
 }
@@ -26,6 +27,7 @@ WORD getlabel(const char *prog, const char *label)
 {
     assert(label != NULL);
     LABELTAB *np;
+
     for(np = labels[labelhash(prog, label)]; np != NULL; np = np->next) {
         if((prog == NULL || (np->prog != NULL && strcmp(prog, np->prog) == 0)) &&
            strcmp(label, np->label) == 0)
@@ -49,21 +51,15 @@ bool addlabel(const char *prog, const char *label, WORD adr)
         return false;
     }
     /* メモリを確保 */
-    if((np = malloc_chk(sizeof(LABELTAB), "addlabel.np")) == NULL) {
-        goto cerr102;
-    }
+    np = malloc_chk(sizeof(LABELTAB), "labels.next");
     /* プログラム名を設定 */
     if(prog == NULL) {
         np->prog = NULL;
     } else {
-        if((np->prog = strdup(prog)) == NULL) {
-            goto cerr102;
-        }
+        np->prog = strdup_chk(prog, "labels.prog");
     }
     /* ラベルを設定 */
-    if((np->label = strdup(label)) == NULL) {
-        goto cerr102;
-    }
+    np->label = strdup_chk(label, "labels.label");
     /* アドレスを設定 */
     np->adr = adr;
     /* ラベル数を設定 */
@@ -73,9 +69,6 @@ bool addlabel(const char *prog, const char *label, WORD adr)
     np->next = labels[hashval];
     labels[hashval] = np;
     return true;
-cerr102:
-    setcerr(102, NULL);    /* label table is full */
-    return false;
 }
 
 int compare_adr(const void *a, const void *b)
@@ -93,9 +86,13 @@ void printlabel()
     for(i = 0; i < LABELTABSIZE; i++) {
         for(np = labels[i]; np != NULL; np = np->next) {
             assert(np->label != NULL);
-            ar[asize] = malloc_chk(sizeof(LABELARRAY), "ar[asize]");
-            ar[asize]->prog = (np->prog == NULL ? NULL : strdup(np->prog));
-            ar[asize]->label = strdup(np->label);
+            ar[asize] = malloc_chk(sizeof(LABELARRAY), "ar[]");
+            if(np->prog == NULL) {
+                ar[asize]->prog = NULL;
+            } else {
+                ar[asize]->prog = strdup_chk(np->prog, "ar[].prog");
+            }
+            ar[asize]->label = strdup_chk(np->label, "ar[].label");
             ar[asize++]->adr = np->adr;
         }
     }
@@ -113,6 +110,7 @@ void freelabel()
 {
     int i;
     LABELTAB *np, *nq;
+
     for(i = 0; i < LABELTABSIZE; i++) {
         for(np = labels[i]; np != NULL; np = nq) {
             nq = np->next;
index 1f62a13..1fb4326 100644 (file)
@@ -19,6 +19,7 @@ PROGPROP *progprop;
 void reset()
 {
     int i;
+
     /* メモリの初期化 */
     memory = malloc_chk(memsize * sizeof(WORD), "memory");
     for(i = 0; i < memsize; i++) {
@@ -37,6 +38,7 @@ void reset()
 /* COMET II仮想マシンのシャットダウン */
 void shutdown()
 {
+    free(progprop);
     free(cpu);
     free(memory);
 }
index e8b630b..b9ff352 100644 (file)
@@ -13,7 +13,7 @@ OPD *opdtok(const char *str)
     if(str == NULL) {
         return opd;
     }
-    p = q = strdup(str);
+    p = q = strdup_chk(str, "opdtopk.p");
     do {
         /* オペランド数が多すぎる場合はエラー */
         if(opd->opdc >= OPDSIZE) {
@@ -54,7 +54,7 @@ OPD *opdtok(const char *str)
                 setcerr(118, NULL);    /* operand length is too long */
                 break;
             }
-            opd->opdv[(++opd->opdc)-1] = strdup(p);
+            opd->opdv[(++opd->opdc)-1] = strdup_chk(p, "opd.opdv[]");
             p = q = sepp + 1;
             qcnt = 0;
         }
@@ -72,7 +72,7 @@ CMDLINE *linetok(const char *line)
     if(line == NULL || strlen(line) == 0) {
         return NULL;
     }
-    tokens = strdup(line);
+    tokens = strdup_chk(line, "tokens");
     /* コメントを削除 */
     for(p = tokens; *p != '\0'; p++) {
         /* 「'」で囲まれた文字列の処理。「''」は無視 */
@@ -96,7 +96,7 @@ CMDLINE *linetok(const char *line)
         if(strlen(p) > LABELSIZE) {
             setcerr(104, p);    /* label length is too long */
         }
-        cmdl->label = strdup(p);
+        cmdl->label = strdup_chk(p, "cmdl.label");
         p = sepp + 1;
     }
     while(*p == ' ' || *p == '\t') {
@@ -113,13 +113,13 @@ CMDLINE *linetok(const char *line)
     /* 命令を取得 */
     sepp = p + strcspn(p, " \t\n");
     *sepp = '\0';
-    cmdl->cmd = strdup(p);
+    cmdl->cmd = strdup_chk(p, "cmdl.cmd");
     p = sepp + 1;
     while(*p == ' ' || *p == '\t') {
         p++;
     }
     /* オペランドを取得 */
-    cmdl->opd = malloc_chk(sizeof(OPD), "cmdl->opd");
+    cmdl->opd = malloc_chk(sizeof(OPD), "cmdl.opd");
     /* 改行かタブまでの文字列を取得。
        「'」で囲まれた文字列に含まれる場合があるため、空白は無視 */
     if((sepp = p + strcspn(p, "\t\n")) > p) {