#include "word.h"
#include "hash.h"
+#include "cmem.h"
#include "cerr.h"
#ifndef ARRAYSIZE
#include <string.h>
#include <assert.h>
#include <stdbool.h>
+#include "cmem.h"
#ifndef ARRAYSIZE
#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
#endif
-/* mallocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *malloc_chk(size_t size, char *tag);
-
-/* callocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *calloc_chk(size_t nmemb, size_t size, char *tag);
-
-/* malloc_chkを実行してメモリを確保してから、 */
-/* コピーした文字列を返す */
-char *strdup_chk(const char *s, char *tag);
-
/* エラーの構造体 */
typedef struct {
int num; /* エラー番号 */
--- /dev/null
+#ifndef YACASL2_CMEM_H_INCLUDED
+#define YACASL2_CMEM_H_INCLUDED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
+#endif
+
+/* mallocを実行し、メモリを確保できない場合は */
+/* エラーを出力して終了 */
+void *malloc_chk(size_t size, char *tag);
+
+/* callocを実行し、メモリを確保できない場合は */
+/* エラーを出力して終了 */
+void *calloc_chk(size_t nmemb, size_t size, char *tag);
+
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag);
+
+/* メモリがNULLの場合は解放 */
+void free_chk(void *ptr, char *tag);
+#endif
#include <ctype.h>
#include <stdbool.h>
+#include "cmem.h"
#include "cerr.h"
/* wordのエラー定義 */
INCLUDE = ../include
CC = gcc
CFLAGS = -g -Wall -I $(INCLUDE)
-HASHSRC = hash.o
-CERRSRC = cerr.o
-WORDSRC = word.o
-COMMONSRC = $(WORDSRC) $(HASHSRC) $(CERRSRC) struct.o cmd.o
-ASSRC = assemble.o token.o label.o macro.o
-EXECSRC = exec.o dump.o
+WORDOBJ = word.o
+HASHOBJ = hash.o
+CMEMOBJ = cmem.o
+CERROBJ = cerr.o
+COMMONOBJ = $(WORDOBJ) $(HASHOBJ) $(CMEMOBJ) $(CERROBJ) struct.o cmd.o
+ASOBJ = assemble.o token.o label.o macro.o
+EXECOBJ = exec.o dump.o
+COMMONHEAD = $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cmem.h $(INCLUDE)/cerr.h
+ASHEAD = $(INCLUDE)/assemble.h
+EXECHEAD = $(INCLUDE)/exec.h
.PHONY: all clean
all: ../casl2 ../comet2 ../dumpword
-../casl2: casl2.o $(COMMONSRC) $(ASSRC) $(EXECSRC)
+../casl2: casl2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ)
$(CC) $(CFLAGS) -o $@ $^
-../comet2: comet2.o $(COMMONSRC) $(EXECSRC)
+../comet2: comet2.o $(COMMONOBJ) $(EXECOBJ)
$(CC) $(CFLAGS) -o $@ $^
-../dumpword: dumpword.o $(WORDSRC) $(CERRSRC)
+../dumpword: dumpword.o $(WORDOBJ) $(CMEMOBJ) $(CERROBJ)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) -c $(CFLAGS) $<
-casl2.o comet2.o $(COMMONSRC) $(ASSRC) $(EXECSRC): $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cerr.h
+casl2.o comet2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ): $(COMMONHEAD)
-casl2.o $(ASSRC): $(INCLUDE)/assemble.h
+casl2.o $(ASOBJ): $(ASHEAD)
-comet2.o $(EXECSRC): $(INCLUDE)/exec.h
+comet2.o $(EXECOBJ): $(EXECHEAD)
TAGS: $(INCLUDE)/*.h *.c
@if test `which etags`; then etags $^; fi
if(cerr->num > 0) {
break;
}
+ free_chk(line, "line");
+ free_chk(cmdl, "cmdl");
}
if(cerr->num > 0) {
fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg);
for(pass = FIRST; pass <= SECOND; pass++) {
if(pass == FIRST) {
create_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を作成 */
- asprop = malloc_chk(sizeof(ASPROP), "asprop");
+ asprop = malloc_chk(sizeof(ASPROP), "asprop"); /* アセンブル時のプロパティ用の領域確保 */
}
for(i = optind; i < argc; i++) {
/* データの格納開始位置 */
}
}
if(pass == SECOND) {
- free_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を解放 */
freelabel(); /* ラベルハッシュ表を解放 */
+ free_chk(asprop->prog, "asprop.prog"); /* プログラム名を解放 */
+ free_chk(asprop, "asprop"); /* アセンブル時のプロパティを解放 */
+ free_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を解放 */
}
}
if(res == true) {
if(cerr->num > 0) {
status = -1;
}
+ free_chk(objfile, "objfile");
/* エラーの解放 */
freecerr();
return status;
#include "cerr.h"
-/* mallocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *malloc_chk(size_t size, char *tag)
-{
- void *p;
-
- if((p = malloc(size)) == NULL) {
- fprintf(stderr, "%s: cannot allocate memory\n", tag);
- exit(-1);
- }
- return p;
-}
-
-/* callocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *calloc_chk(size_t nmemb, size_t size, char *tag)
-{
- void *p;
-
- if((p = calloc(nmemb, size)) == NULL) {
- fprintf(stderr, "%s: cannot allocate memory\n", tag);
- exit(-1);
- }
- return p;
-}
-
/* エラーの初期化 */
void cerr_init()
{
cerr->num = 0;
}
-/* 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;
/* 現在のエラーを設定する */
void setcerr(int num, const char *str)
{
+ /* 現在のエラー番号を設定 */
cerr->num = num;
+ /* 現在のエラーメッセージを設定 */
cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
if(str != NULL && strlen(str) <= CERRSTRSIZE) {
sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
/* エラーリストを解放 */
while(p != NULL) {
q = p->next;
- free(p);
+ free_chk(p, "freecerr.p");
p = q;
}
+ /* 現在のエラーメッセージを解放 */
+ free_chk(cerr->msg, "cerr.msg");
/* 現在のエラーを解放 */
- free(cerr);
+ free_chk(cerr, "cerr");
}
/* 命令と命令タイプからハッシュ値を生成する */
unsigned hash_cmdtype(const char *cmd, CMDTYPE type) {
HKEY *keys[2];
+ unsigned hashval;
/* 命令をセット */
- keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
+ keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]");
keys[0]->type = CHARS;
- keys[0]->val.s = strdup_chk(cmd, "keys[0].val");
+ keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s");
/* 命令タイプをセット */
- keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
+ keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]");
keys[1]->type = INT;
keys[1]->val.i = (int)(type & 070);
+ /* ハッシュ値の計算 */
+ hashval = hash(2, keys, cmdtabsize);
+ free_chk(keys[0]->val.s, "keys[0].val.s");
+ free_chk(keys[0], "keys[0]");
+ free_chk(keys[1], "keys[1]");
/* ハッシュ値を返す */
- return hash(2, keys, cmdtabsize);
+ return hashval;
}
/* 命令と命令タイプがキーのハッシュ表を作成する */
np = cmdtype_code[i];
while(np != NULL) {
nq = np->next;
- free(np);
+ free_chk(np, "free_cmdtype_code.np");
np = nq;
}
}
- free(cmdtype_code);
+ free_chk(cmdtype_code, "cmdtype_code");
}
/* 命令コードからハッシュ値を生成する */
--- /dev/null
+#include "cmem.h"
+
+/* mallocを実行し、0で初期化 */
+/* メモリを確保できない場合はエラーを出力して終了 */
+void *malloc_chk(size_t size, char *tag)
+{
+ void *p;
+
+ if((p = malloc(size)) == NULL) {
+ fprintf(stderr, "%s: cannot allocate memory\n", tag);
+ exit(-1);
+ }
+ return memset(p, 0, size);
+}
+
+/* callocを実行 */
+/* メモリを確保できない場合はエラーを出力して終了 */
+void *calloc_chk(size_t nmemb, size_t size, char *tag)
+{
+ void *p;
+
+ if((p = calloc(nmemb, size)) == NULL) {
+ fprintf(stderr, "%s: cannot allocate memory\n", tag);
+ exit(-1);
+ }
+ 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;
+}
+
+/* メモリがNULLの場合は解放 */
+void free_chk(void *ptr, char *tag)
+{
+ if(ptr != NULL) {
+ free(ptr);
+ }
+}
sys->memory[sys->cpu->gr[1]+i] = *(buffer + i);
}
sys->memory[sys->cpu->gr[2]] = i + 1;
+ free_chk(buffer, "buffer");
}
/* 標準出力へ文字データを書出(SVC 2) */
val = sys->memory[val];
}
}
+ free_chk(errpr, "errpr");
/* 主オペランドが1〜4の場合、第2ビットを無視 */
if(op >= 0x1000 && op <= 0x4FFF) {
op &= 0xFB00;
if(np->prog != NULL) {
free(np->prog);
}
- free(np->label);
- free(np);
+ free_chk(np->label, "np.label");
+ free_chk(np, "np");
}
}
}
/* COMET II仮想マシンのシャットダウン */
void shutdown()
{
- free(prog);
- free(sys->memory);
- free(sys->cpu);
- free(sys);
+ free_chk(prog, "prog");
+ free_chk(sys->memory, "sys.memory");
+ free_chk(sys->cpu, "sys.cpu");
+ free_chk(sys, "sys");
}
OPD *opdtok(const char *str)
{
OPD *opd = malloc_chk(sizeof(OPD), "opd");
- char *p, *q, *sepp;
- int sepc = ',', qcnt = 0;
+ 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 = strdup_chk(str, "opdtopk.p");
+ p = q = r = strdup_chk(str, "opdtopk.p");
do {
/* オペランド数が多すぎる場合はエラー */
if(opd->opdc >= OPDSIZE) {
setcerr(117, NULL); /* operand is too many */
break;
}
- /* 先頭が「=」の場合の処理 */
- if(*q == '=') {
- q++;
+ /* 先頭が「=」の場合 */
+ if(*r == '=') {
+ r++;
}
/* 「'」の場合 */
- if(*q == '\'') {
+ if(*r == '\'') {
/* 「''」以外の場合はquote値を反転 */
- if(*(q+1) != '\'' && !(p < q && *(q-1) == '\'')) {
+ if(*(r+1) != '\'' && !(q < r && *(r-1) == '\'')) {
quoting = !quoting;
}
- /* 「'」の分、文字列の長さを小さくする */
- if(*(q+1) != '\'') {
- qcnt++;
+ /* 文字列の長さを数える。「'」の場合は数えない */
+ if(*(r+1) != '\'') {
+ rcnt++;
}
}
if(quoting == true) {
/* 閉じ「'」がないまま文字列が終了した場合 */
- if(*q == '\0') {
+ if(*r == '\0') {
setcerr(123, str); /* unclosed quote */
break;
}
- q++;
+ r++;
} else {
- sepp = q + strcspn(q, ", ");
+ sepp = r + strcspn(r, ", ");
sepc = *sepp;
*sepp = '\0';
- if(*p == '\0') {
+ if(*q == '\0') {
setcerr(121, NULL); /* cannot get operand token */
break;
}
- if(strlen(p) - qcnt > OPDSIZE) {
+ if(strlen(q) - rcnt > OPDSIZE) {
setcerr(118, NULL); /* operand length is too long */
break;
}
- opd->opdv[(++opd->opdc)-1] = strdup_chk(p, "opd.opdv[]");
- p = q = sepp + 1;
- qcnt = 0;
+ opd->opdv[(++opd->opdc)-1] = strdup_chk(q, "opd.opdv[]");
+ q = r = sepp + 1;
+ rcnt = 0;
}
} while(sepc == ',');
+ free_chk(p, "opdtok.p");
return opd;
}
enum {
MAXLEN = 6, /* WORD値を10進数で表したときの最大桁数 */
};
- char *p = malloc_chk(MAXLEN, "word2n.p"), *q = malloc_chk(MAXLEN, "word2n.q");
+ char *p = malloc_chk(MAXLEN, "word2n.p"), *digit = malloc_chk(MAXLEN, "word2n.digit");
int i = 0, j;
do{
*(p + i++) = word % 10 + '0';
} while((word /= 10) > 0);
for(j = 0; j < i; j++) {
- *(q + j) = *(p + (i - 1) - j);
+ *(digit + j) = *(p + (i - 1) - j);
}
- *(q + j + 1) = '\0';
- return q;
+ *(digit + j + 1) = '\0';
+ free_chk(p, "word2n.p");
+ return digit;
}
/* WORD値を2進数の文字列に変換 */
WORD mask = 0x8000;
char *bit, *p;
- p = bit = malloc_chk(MAXLEN + 1, "word2bit.bit");
+ bit = p = malloc_chk(MAXLEN + 1, "word2bit.bit");
do {
*p++ = (word & mask) ? '1' : '0';
} while((mask >>= 1) > 0);
INCLUDE = ../../../include
CC = gcc
CFLAGS = -g -Wall -I $(INCLUDE)
-COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cerr.o
+COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cmem.o $(SRCDIR)/cerr.o
ASSRC = $(SRCDIR)/assemble.o $(SRCDIR)/token.o $(SRCDIR)/label.o $(SRCDIR)/macro.o
EXECSRC = $(SRCDIR)/exec.o $(SRCDIR)/dump.o