From: j8takagi Date: Sun, 21 Mar 2010 17:42:38 +0000 (+0900) Subject: malloc周辺を中心としたリファクタリング X-Git-Tag: v0.1p15~38 X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=commitdiff_plain;h=650f92bf8dfdd0095db993f71f9e3867e7119acc malloc周辺を中心としたリファクタリング --- diff --git a/include/assemble.h b/include/assemble.h index deb83eb..eb0ab28 100644 --- a/include/assemble.h +++ b/include/assemble.h @@ -33,25 +33,37 @@ typedef struct { extern ASPROP *asprop; -/* アセンブラ命令とマクロ命令を表す番号 */ +/* アセンブラ命令を表す番号 */ 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; -/* アセンブラ命令とマクロ命令を表す配列 */ +/* マクロ命令を表す配列 */ 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行のアセンブル */ diff --git a/include/cerr.h b/include/cerr.h index 7265b0e..e6e8ddf 100644 --- a/include/cerr.h +++ b/include/cerr.h @@ -15,6 +15,10 @@ /* エラーを出力して終了 */ void *malloc_chk(size_t size, char *tag); +/* malloc_chkを実行してメモリを確保してから、 */ +/* コピーした文字列を返す */ +char *strdup_chk(const char *s, char *tag); + /* エラーの構造体 */ typedef struct { int num; /* エラー番号 */ diff --git a/src/assemble.c b/src/assemble.c index c9f1345..7dcd888 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -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); diff --git a/src/casl2.c b/src/casl2.c index d75650d..139e6b9 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -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; } diff --git a/src/cerr.c b/src/cerr.c index 3f7887b..db5ca2f 100644 --- a/src/cerr.c +++ b/src/cerr.c @@ -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; diff --git a/src/cmd.c b/src/cmd.c index 67d7c2a..04d32aa 100644 --- 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; diff --git a/src/comet2.c b/src/comet2.c index 8233613..6ab8693 100644 --- a/src/comet2.c +++ b/src/comet2.c @@ -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 ] [-C ] 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; } diff --git a/src/dumpword.c b/src/dumpword.c index 073dd3e..5ce0ec4 100644 --- a/src/dumpword.c +++ b/src/dumpword.c @@ -3,10 +3,10 @@ #include 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[]) diff --git a/src/exec.c b/src/exec.c index 07e4fcd..0d3863b 100644 --- a/src/exec.c +++ b/src/exec.c @@ -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; diff --git a/src/label.c b/src/label.c index a65e293..c76c3a7 100644 --- a/src/label.c +++ b/src/label.c @@ -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; diff --git a/src/struct.c b/src/struct.c index 1f62a13..1fb4326 100644 --- a/src/struct.c +++ b/src/struct.c @@ -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); } diff --git a/src/token.c b/src/token.c index e8b630b..b9ff352 100644 --- a/src/token.c +++ b/src/token.c @@ -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) {