OPD *opdtok(const char *str) { OPD *opd = malloc_chk(sizeof(OPD), "opd"); char *p, *q, *r, *sepp; /* pは文字列全体の先頭位置、qはトークンの先頭位置、rは文字の位置 */ int sepc = ',', rcnt = 0; bool quoting = false; opd->opdc = 0; if(str == NULL) { return opd; } p = q = r = strdup_chk(str, "opdtok.p"); do { /* オペランド数が多すぎる場合はエラー */ if(opd->opdc >= OPDSIZE) { setcerr(117, ""); /* operand is too many */ break; } /* 先頭が等号(=)の場合 */ if(*r == '=') { r++; } /* 「'」の場合 */ if(*r == '\'') { /* 「''」以外の場合はquote値を反転 */ if(*(r+1) != '\'' && !(q < r && *(r-1) == '\'')) { quoting = !quoting; } /* 文字列の長さを数える。「'」の場合は数えない */ if(*(r+1) != '\'') { rcnt++; } } if(quoting == true) { /* 閉じ「'」がないまま文字列が終了した場合 */ if(*r == '\0') { setcerr(123, str); /* unclosed quote */ break; } r++; } else { sepp = r + strcspn(r, ", "); sepc = *sepp; *sepp = '\0'; if(*q == '\0') { setcerr(121, ""); /* cannot get operand token */ break; } if(strlen(q) - rcnt > OPDSIZE) { setcerr(118, ""); /* operand length too long */ break; } opd->opdv[(++opd->opdc)-1] = strdup_chk(q, "opd.opdv[]"); q = r = sepp + 1; rcnt = 0; } } while(sepc == ','); FREE(p); return opd; }
/** * @brief comet2コマンドのメイン * * @return 正常終了時は0、異常終了時は1 * * @param argc コマンドライン引数の数 * @param *argv[] コマンドライン引数の配列 */ int main(int argc, char *argv[]) { int memsize = DEFAULT_MEMSIZE, clocks = DEFAULT_CLOCKS; int opt, stat = 0; const char *version = PACKAGE_VERSION, *cmdversion = "comet2 of YACASL2 version %s\n"; const char *usage = "Usage: %s [-tTdvh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n"; cerr_init(); addcerrlist_load(); addcerrlist_exec(); /* オプションの処理 */ while((opt = getopt_long(argc, argv, "tTdM:C:vh", longopts, NULL)) != -1) { switch(opt) { case 't': execmode.trace = true; break; case 'T': execmode.trace = true; execmode.logical = true; break; case 'd': execmode.dump = true; break; case 'M': memsize = atoi(optarg); break; case 'C': clocks = atoi(optarg); break; case 'v': fprintf(stdout, cmdversion, version); return 0; case 'h': fprintf(stdout, usage, argv[0]); return 0; case '?': fprintf(stderr, usage, argv[0]); exit(1); } } if(argv[optind] == NULL) { setcerr(211, ""); /* object file not specified */ fprintf(stderr, "comet2 error - %d: %s\n", cerr->num, cerr->msg); exit(1); } /* COMET II仮想マシンのリセット */ reset(memsize, clocks); execptr->start = 0; if(loadassemble(argv[optind]) == true) { exec(); /* プログラム実行 */ } /* COMET II仮想マシンのシャットダウン */ shutdown(); stat = (cerr->num == 0) ? 0 : 1; /* エラーの解放 */ freecerr(); return stat; }
void writememory(WORD word, WORD adr, PASS pass) { char *n = NULL; /* メモリオーバーの場合、エラー発生 */ if(adr >= sys->memsize) { setcerr(119, (n = word2n(adr))); /* out of COMET II memory */ FREE(n) return; }
/** * @brief casl2revコマンドのメイン * * @return 正常終了時は0、異常終了時は1 * * @param argc コマンドライン引数の数 * @param *argv[] コマンドライン引数の配列 */ int main(int argc, char *argv[]) { int opt = 0; int stat = 0; const char *version = PACKAGE_VERSION; const char *cmdversion = "disassemble of YACASL2 version %s\n"; const char *usage = "Usage: %s [-vh] FILE\n"; /* エラーの定義 */ cerr_init(); addcerrlist_load(); /* オプションの処理 */ while((opt = getopt_long(argc, argv, "vh", longopts, NULL)) != -1) { switch(opt) { case 'v': fprintf(stdout, cmdversion, version); goto casl2revfin; case 'h': fprintf(stdout, usage, argv[0]); goto casl2revfin; case '?': fprintf(stderr, usage, argv[0]); setcerr(212, ""); /* invalid option */ goto casl2revfin; } } if(argv[optind] == NULL) { setcerr(211, ""); /* object file not specified */ fprintf(stderr, "disassemble error - %d: %s\n", cerr->num, cerr->msg); goto casl2revfin; } disassemble_file(argv[optind]); /* プログラム実行 */ casl2revfin: if(cerr->num > 0) { stat = 1; } freecerr(); /* エラーの解放 */ return stat; }
WORD getadr(const char *prog, const char *str, PASS pass) { WORD adr = 0; if(str[0] == '=') { adr = getliteral(str, pass); } else if(isdigit(str[0]) || str[0] == '-' || str[0] == '#') { adr = nh2word(str); } else { if(pass == SECOND) { if((adr = getlabel(prog, str)) == 0xFFFF) { setcerr(103, str); /* label not found */ } } } return adr; }
WORD grword(const char *str, bool is_x) { WORD r = 0; /* "GR[0-7]" 以外の文字列では、0xFFFFを返して終了 */ if(strlen(str) != 3 || strncmp(str, "GR", 2) != 0 || str[2] < '0' || str[2] > '0' + (GRSIZE - 1)) { return 0xFFFF; } r = (WORD)(str[2] - '0'); /* GR0は指標レジスタとして用いることができない */ if(is_x == true && r == 0x0) { setcerr(120, ""); /* GR0 in operand x */ return 0; } return r; }
int main(){ int i, j; int code[] = { 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 201, 202, 203, 204, 205, 206, 207, 999 }; const char *str[] = {NULL, "foobar"}; addcerrlist(ARRAYSIZE(cerr_utest), cerr_utest); /* エラーの初期化 */ cerr = malloc_chk(sizeof(CERR), "cerr"); for(i = 0; i < ARRAYSIZE(str); i++) { for(j = 0; j < ARRAYSIZE(code); j++) { setcerr(code[j], str[i]); printf("%d: %s - %d\t%s\n", code[j], str[i], cerr->num, cerr->msg); } } freecerr(); return 0; }
CMDLINE *linetok(const char *line) { char *tokens, *p, *sepp; bool quoting = false; CMDLINE *cmdl = NULL; if(*line == '\0') { return NULL; } tokens = strdup_chk(line, "tokens"); /* コメントを削除 */ for(p = tokens; *p != '\0'; p++) { /* 「'」で囲まれた文字列の処理。「''」は無視 */ if(*p == '\'' && *(p+1) != '\'' && !(p > tokens && *(p-1) == '\'')) { quoting = !quoting; } else if(quoting == false && *p == ';') { *p = '\0'; break; } } if(*tokens != '\n' && *tokens != '\0') { p = tokens; cmdl = malloc_chk(sizeof(CMDLINE), "cmdl"); cmdl->label = malloc_chk(LABELSIZE + 1, "cmdl.label"); /* ラベルの取得。行の先頭が空白またはタブの場合、ラベルは空 */ if((sepp = p + strcspn(p, " \t\n")) == p){ *(cmdl->label) = '\0'; } else { /* ラベルを取得 */ *sepp = '\0'; /* 文字列が長すぎる場合はエラー */ if(strlen(p) > LABELSIZE) { setcerr(104, p); /* label length is too long */ } else { strcpy(cmdl->label, p); } p = sepp + 1; } /* ラベルと命令の間の空白をスキップ */ while(*p == ' ' || *p == '\t') { p++; } /* 命令とオペランドの取得 */ if(*p == '\n' || *p == '\0') { /* 命令がない場合は、終了 */ if(*(cmdl->label) != '\0') { /* ラベルが定義されていて命令がない場合はエラー */ setcerr(105, ""); /* no command in the line */ } FREE(cmdl->label); FREE(cmdl); } else { /* 命令の取得 */ sepp = p + strcspn(p, " \t\n"); *sepp = '\0'; cmdl->cmd = strdup_chk(p, "cmdl.cmd"); p = sepp + 1; /* 命令とオペランドの間の空白をスキップ */ while(*p == ' ' || *p == '\t') { p++; } /* 改行かタブまでの文字列を取得 */ /* 「'」で囲まれた文字列に含まれる場合があるため、空白は無視 */ if((sepp = p + strcspn(p, "\t\n")) > p) { *sepp = '\0'; cmdl->opd = opdtok(p); } else { cmdl->opd = malloc_chk(sizeof(OPD), "cmdl.opd"); cmdl->opd->opdc = 0; } } } FREE(tokens); return cmdl; }