Valgrindで判明したメモリーに関する問題を修正
[YACASL2.git] / src / token.c
index ce2a69b..713a61f 100644 (file)
@@ -50,10 +50,10 @@ OPD *opdtok(const char *str)
     do {
         /* オペランド数が多すぎる場合はエラー */
         if(opd->opdc >= OPDSIZE) {
-            setcerr(117, NULL);    /* operand is too many */
+            setcerr(117, "");    /* operand is too many */
             break;
         }
-        /* 先頭が「=」の場合 */
+        /* 先頭が等号(=)の場合 */
         if(*r == '=') {
             r++;
         }
@@ -80,11 +80,11 @@ OPD *opdtok(const char *str)
             sepc = *sepp;
             *sepp = '\0';
             if(*q == '\0') {
-                setcerr(121, NULL);    /* cannot get operand token */
+                setcerr(121, "");    /* cannot get operand token */
                 break;
             }
             if(strlen(q) - rcnt > OPDSIZE) {
-                setcerr(118, NULL);    /* operand length is too long */
+                setcerr(118, "");    /* operand length is too long */
                 break;
             }
             opd->opdv[(++opd->opdc)-1] = strdup_chk(q, "opd.opdv[]");
@@ -119,19 +119,21 @@ CMDLINE *linetok(const char *line)
             break;
         }
     }
-    if(*tokens != '\0') {
+    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 = NULL;
+            *(cmdl->label) = '\0';
         } else {        /* ラベルを取得 */
             *sepp = '\0';
             /* 文字列が長すぎる場合はエラー */
             if(strlen(p) > LABELSIZE) {
                 setcerr(104, p);    /* label length is too long */
+            } else {
+                strcpy(cmdl->label, p);
             }
-            cmdl->label = strdup_chk(p, "cmdl.label");
             p = sepp + 1;
         }
         /* ラベルと命令の間の空白をスキップ */
@@ -140,9 +142,11 @@ CMDLINE *linetok(const char *line)
         }
         /* 命令とオペランドの取得 */
         if(*p == '\n' || *p == '\0') {        /* 命令がない場合は、終了 */
-            if(cmdl->label != NULL) {         /* ラベルが定義されていて命令がない場合はエラー */
-                setcerr(105, NULL);    /* no command in the line */
+            if(*(cmdl->label) != '\0') {      /* ラベルが定義されていて命令がない場合はエラー */
+                setcerr(105, "");    /* no command in the line */
             }
+            FREE(cmdl->label);
+            FREE(cmdl);
         } else {
             /* 命令の取得 */
             sepp = p + strcspn(p, " \t\n");
@@ -153,13 +157,13 @@ CMDLINE *linetok(const char *line)
             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 = malloc_chk(sizeof(OPD), "cmdl.opd");
                 cmdl->opd->opdc = 0;
             }
         }