diff --git a/src/cmdm.c b/src/cmdm.c index eba8ac5..6d5ebbf 100644 --- a/src/cmdm.c +++ b/src/cmdm.c @@ -249,16 +249,13 @@ void commandMF() { void commandMZ0() { /* 文字列変数の文字数・個数の設定の変更 */ - int max_len = getCaliValue(); + int max_len = getCaliValue(); // deprecated in System3.9 int max_num = getCaliValue(); int rsv = getCaliValue(); DEBUG_COMMAND("MZ0 %d,%d,%d:",max_len, max_num, rsv); - /* いつからか、文字列変数の最大長さは∞になったようだ */ - if (max_len == 0) max_len = STRVAR_LEN * 2; - - svar_init(max_num, max_len * 2 + 1); + svar_init(max_num); } void commandMG() { diff --git a/src/savedata.c b/src/savedata.c index 984a23c..6207986 100644 --- a/src/savedata.c +++ b/src/savedata.c @@ -572,24 +572,30 @@ static void loadStackInfo(char *buf) { /* 文字列変数のセーブ */ static void *saveStrVar(Ald_strVarHdr *head) { - int i; - char *tmp, *_tmp; - _tmp = tmp = malloc(svar_maxindex() * strvar_len); - if (tmp == NULL) { - WARNING("Out of memory"); - return NULL; - } - *tmp = 0; + int bufsize = 65536; + char *buf = malloc(bufsize); + if (!buf) + NOMEMERR(); + + int offset = 0; // Do not save svar[0], for backward compatibility. - for (i = 1; i <= svar_maxindex(); i++) { - strncpy(tmp, svar_get(i), strvar_len - 1); - tmp[strvar_len - 1] = '\0'; - tmp += strlen(tmp) + 1; + for (int i = 1; i <= svar_maxindex(); i++) { + const char *s = svar_get(i); + int len = strlen(s); + if (offset + len + 1 > bufsize) { + bufsize *= 2; + buf = realloc(buf, bufsize); + if (!buf) + NOMEMERR(); + } + strcpy(buf + offset, s); + buf[offset + len] = '\0'; + offset += len + 1; } - head->size = tmp - _tmp; + head->size = offset; head->count = svar_maxindex(); - head->maxlen = strvar_len; - return _tmp; + head->maxlen = 101; // so that old versions of xystem35 can read this save file + return buf; } /* 文字列変数のロード */ @@ -598,10 +604,9 @@ static void loadStrVar(char *buf) { int cnt, max, i; cnt = head->count; - max = head->maxlen; - if (svar_maxindex() != cnt || strvar_len != max) { + if (svar_maxindex() != cnt) { WARNING("Unexpected number of strings in savedata (%d, expected %d)", cnt, svar_maxindex()); - svar_init(cnt, max); + svar_init(cnt); } buf += sizeof(Ald_strVarHdr); for (i = 1; i <= cnt; i++) { diff --git a/src/savedata.h b/src/savedata.h index e2aa75b..01fbf34 100644 --- a/src/savedata.h +++ b/src/savedata.h @@ -36,8 +36,6 @@ #define SAVE_SAVEOK1 1 #define SAVE_SAVEOK0 0 -/* defined by variable.c */ -extern int strvar_len; struct VarRef; int save_loadAll(int no); diff --git a/src/variable.c b/src/variable.c index e70653b..e34c8e3 100644 --- a/src/variable.c +++ b/src/variable.c @@ -48,9 +48,7 @@ struct VarPage varPage[PAGE_MAX]; double longVar[SYSVARLONG_MAX]; /* 文字列変数 */ static char **strVar; -/* 文字列変数の属性(最大,1つあたりの大きさ) */ -int strvar_cnt; -int strvar_len; +static int strvar_cnt; const char *v_name(int var) { if (var < nact->ain.varnum) @@ -154,7 +152,7 @@ void v_getPageStatus(int page, int *in_use, int *size) { } /* 文字列変数の再初期化 */ -void svar_init(int max_index, int len) { +void svar_init(int max_index) { for (int i = max_index + 1; i < strvar_cnt; i++) { if (strVar[i]) free(strVar[i]); @@ -166,7 +164,6 @@ void svar_init(int max_index, int len) { for (int i = strvar_cnt; i <= max_index; i++) strVar[i] = NULL; strvar_cnt = max_index + 1; - strvar_len = len; } int svar_maxindex(void) { @@ -178,7 +175,7 @@ void v_init(void) { varPage[0].value = sysVar; varPage[0].size = SYSVAR_MAX; varPage[0].saveflag = true; - svar_init(STRVAR_MAX - 1, STRVAR_LEN); + svar_init(STRVAR_MAX - 1); } void v_reset(void) { diff --git a/src/variable.h b/src/variable.h index 2d43154..45a4375 100644 --- a/src/variable.h +++ b/src/variable.h @@ -29,7 +29,6 @@ #define SYSVAR_MAX 65536 #define STRVAR_MAX 5000 -#define STRVAR_LEN 101 struct VarPage { int size; @@ -67,7 +66,7 @@ static inline int *v_ref(int var, struct VarRef *ref) { return v_ref_indexed(var, -1, ref); } -void svar_init(int max_index, int len); +void svar_init(int max_index); int svar_maxindex(void); const char *svar_get(int no); void svar_set(int no, const char *str);