generic tmp alloc fixes.

This commit is contained in:
Vitor Santos Costa
2017-10-02 08:58:51 +01:00
parent c06dd92761
commit 9f1ef65ff5
15 changed files with 341 additions and 307 deletions

View File

@@ -1,19 +1,19 @@
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: iopreds.c *
* Last rev: 5/2/88 *
* mods: *
* comments: Input/Output C implemented predicates *
* *
*************************************************************************/
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: iopreds.c *
* Last rev: 5/2/88 *
* mods: *
* comments: Input/Output C implemented predicates *
* *
*************************************************************************/
#ifdef SCCS
static char SccsId[] = "%W% %G%";
#endif
@@ -32,101 +32,124 @@ static char SccsId[] = "%W% %G%";
#define SYSTEM_STAT stat
#endif
bool Yap_GetFileName(Term t, char *buf, size_t len, encoding_t enc) {
while (IsApplTerm(t) && FunctorOfTerm(t) == FunctorSlash) {
if (!Yap_GetFileName(ArgOfTerm(1, t), buf, len, enc))
return false;
size_t szl = strlen(buf);
buf += szl;
*buf++ = '/';
t = ArgOfTerm(2, t);
len -= (szl + 1);
const char *Yap_GetFileName(Term t USES_REGS) {
char *buf = Malloc(YAP_FILENAME_MAX + 1);
if (IsApplTerm(t) && FunctorOfTerm(t) == FunctorSlash) {
snprintf(buf, YAP_FILENAME_MAX, "%s/%s", Yap_GetFileName(ArgOfTerm(1, t)),
Yap_GetFileName(ArgOfTerm(1, t)));
}
return Yap_TextTermToText(t, buf, enc);
return Yap_TextTermToText(t PASS_REGS);
}
/**
* @pred file_name_extension( ? BaseFile, ?Extension, ?FullNameO)
*
* Relate a file name with an extension. The extension is the filename's suffix
* and indicates the kind of the file.
*
* The predicate can be used to:
* - Given __FullName__, extract the extension as _Extension_, and the remainder
* as _BaseFile_. - Given _BaseFile_ and _?Extension_ obtain a _FullNameO_.
* ~~~~
* ~~~~
* Notice that:
* + if no suffix is found, file_name_extension/3 generates the empty
* suffu]kx, `''`. + the extension does not include the `,` separator; + the
* suffix may be longer thsn 3 characters + case should not matter in Windows
* and MacOS + paths may not correspond to valid file names.
*
* @return G
*/
static Int file_name_extension(USES_REGS1) {
Term t1 = Deref(ARG1);
Term t2 = Deref(ARG2);
Term t1;
Term t2;
Term t3 = Deref(ARG3);
char f[YAP_FILENAME_MAX + 1];
#if __APPLE__ || _WIN32
bool lowcase = true;
#endif
if (!IsVarTerm((t3))) {
char *f2;
if (!Yap_GetFileName(t3, f, YAP_FILENAME_MAX, ENC_ISO_UTF8)) {
int l = push_text_stack();
if (!IsVarTerm(t3)) {
// full path is given.
const char *f = Yap_GetFileName(t3);
const char *ext;
char *base;
bool rc = true;
seq_type_t typ = Yap_TextType(t3);
if (!f) {
pop_text_stack(l);
return false;
}
char *pts = strrchr(f, '/');
#if WIN32_
char *pts1 = strrchr(f, '\\');
if (pts11 > pts)
pts = pts1;
#endif
char *ss = strrchr(f, '.');
if (pts > ss) {
ss = f + strlen(f);
} else if (ss == NULL) {
ss = "";
size_t len_b = strlen(f), lenb_b, lene_b;
char *candidate = strrchr(f, '.');
char *file = strrchr(f, '/');
if (candidate && file && candidate > file) {
lenb_b = candidate - f, lene_b = (f + len_b) - (candidate + 1);
ext = candidate + 1;
} else {
ss++;
lenb_b = len_b;
lene_b = 0;
ext = "";
}
if (IsVarTerm(t2)) {
Term t = Yap_MkTextTerm(ss, ENC_ISO_UTF8, t3);
Yap_unify(t2, t);
base = Malloc(lenb_b + 1);
memcpy(base, f, lenb_b);
base[lenb_b] = '\0';
if (IsVarTerm(t1 = Deref(ARG1))) {
// should always succeed
rc = Yap_unify(t1, Yap_MkTextTerm(base, typ));
} else {
f2 = ss + (strlen(ss) + 1);
if (!Yap_TextTermToText(t2, f2, ENC_ISO_UTF8))
return false;
char *f_a = (char *)Yap_GetFileName(t1 PASS_REGS);
#if __APPLE__ || _WIN32
Yap_OverwriteUTF8BufferToLowCase(f2);
lowcase = true;
rc = strcasecmp(f_a, base) == 0;
#else
rc = strcmp(f_a, base) == 0
#endif
}
if (rc) {
if (IsVarTerm(t2 = Deref(ARG2))) {
// should always succeed
rc = Yap_unify(t2, Yap_MkTextTerm(ext, typ));
} else {
char *f_a = (char *)Yap_TextTermToText(t2 PASS_REGS);
if (f_a[0] == '.') {
f_a += 1;
}
#if __APPLE__ || _WIN32
rc = strcasecmp(f_a, ext) == 0;
#else
rc = strcmp(f_a, ext) == 0
#endif
if (strcmp(f2, ss) != 0 && (ss > f && strcmp(f2, ss - 1) != 0)) {
return false;
}
}
if (f[0] && ss[0] && ss[0] != '.') {
ss[-1] = '\0';
}
if (IsVarTerm(t1)) {
Term t = Yap_MkTextTerm(f, ENC_ISO_UTF8, t3);
Yap_unify(t1, t);
} else {
char f1[YAP_FILENAME_MAX + 1];
#if __APPLE || _WIN32
Yap_OverwriteUTF8BufferToLowCase(f);
#endif
if (!Yap_GetFileName(t2, f1, YAP_FILENAME_MAX, ENC_ISO_UTF8))
return false;
#if __APPLE__ || _WIN32
if (!lowcase)
Yap_OverwriteUTF8BufferToLowCase(f2);
#endif
if (strcmp(f1, f) != 0) {
return false;
}
}
return true;
pop_text_stack(l);
return rc;
} else {
const char *f;
char *f2;
if (!Yap_TextTermToText(t1, f, ENC_ISO_UTF8)) {
seq_type_t typ, typ1 = Yap_TextType((t1 = Deref(ARG1))),
typ2 = Yap_TextType((t2 = Deref(ARG2)));
if (typ1 == typ2) {
typ = typ1;
} else if (typ1 == YAP_STRING_ATOM || typ2 == YAP_STRING_ATOM) {
typ = YAP_STRING_ATOM;
} else {
typ = YAP_STRING_STRING;
}
if (!(f = Yap_TextTermToText(t1 PASS_REGS))) {
pop_text_stack(l);
return false;
}
f2 = f + strlen(f);
if (!Yap_TextTermToText(t2, f2, ENC_ISO_UTF8)) {
if (!(f2 = (char *)Yap_TextTermToText(t2 PASS_REGS))) {
pop_text_stack(l);
return false;
}
if (f2[0] != '.') {
memmove(f2 + 1, f2, strlen(f2) + 1);
f2[0] = '.';
if (f2[0] == '.') {
f2++;
}
Term t = Yap_MkTextTerm(f, ENC_ISO_UTF8, t1);
if (!t)
return false;
return Yap_unify(t, t3);
size_t lenb_b = strlen(f);
char *o = Realloc((void *)f, lenb_b + strlen(f2) + 2);
o[lenb_b] = '.';
o += lenb_b + 1;
pop_text_stack(l);
return strcpy(o, f2) && (t3 = Yap_MkTextTerm(o, typ)) &&
Yap_unify(t3, ARG3);
}
}
@@ -458,15 +481,15 @@ static Int is_absolute_file_name(USES_REGS1) { /* file_base_name(Stream,N) */
return false;
}
int l = push_text_stack();
const char *buf = Yap_TextTermToText(t, NULL, LOCAL_encoding);
const char *buf = Yap_TextTermToText(t PASS_REGS);
if (buf) {
rc = Yap_IsAbsolutePath(buf);
} else {
at = AtomOfTerm(t);
at = AtomOfTerm(t);
#if _WIN32
rc = PathIsRelative(RepAtom(at)->StrOfAE);
rc = PathIsRelative(RepAtom(at)->StrOfAE);
#else
rc = RepAtom(at)->StrOfAE[0] == '/';
rc = RepAtom(at)->StrOfAE[0] == '/';
#endif
}
pop_text_stack(l);
@@ -523,6 +546,10 @@ static Int file_directory_name(USES_REGS1) { /* file_directory_name(Stream,N) */
if (Yap_dir_separator((int)c[i]))
break;
}
if (i == 0) {
s[0] = '.';
i = 1;
}
s[i] = '\0';
#endif
return Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(s)));
@@ -586,13 +613,12 @@ static Int same_file(USES_REGS1) {
}
out = (b1->st_ino == b2->st_ino
#ifdef __LCC__
&&
memcmp((const void *)&(b1->st_dev), (const void *)&(b2->st_dev),
sizeof(buf1.st_dev)) == 0
&& memcmp((const void *)&(b1->st_dev), (const void *)&(b2->st_dev),
sizeof(buf1.st_dev)) == 0
#else
&& b1->st_dev == b2->st_dev
#endif
);
);
return out;
}
#else