4 * @brief 「,」区切りの文字列から、オペランドのトークンを取得
8 * @param *str 「,」区切りの文字列
10 OPD *opdtok(const char *str);
13 * @brief 行トークン取得のエラー定義
15 CERR cerr_linetok[] = {
16 { 104, "label length is too long" },
17 { 105, "no command in the line" },
21 * @brief オペランドトークン取得のエラー定義
23 static CERR cerr_opdtok[] = {
24 { 117, "operand too many in DC" },
25 { 118, "operand length too long" },
26 { 121, "cannot get operand token" },
27 { 123, "unclosed quote" },
30 OPD *opdtok(const char *str)
32 OPD *opd = malloc_chk(sizeof(OPD), "opd");
33 char *tok, *p, sepc = ',';
34 int i = 0, cnt_quote = 0;
41 tok = p = strdup_chk(str, "opdtok.p");
43 /* オペランド数が多すぎる場合はエラー */
44 if(opd->opdc >= OPDSIZE) {
45 setcerr(117, ""); /* operand is too many */
54 /* 「''」以外の場合はquote値を反転する */
55 if(p[i+1] != '\'' && (quoting == false || p[i-1] != '\'')) {
58 /* 「'」をカウントする。「''」の場合は1をカウント */
64 /* 「'」で開いたまま文字列が終了した場合 */
66 setcerr(123, str); /* unclosed quote */
71 i += strcspn(p + i, ", ");
73 setcerr(121, ""); /* cannot get operand token */
76 if(i - cnt_quote > OPDSIZE) {
77 setcerr(118, ""); /* operand length too long */
81 opd->opdv[(opd->opdc)++] = strndup_chk(p, i, "opd->opdv[]");
90 /* assemble.hで定義された関数群 */
91 void addcerrlist_tok()
93 addcerrlist(ARRAYSIZE(cerr_linetok), cerr_linetok);
94 addcerrlist(ARRAYSIZE(cerr_opdtok), cerr_opdtok);
97 CMDLINE *linetok(const char *line)
99 char *tok = NULL, *p = NULL;
101 CMDLINE *cmdl = NULL;
104 if(!line[0] || line[0] == '\n') {
107 tok = p = strdup_chk(line, "tok");
109 strip_casl2_comment(p);
116 cmdl = malloc_chk(sizeof(CMDLINE), "cmdl");
119 /* 行の先頭が空白またはタブの場合、ラベルは空 */
120 if((i = strcspn(p, " \t")) == 0) {
121 cmdl->label = strdup_chk("", "cmdl->label");
123 cmdl->label = strndup_chk(p, i, "cmdl->label");
124 /* ラベルの文字列が長すぎる場合はエラー */
126 setcerr(104, cmdl->label); /* label length is too long */
133 /* 文字列先頭をラベルの次の文字に移動 */
135 /* 文字列先頭を、ラベルと命令の間の空白の後ろに移動 */
136 p += strspn(p, " \t");
139 if(cmdl->label) { /* ラベルが定義されていて命令がない場合はエラー */
140 setcerr(105, ""); /* no command in the line */
147 i = strcspn(p, " \t");
148 cmdl->cmd = strndup_chk(p, i, "cmdl.cmd");
151 /* 文字列先頭を、命令の次の文字に移動 */
153 /* 文字列先頭を、命令とオペランドの間の空白の後ろに移動 */
154 p += strspn(p, " \t");
156 cmdl->opd = opdtok(p);