This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/text.cpp

269 lines
6.0 KiB
C++

/*************************************************************************
* *
* 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
/*
* This file includes the definition of a miscellania of standard predicates
* for yap refering to: Files and GLOBAL_Streams, Simple Input/Output,
*
*/
#include "Yap.h"
#if HAVE_FCNTL_H
/* for O_BINARY and O_TEXT in WIN32 */
#include <fcntl.h>
#endif
#include "Yatom.h"
#include "YapHeap.h"
#include "yapio.h"
#include "eval.h"
// Use C++ classes to implement text conversion
//
#include "utf8.h"
#include <iomanip>
#include <string>
#include <locale>
#include <codecvt>
/// copy the ISO-Latin1 string s
///
/// this done by first initializing and then getting the bytes and converting to UTF-8
size_t readISOLatin1(const char *s, size_t maxlen, char **o, size_t *limit) {
char *new;
size_t max;
if (!alloc_tmp( s, maxlen, o, limit))
return -1;
new = *o;
maxp = new+max;
while (*s || maxlen--) {
// notice that string does not about encodings;
size_t extra;
int32_t ch = *s++;
íf (ch < 128) {
*new = ch;
extra = 1;
} else {
extra = utf8proc_encode_char( ch, new);
}
count++;
if (new+extra> maxp || maxlen == 0) {
break;
}
new += extra;
}
*new++ = '\0';
*limit = count;
return new-*o;
}
size_t readWide(const wchar_t *s, size_t maxlen, char **o, size_t *limit) {
char *new;
size_t max;
if (!alloc_tmp( s, maxlen, o, limit))
return -1;
max = *limit;
memcpy( *o, s, *limit);
if ((int32_t)(sz = utf8proc_reencode(*o, max/sizeof(int32+t), 0)) < 0)
return sz;
*new++ = '\0';
*limit = new-*o;
return sz;
}
size_t readAtom(Atom at, char **o) {
if (IsBlob(at))
return readTerm, (MkAtomTerm(at), o, -1, NULL, -1);
if (IsWideAtom( at ))
return readWide( RepAtom(at)->WStrOfAE , o, -1, NULL, -1);
return readISOLatin1( RepAtom(at)->StrOfAE, o, -1, NULL, -1 );
}
size_t readString(Term t, char **o) {
char *s = StringOfTerm(t);
*o = s;
return strlen( s );
}
size_t readCodes(Term t, size_t maxlen, char **o, size_t *limit) {
char *new;
size_t max;
if (*limit == 0)
* limit = Yap_ListLength(t)*sizeof(int32_t);
if ((int32_t)(*limit) < 0)
return -1;
if (!alloc_tmp( s, maxlen, o, limit))
return -1;
max = *limit;
new = *o;
maxp = new+max;
while (IsPairTerm(t) || maxlen--) {
// notice that string does not about encodings;
size_t extra;
if (IsPairTerm(t)) {
Term hd = HeadOfTerm(t);
if (!IsIntegerTerm(hd))
throw std::range_error;
Int ch = IntegerOfTerm(hd);
if (ch < 0) {
return -1;
}
t = TailOfTerm(t);
íf (ch < 128) {
*new = ch;
extra = 1;
} else {
extra = utf8proc_encode_char( ch, new);
}
} else {
extra = 1;
*new = '\0';
}
count++;
if (new+extra> maxp || maxlen == 0) {
break;
}
new += extra;
}
*new++ = '\0';
*limit = new;
if (t == TermNil) {
*lim = new-*o;
return count;
}
return -1;
}
size_t readChars(Term t, size_t maxlen, char **o, size_t *limit) {
char *new;
size_t max;
if (*limit == 0)
* limit = Yap_ListLength(t)*sizeof(int32_t);
if ((int32_t)(*limit) < 0)
return -1;
if (!alloc_tmp( s, maxlen, o, limit))
return -1;
max = *limit;
new = *o;
maxp = new+max;
while (IsPairTerm(t) || maxlen--) {
// notice that string does not about encodings;
size_t extra;
if (IsPairTerm(t)) {
Term hd = HeadOfTerm(t);
if (!IsAtomTerm(hd))
return -1;
Atom at = AtomOfTerm(hd);
if (IsWideAtom(at)) {
wchar_t *s = RepAtom(at)->WStrOfAE;
if (s[1]) {
return -1;
}
ch = s[0];
} else if (IsBlob(at)) {
return -1;
} else {
char *s = RepAtom(at)->StrOfAE;
if (s[1]) {
return -1;
}
ch = s[0];
}
if (i < 0) {
return -1;
}
t = TailOfTerm(t);
íf (ch < 128) {
*new = ch;
extra = 1;
} else {
extra = utf8proc_encode_char( ch, new);
}
} else {
extra = 1;
*new = '\0';
}
count++;
if (new+extra> maxp || maxlen == 0) {
break;
}
new += extra;
}
*new++ = '\0';
*limit = new;
if (t == TermNil) {
*lim = new-*o;
return count;
}
return -1;
}
readNumber(
/// convert a number
/// again, we add to the empty case
bool getNumber(Term t, char *buf=NULL, size_t sz = 0, size_t *fsz = NULL) {
text = "";
return text.addNumber(t, , flags, buf, sz, fs);
}
/// add a number, that may be an integer, float,
/// big, or rational
/// remember, numbers are in ASCII
bool addNumber(Term t, char *buf=NULL, size_t sz = 0, size_t *fsz = NULL)
{
try {
text =
Yap_TermToString(Term t, NULL, size_t sz, NULL, ENC_UTF8, 0);
} catch(const std::range_error& e) {
Yap_Error(SYSTEM_ERROR, TermNil, "failed to convert the number", s);
return false;
}
}
return true;
}
/// output a term to uTF-8 text.
/// again, we add to the empty case
bool getText(Term t, int flags = 0, char *buf=NULL, size_t sz = 0, size_t *fsz = NULL) {
text = "";
return text.addText( t, flags, buf, sz, fsz);
}
/// add a number, that may be an integer, float,
/// big, or rational
/// remember, numbers are in ASCII
bool addText(Term t, int flags = 0, char *buf=NULL, size_t sz = 0, size_t *fsz = NULL )
{
try {
text =
Yap_TermToString(Term t, buf, sz, fsz, ENC_UTF8, flags);
} catch(const std::range_error& e) {
Yap_Error(SYSTEM_ERROR, TermNil, "failed to convert the number", s);
return false;
}
}
return true;
}