aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2020-06-10 06:10:04 +0300
committerArnold D. Robbins <arnold@skeeve.com>2020-06-10 17:48:50 +0300
commit17d03a4deb7ed18abb4e0e590e6315050d9c29fd (patch)
tree324feeb1e3568042fe9e2f73ebd6d63296781cf7
parent5aae00200fc44bdfefbb497cf57eb23a9d2517be (diff)
downloadegawk-17d03a4deb7ed18abb4e0e590e6315050d9c29fd.tar.gz
egawk-17d03a4deb7ed18abb4e0e590e6315050d9c29fd.tar.bz2
egawk-17d03a4deb7ed18abb4e0e590e6315050d9c29fd.zip
Add mbuilov fixes. Still needs review.
-rw-r--r--awk.h8
-rw-r--r--awkgram.c6
-rw-r--r--awkgram.y6
-rw-r--r--builtin.c3
-rw-r--r--debug.c24
-rw-r--r--extension/filefuncs.c23
-rw-r--r--extension/gawkfts.c5
-rw-r--r--extension/readdir.c5
-rw-r--r--extension/rwarray0.c2
-rw-r--r--io.c2
-rw-r--r--node.c25
-rwxr-xr-xtest/Gentests2
12 files changed, 66 insertions, 45 deletions
diff --git a/awk.h b/awk.h
index 283817a1..9005ff34 100644
--- a/awk.h
+++ b/awk.h
@@ -1267,8 +1267,11 @@ static inline void
DEREF(NODE *r)
{
assert(r->valref > 0);
- if (--r->valref == 0)
- r_unref(r);
+#ifndef GAWKDEBUG
+ if (--r->valref > 0)
+ return;
+#endif
+ r_unref(r);
}
#define POP_NUMBER() force_number(POP_SCALAR())
@@ -1926,6 +1929,7 @@ force_string_fmt(NODE *s, const char *fmtstr, int fmtidx)
static inline void
unref(NODE *r)
{
+ assert(r == NULL || r->valref > 0);
if (r != NULL && --r->valref <= 0)
r_unref(r);
}
diff --git a/awkgram.c b/awkgram.c
index b5985fe9..469184e5 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -212,7 +212,7 @@ const char awk_namespace[] = "awk";
const char *current_namespace = awk_namespace;
bool namespace_changed = false;
-static INSTRUCTION *rule_block[sizeof(ruletab)];
+static INSTRUCTION *rule_block[sizeof(ruletab)/sizeof(ruletab[0])];
static INSTRUCTION *ip_rec;
static INSTRUCTION *ip_newfile;
@@ -5293,7 +5293,7 @@ parse_program(INSTRUCTION **pcode, bool from_eval)
lexeof = false;
lexptr = NULL;
lasttok = 0;
- memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
+ memset(rule_block, 0, sizeof(rule_block));
errcount = 0;
tok = tokstart != NULL ? tokstart : tokexpand();
@@ -5974,7 +5974,7 @@ get_comment(enum commenttype flag, INSTRUCTION **comment_instruction)
sourceline++;
tokadd(c);
}
- } while (isspace(c) && c != END_FILE);
+ } while (c != END_FILE && isspace(c));
if (c == END_FILE)
break;
else if (c != '#') {
diff --git a/awkgram.y b/awkgram.y
index 0eb96940..ec917c3b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -167,7 +167,7 @@ const char awk_namespace[] = "awk";
const char *current_namespace = awk_namespace;
bool namespace_changed = false;
-static INSTRUCTION *rule_block[sizeof(ruletab)];
+static INSTRUCTION *rule_block[sizeof(ruletab)/sizeof(ruletab[0])];
static INSTRUCTION *ip_rec;
static INSTRUCTION *ip_newfile;
@@ -2779,7 +2779,7 @@ parse_program(INSTRUCTION **pcode, bool from_eval)
lexeof = false;
lexptr = NULL;
lasttok = 0;
- memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
+ memset(rule_block, 0, sizeof(rule_block));
errcount = 0;
tok = tokstart != NULL ? tokstart : tokexpand();
@@ -3460,7 +3460,7 @@ get_comment(enum commenttype flag, INSTRUCTION **comment_instruction)
sourceline++;
tokadd(c);
}
- } while (isspace(c) && c != END_FILE);
+ } while (c != END_FILE && isspace(c));
if (c == END_FILE)
break;
else if (c != '#') {
diff --git a/builtin.c b/builtin.c
index dc8d1a8e..7ef2acd8 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3997,6 +3997,9 @@ do_bindtextdomain(int nargs)
DEREF(t2);
}
+ if (the_result == NULL)
+ the_result = "";
+
return make_string(the_result, strlen(the_result));
}
diff --git a/debug.c b/debug.c
index d53b9b8a..d6bb0bdd 100644
--- a/debug.c
+++ b/debug.c
@@ -2403,9 +2403,11 @@ func:
if ((b = set_breakpoint_at(rp, rp->source_line, false)) == NULL)
fprintf(out_fp, _("cannot set breakpoint in function `%s'\n"),
func->vname);
- else if (temporary)
- b->flags |= BP_TEMP;
- lineno = b->bpi->source_line;
+ else {
+ if (temporary)
+ b->flags |= BP_TEMP;
+ lineno = b->bpi->source_line;
+ }
break;
default:
@@ -4605,10 +4607,10 @@ enlarge_buffer:
}
if (nchar > 0) { /* non-empty commands list */
- nchar += (strlen("commands ") + 20 + strlen("end") + 1); /* 20 for cnum (an int) */
- if (nchar > buflen - bl) {
- buflen = bl + nchar;
- erealloc(buf, char *, buflen + 3, "serialize_list");
+ nchar += (strlen("commands ") + 20/*cnum*/ + 1/*CSEP*/ + strlen("end") + 1/*FSEP*/);
+ if (nchar >= buflen - bl) {
+ buflen = bl + nchar + 1/*RSEP*/;
+ erealloc(buf, char *, buflen + 1, "serialize_list");
}
nchar = sprintf(buf + bl, "commands %d", cnum);
bl += nchar;
@@ -4634,8 +4636,8 @@ enlarge_buffer:
nchar = strlen("end"); /* end of 'commands' */
memcpy(buf + bl, "end", nchar);
bl += nchar;
+ buf[bl++] = FSEP; /* field */
}
- buf[bl++] = FSEP; /* field */
buf[bl++] = RSEP; /* record */
buf[bl] = '\0';
@@ -4643,9 +4645,9 @@ enlarge_buffer:
if (cndn->expr) {
bl--; /* undo RSEP from above */
nchar = strlen(cndn->expr);
- if (nchar > buflen - bl) {
- buflen = bl + nchar;
- erealloc(buf, char *, buflen + 3, "serialize_list");
+ if (nchar + 1/*FSEP*/ >= buflen - bl) {
+ buflen = bl + nchar + 1/*FSEP*/ + 1/*RSEP*/;
+ erealloc(buf, char *, buflen + 1, "serialize_list");
}
memcpy(buf + bl, cndn->expr, nchar);
bl += nchar;
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 86e60321..83141685 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -126,13 +126,16 @@ static long long
get_inode(const char *fname)
{
HANDLE fh;
+ BOOL ok;
BY_HANDLE_FILE_INFORMATION info;
fh = CreateFile(fname, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (fh == INVALID_HANDLE_VALUE)
return 0;
- if (GetFileInformationByHandle(fh, &info)) {
+ ok = GetFileInformationByHandle(fh, &info);
+ CloseHandle(fh);
+ if (ok) {
long long inode = info.nFileIndexHigh;
inode <<= 32;
@@ -403,7 +406,8 @@ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
array_set_numeric(array, "gid", sbuf->st_gid);
array_set_numeric(array, "size", sbuf->st_size);
#ifdef __MINGW32__
- array_set_numeric(array, "blocks", (sbuf->st_size + 4095) / 4096);
+ array_set_numeric(array, "blocks", (double)((sbuf->st_size +
+ device_blocksize() - 1) / device_blocksize()));
#else
array_set_numeric(array, "blocks", sbuf->st_blocks);
#endif
@@ -568,6 +572,7 @@ init_filefuncs(void)
#ifndef __MINGW32__
/* at least right now, only FTS needs initializing */
+#define FTS_NON_RECURSIVE FTS_STOP /* Don't step into directories. */
static struct flagtab {
const char *name;
int value;
@@ -579,7 +584,7 @@ init_filefuncs(void)
ENTRY(FTS_PHYSICAL),
ENTRY(FTS_SEEDOT),
ENTRY(FTS_XDEV),
- ENTRY(FTS_SKIP),
+ {"FTS_SKIP", FTS_NON_RECURSIVE},
{ NULL, 0 }
};
@@ -836,7 +841,7 @@ do_fts(int nargs, awk_value_t *result, struct awk_ext_func *unused)
int ret = -1;
static const int mask = (
FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR | FTS_PHYSICAL
- | FTS_SEEDOT | FTS_XDEV | FTS_SKIP);
+ | FTS_SEEDOT | FTS_XDEV | FTS_NON_RECURSIVE);
assert(result != NULL);
fts_errors = 0; /* ensure a fresh start */
@@ -886,6 +891,9 @@ do_fts(int nargs, awk_value_t *result, struct awk_ext_func *unused)
}
flags &= mask; /* turn off anything else */
+ if (flags & FTS_NON_RECURSIVE)
+ flags |= FTS_NOCHDIR;
+
/* make pathvector */
count = path_array->count + 1;
ezalloc(pathvector, char **, count * sizeof(char *), "do_fts");
@@ -900,8 +908,11 @@ do_fts(int nargs, awk_value_t *result, struct awk_ext_func *unused)
assert(clear_array(dest.array_cookie));
/* let's do it! */
- if ((hierarchy = fts_open(pathvector, flags, NULL)) != NULL) {
- process(hierarchy, dest.array_cookie, (flags & FTS_SEEDOT) != 0, (flags & FTS_SKIP) != 0);
+ hierarchy = fts_open(pathvector, flags & ~FTS_NON_RECURSIVE, NULL);
+ if (hierarchy != NULL) {
+ process(hierarchy, dest.array_cookie,
+ (flags & FTS_SEEDOT) != 0,
+ (flags & FTS_NON_RECURSIVE) != 0);
fts_close(hierarchy);
if (fts_errors == 0)
diff --git a/extension/gawkfts.c b/extension/gawkfts.c
index c7fbc17d..2e7ab688 100644
--- a/extension/gawkfts.c
+++ b/extension/gawkfts.c
@@ -228,7 +228,7 @@ fts_open(char * const *argv, int options,
* so that everything about the "current" node is ignored.
*/
if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
- goto mem3;
+ goto mem4;
sp->fts_cur->fts_link = root;
sp->fts_cur->fts_info = FTS_INIT;
@@ -252,6 +252,8 @@ fts_open(char * const *argv, int options,
return (sp);
+mem4: if (sp->fts_array != NULL)
+ free(sp->fts_array);
mem3: fts_lfree(root);
fts_free(parent);
mem2: free(sp->fts_path);
@@ -916,6 +918,7 @@ mem1: saved_errno = errno;
(cur->fts_level == FTS_ROOTLEVEL ?
FCHDIR(sp, sp->fts_rfd) :
fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
+ fts_lfree(head);
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
return (NULL);
diff --git a/extension/readdir.c b/extension/readdir.c
index cc1cd505..fb739754 100644
--- a/extension/readdir.c
+++ b/extension/readdir.c
@@ -144,6 +144,7 @@ get_inode(struct dirent *entry, const char *dirname)
#ifdef __MINGW32__
char fname[PATH_MAX];
HANDLE fh;
+ BOOL ok;
BY_HANDLE_FILE_INFORMATION info;
sprintf(fname, "%s\\%s", dirname, entry->d_name);
@@ -151,7 +152,9 @@ get_inode(struct dirent *entry, const char *dirname)
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (fh == INVALID_HANDLE_VALUE)
return 0;
- if (GetFileInformationByHandle(fh, &info)) {
+ ok = GetFileInformationByHandle(fh, &info);
+ CloseHandle(fh);
+ if (ok) {
long long inode = info.nFileIndexHigh;
inode <<= 32;
diff --git a/extension/rwarray0.c b/extension/rwarray0.c
index 5298bea3..72a376c1 100644
--- a/extension/rwarray0.c
+++ b/extension/rwarray0.c
@@ -425,7 +425,7 @@ read_value(int fd, awk_value_t *value)
if (code == 2) {
awk_array_t array = create_array();
- if (read_array(fd, array) != 0)
+ if (! read_array(fd, array))
return awk_false;
/* hook into value */
diff --git a/io.c b/io.c
index f954d6e3..7c69fcf3 100644
--- a/io.c
+++ b/io.c
@@ -2681,8 +2681,8 @@ gawk_popen(const char *cmd, struct redirect *rp)
close(p[0]);
fatal(_("close of pipe failed: %s"), strerror(errno));
}
-#endif
os_close_on_exec(p[0], cmd, "pipe", "from");
+#endif
if ((BINMODE & BINMODE_INPUT) != 0)
os_setbinmode(p[0], O_BINARY);
rp->iop = iop_alloc(p[0], cmd, 0);
diff --git a/node.c b/node.c
index c99af12a..bcb9a4a5 100644
--- a/node.c
+++ b/node.c
@@ -304,6 +304,7 @@ r_dupnode(NODE *n)
assert(n->type == Node_val);
#ifdef GAWKDEBUG
+ /* Do the same as in awk.h:dupnode(). */
if ((n->flags & MALLOC) != 0) {
n->valref++;
return n;
@@ -496,20 +497,14 @@ void
r_unref(NODE *tmp)
{
#ifdef GAWKDEBUG
- if (tmp == NULL)
+ /* Do the same as in awk.h:unref(). */
+ assert(tmp == NULL || tmp->valref > 0);
+ if (tmp == NULL || --tmp->valref > 0)
return;
- if ((tmp->flags & MALLOC) != 0) {
- if (tmp->valref > 1) {
- tmp->valref--;
- return;
- }
- if ((tmp->flags & STRCUR) != 0)
- efree(tmp->stptr);
- }
-#else
+#endif
+
if ((tmp->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
efree(tmp->stptr);
-#endif
mpfr_unset(tmp);
@@ -615,7 +610,7 @@ parse_escape(const char **string_ptr)
start = *string_ptr;
for (i = j = 0; j < 2; j++) {
/* do outside test to avoid multiple side effects */
- c = *(*string_ptr)++;
+ c = (unsigned char) *(*string_ptr)++;
if (isxdigit(c)) {
i *= 16;
if (isdigit(c))
@@ -629,8 +624,8 @@ parse_escape(const char **string_ptr)
break;
}
}
- if (do_lint && j > 2)
- lintwarn(_("hex escape \\x%.*s of %d characters probably not interpreted the way you expect"), j, start, j);
+ if (do_lint && j == 2 && isxdigit((unsigned char)*(*string_ptr)))
+ lintwarn(_("hex escape \\x%.*s of %d characters probably not interpreted the way you expect"), 3, start, 3);
return i;
case '\\':
case '"':
@@ -1018,7 +1013,7 @@ void init_btowc_cache()
{
int i;
- for (i = 0; i < 255; i++) {
+ for (i = 0; i <= 255; i++) {
btowc_cache[i] = btowc(i);
}
}
diff --git a/test/Gentests b/test/Gentests
index 78833f0f..392cbf2a 100755
--- a/test/Gentests
+++ b/test/Gentests
@@ -16,7 +16,7 @@ BEGIN {
Locale["EN"] = "en_US.UTF-8"
Locale["FR"] = "fr_FR.UTF-8"
Locale["GR"] = "el_GR.iso88597"
- Locale["JA"] = "ja_JP.UTF-8"
+ Locale["JP"] = "ja_JP.UTF-8"
Locale["RU"] = "ru_RU.UTF-8"
}