fix broken padding

This commit is contained in:
Vítor Santos Costa 2015-11-11 07:50:12 +00:00
parent e4bcc5e8a2
commit 0b982a72fe
6 changed files with 592 additions and 632 deletions

View File

@ -27,8 +27,6 @@
#define LOCAL_newline LOCAL->newline_
#define REMOTE_newline(wid) REMOTE(wid)->newline_
#define LOCAL_FormatInfo LOCAL->FormatInfo_
#define REMOTE_FormatInfo(wid) REMOTE(wid)->FormatInfo_
#define LOCAL_AtPrompt LOCAL->AtPrompt_
#define REMOTE_AtPrompt(wid) REMOTE(wid)->AtPrompt_
#define LOCAL_Prompt LOCAL->Prompt_

View File

@ -18,7 +18,6 @@ typedef struct worker_local {
bool newline_;
struct format_status* FormatInfo_;
Atom AtPrompt_;
char Prompt_[MAX_PROMPT+1];
encoding_t encoding_;

View File

@ -18,7 +18,6 @@ static void InitWorker(int wid) {
REMOTE_newline(wid) = true;
REMOTE_FormatInfo(wid) = NULL;
REMOTE_AtPrompt(wid) = AtomNil;
REMOTE_encoding(wid) = Yap_DefaultEncoding();

View File

@ -66,7 +66,6 @@ static void RestoreWorker(int wid USES_REGS) {
REMOTE_GlobalArena(wid) = TermToGlobalOrAtomAdjust(REMOTE_GlobalArena(wid));

View File

@ -20,8 +20,6 @@ bool within_print_message =false
//
bool newline =true
struct format_status* FormatInfo =NULL
Atom AtPrompt =AtomNil
char Prompt[MAX_PROMPT+1] void

View File

@ -232,7 +232,6 @@ output is directed to the stream used by format/2.
*/
#include "Yap.h"
#include "Yatom.h"
#include "YapHeap.h"
@ -255,13 +254,12 @@ output is directed to the stream used by format/2.
#endif
#include <windows.h>
#ifndef S_ISDIR
#define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR)
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
#endif
#endif
#include "iopreds.h"
#include "eval.h"
#define FORMAT_MAX_SIZE 1024
typedef struct {
@ -277,39 +275,34 @@ typedef struct format_status {
int padders;
} format_info;
static int
fill(int sno, int n, wchar_t nch)
{
int (* f_putc)(int, wchar_t);
static int fill(int sno, int n, wchar_t nch) {
int (*f_putc)(int, wchar_t);
f_putc = GLOBAL_Stream[sno].stream_wputc;
while (n--)
f_putc(sno, nch);
return nch;
}
static int
f_puts(int sno, char *s, int n)
{
int (* f_putc)(int, wchar_t);
static int f_puts(int sno, char *s, int n) {
int (*f_putc)(int, wchar_t);
f_putc = GLOBAL_Stream[sno].stream_wputc;
while (n--)
f_putc(sno, *s++);
return *s;
}
// uses directly the buffer in the memory stream.
static bool fill_pads(int sno, int nchars, format_info *fg USES_REGS)
{
static bool fill_pads(int sno, int nchars, format_info *fg USES_REGS) {
int nfillers, fill_space, lfill_space;
if (nchars < 0) nchars = 0; /* ignore */
nfillers =fg->padders;
if (nchars < 0)
nchars = 0; /* ignore */
nfillers = fg->padders;
if (fg->padders == 0) {
return fill( sno, nchars, ' ' );
return fill(sno, nchars, ' ');
}
fill_space = nchars/nfillers;
lfill_space = nchars%nfillers;
fill_space = nchars / nfillers;
lfill_space = nchars % nfillers;
pads *padi = fg->pad_entries;
@ -317,9 +310,9 @@ static bool fill_pads(int sno, int nchars, format_info *fg USES_REGS)
if (!fg->padders)
fill_space += lfill_space;
// give remainder to last block.
fill( sno, fill_space, padi->filler);
fill(sno, fill_space, padi->filler);
if (padi->pad) {
f_puts( sno, (char *)padi->pad, padi->len);
f_puts(sno, (char *)padi->pad, padi->len);
free(padi->pad);
padi->pad = NULL;
}
@ -328,15 +321,14 @@ static bool fill_pads(int sno, int nchars, format_info *fg USES_REGS)
return true;
}
static int
format_print_str (Int sno, Int size, Int has_size, Term args, int (* f_putc)(int, wchar_t))
{
static int format_print_str(Int sno, Int size, Int has_size, Term args,
int (*f_putc)(int, wchar_t)) {
Term arghd;
if (IsStringTerm(args) ) {
if (IsStringTerm(args)) {
const unsigned char *pt = UStringOfTerm(args);
while(*pt && (!has_size || size > 0)) {
while (*pt && (!has_size || size > 0)) {
utf8proc_int32_t ch;
pt += get_utf8(( unsigned char *)pt, &ch);
pt += get_utf8((unsigned char *)pt, &ch);
f_putc(sno, ch);
}
} else {
@ -346,64 +338,57 @@ format_print_str (Int sno, Int size, Int has_size, Term args, int (* f_putc)(int
return FALSE;
} else if (args == TermNil) {
return TRUE;
}
else if (!IsPairTerm (args)) {
} else if (!IsPairTerm(args)) {
Yap_Error(TYPE_ERROR_LIST, args, "format/2");
return FALSE;
}
arghd = HeadOfTerm (args);
args = TailOfTerm (args);
arghd = HeadOfTerm(args);
args = TailOfTerm(args);
if (IsVarTerm(arghd)) {
Yap_Error(INSTANTIATION_ERROR, arghd, "format/2");
return FALSE;
} else if (!IsIntTerm (arghd)) {
} else if (!IsIntTerm(arghd)) {
Yap_Error(TYPE_ERROR_LIST, arghd, "format/2");
return FALSE;
}
f_putc(sno, (int) IntOfTerm (arghd));
f_putc(sno, (int)IntOfTerm(arghd));
size--;
}
}
return TRUE;
}
typedef enum {
fst_ok,
fst_error,
fst_too_long
} format_cp_res;
typedef enum { fst_ok, fst_error, fst_too_long } format_cp_res;
static format_cp_res
copy_format_string(Term inp, char *out, int max)
{
static format_cp_res copy_format_string(Term inp, char *out, int max) {
int i = 0;
while (inp != TermNil) {
Term hd;
int ch;
if (IsVarTerm(inp)) {
Yap_Error(INSTANTIATION_ERROR,inp,"format/2");
Yap_Error(INSTANTIATION_ERROR, inp, "format/2");
return fst_error;
}
if (!IsPairTerm(inp)) {
Yap_Error(TYPE_ERROR_LIST,inp,"format/2");
Yap_Error(TYPE_ERROR_LIST, inp, "format/2");
return fst_error;
}
hd = HeadOfTerm(inp);
if (IsVarTerm(hd)) {
Yap_Error(INSTANTIATION_ERROR,hd,"format/2");
Yap_Error(INSTANTIATION_ERROR, hd, "format/2");
return fst_error;
}
if (!IsIntTerm(hd)) {
Yap_Error(TYPE_ERROR_INTEGER,hd,"format/2");
Yap_Error(TYPE_ERROR_INTEGER, hd, "format/2");
return fst_error;
}
ch = IntOfTerm(hd);
if (ch < 0) {
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO,hd,"format/2");
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, hd, "format/2");
return fst_error;
}
if (i+1 == max) {
if (i + 1 == max) {
return fst_too_long;
}
/* we've got a character */
@ -418,17 +403,15 @@ copy_format_string(Term inp, char *out, int max)
#define FORMAT_COPY_ARGS_ERROR -1
#define FORMAT_COPY_ARGS_OVERFLOW -2
static Int
format_copy_args(Term args, Term *targs, Int tsz)
{
static Int format_copy_args(Term args, Term *targs, Int tsz) {
Int n = 0;
while (args != TermNil) {
if (IsVarTerm(args)) {
Yap_Error(INSTANTIATION_ERROR,args,"format/2");
Yap_Error(INSTANTIATION_ERROR, args, "format/2");
return FORMAT_COPY_ARGS_ERROR;
}
if (!IsPairTerm(args)) {
Yap_Error(TYPE_ERROR_LIST,args,"format/2");
Yap_Error(TYPE_ERROR_LIST, args, "format/2");
return FORMAT_COPY_ARGS_ERROR;
}
if (n == tsz)
@ -438,13 +421,11 @@ format_copy_args(Term args, Term *targs, Int tsz)
n++;
}
return n;
}
static void
format_clean_up( int sno, const char *fstr, const Term *targs)
{
format_clean_up(int sno, const char *fstr, const Term *targs) {
if (fstr) {
Yap_FreeAtomSpace((void *)fstr);
}
@ -452,9 +433,7 @@ format_clean_up( int sno, const char *fstr, const Term *targs)
Yap_FreeAtomSpace((void *)targs);
}
static Int
fetch_index_from_args(Term t)
{
static Int fetch_index_from_args(Term t) {
Int i;
if (IsVarTerm(t))
@ -467,23 +446,19 @@ fetch_index_from_args(Term t)
return i;
}
static wchar_t
base_dig(Int dig, Int ch)
{
static wchar_t base_dig(Int dig, Int ch) {
if (dig < 10)
return dig+'0';
return dig + '0';
else if (ch == 'r')
return (dig-10)+'a';
return (dig - 10) + 'a';
else /* ch == 'R' */
return (dig-10)+'A';
return (dig - 10) + 'A';
}
#define TMP_STRING_SIZE 1024
static Int
doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
{
static Int doformat(volatile Term otail, volatile Term oargs,
int sno USES_REGS) {
char tmp1[TMP_STRING_SIZE], *tmpbase;
int ch;
Term mytargs[8], *targs;
@ -491,18 +466,16 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
const char *fstr = NULL, *fptr;
Term args;
Term tail;
int (* f_putc)(int, wchar_t);
int (*f_putc)(int, wchar_t);
int osno = 0;
jmp_buf format_botch;
volatile void *old_handler;
volatile int old_pos;
format_info finfo;
unsigned char *bufp;
unsigned char *bufp = NULL;
Term fmod = CurrentModule;
size_t sz;
LOCAL_FormatInfo = &finfo;
finfo.padders = 0;
finfo.format_error = FALSE;
if (GLOBAL_Stream[sno].status & InMemory_Stream_f) {
@ -515,7 +488,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
*HR++ = oargs;
*HR++ = otail;
if (!Yap_growheap(FALSE, LOCAL_Error_Size, NULL)) {
Yap_Error(RESOURCE_ERROR_HEAP,otail,"format/2");
Yap_Error(RESOURCE_ERROR_HEAP, otail, "format/2");
return FALSE;
}
oargs = HR[-2];
@ -530,19 +503,19 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
tail = otail;
targ = 0;
if (IsVarTerm(tail)) {
Yap_Error(INSTANTIATION_ERROR,tail,"format/2");
return(FALSE);
} else if (IsPairTerm (tail)) {
Yap_Error(INSTANTIATION_ERROR, tail, "format/2");
return (FALSE);
} else if (IsPairTerm(tail)) {
int sz = 256;
do {
format_cp_res fr;
char *fstr0;
fstr = fptr = fstr0 = Yap_AllocAtomSpace(sz*sizeof(char));
fstr = fptr = fstr0 = Yap_AllocAtomSpace(sz * sizeof(char));
if ((fr = copy_format_string(tail, fstr0, sz)) == fst_ok)
break;
if (fr == fst_error) return FALSE;
if (fr == fst_error)
return FALSE;
sz += 256;
Yap_FreeCodeSpace(fstr0);
} while (TRUE);
@ -559,8 +532,8 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
return FALSE;
}
while (IsApplTerm(args) && FunctorOfTerm(args) == FunctorModule) {
fmod = ArgOfTerm(1,args);
args = ArgOfTerm(2,args);
fmod = ArgOfTerm(1, args);
args = ArgOfTerm(2, args);
if (IsVarTerm(fmod)) {
Yap_Error(INSTANTIATION_ERROR, fmod, "format/2");
return FALSE;
@ -587,7 +560,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
Yap_FreeCodeSpace((char *)targs);
}
tsz += 16;
targs = (Term *)Yap_AllocAtomSpace(tsz*sizeof(Term));
targs = (Term *)Yap_AllocAtomSpace(tsz * sizeof(Term));
} else {
break;
}
@ -600,7 +573,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
tnum = 0;
targs = mytargs;
}
finfo.format_error = FALSE;
finfo.format_error = false;
f_putc = GLOBAL_Stream[sno].stream_wputc;
while ((ch = *fptr++)) {
@ -614,7 +587,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
if (ch == '*') {
ch = *fptr++;
has_repeats = TRUE;
if (targ > tnum-1) {
if (targ > tnum - 1) {
goto do_consistency_error;
}
repeats = fetch_index_from_args(targs[targ++]);
@ -629,14 +602,14 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
has_repeats = TRUE;
repeats = 0;
while (ch >= '0' && ch <= '9') {
repeats = repeats*10+(ch-'0');
repeats = repeats * 10 + (ch - '0');
ch = *fptr++;
}
}
switch (ch) {
case 'a':
/* print an atom */
if (has_repeats || targ > tnum-1)
if (has_repeats || targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
@ -645,15 +618,13 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
goto do_type_atom_error;
yhandle_t sl = Yap_StartSlots();
// stream is already locked.
Yap_plwrite (t, GLOBAL_Stream+sno, 0, Handle_vars_f|To_heap_f, 1200);
Yap_plwrite(t, GLOBAL_Stream + sno, 0, Handle_vars_f | To_heap_f, 1200);
Yap_CloseSlots(sl);
LOCAL_FormatInfo = &finfo;
break;
case 'c':
{
case 'c': {
Int nch, i;
if (targ > tnum-1)
if (targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
@ -673,12 +644,11 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
case 'E':
case 'f':
case 'g':
case 'G':
{
case 'G': {
Float fl;
char *ptr;
if (targ > tnum-1)
if (targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
@ -698,24 +668,25 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
repeats = 6;
tmp1[0] = '%';
tmp1[1] = '.';
ptr = tmp1+2;
ptr = tmp1 + 2;
#if HAVE_SNPRINTF
snprintf(ptr,256-5,"%d",repeats);
snprintf(ptr, 256 - 5, "%d", repeats);
#else
sprintf(ptr,"%d",repeats);
sprintf(ptr, "%d", repeats);
#endif
while (*ptr) ptr++;
while (*ptr)
ptr++;
ptr[0] = ch;
ptr[1] = '\0';
{
char *tmp2;
if (!(tmp2 = Yap_AllocCodeSpace(repeats+10))) {
if (!(tmp2 = Yap_AllocCodeSpace(repeats + 10))) {
goto do_type_int_error;
}
#if HAVE_SNPRINTF
snprintf (tmp2, repeats+10, tmp1, fl);
snprintf(tmp2, repeats + 10, tmp1, fl);
#else
sprintf (tmp2, tmp1, fl);
sprintf(tmp2, tmp1, fl);
#endif
ptr = tmp2;
while ((ch = *ptr++) != 0)
@ -726,7 +697,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
case 'd':
case 'D':
/* print a decimal, using weird . stuff */
if (targ > tnum-1)
if (targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
@ -752,14 +723,16 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
sprintf(tmp1, "%ld", (long int)il);
#endif
siz = strlen(tmp1);
if (il < 0) siz--;
if (il < 0)
siz--;
#ifdef HAVE_GMP
} else if (IsBigIntTerm(t) && RepAppl(t)[1] == BIG_INT) {
char *res;
tmpbase = tmp1;
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, 10))) {
while (
!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, 10))) {
if (tmpbase == tmp1) {
tmpbase = NULL;
} else {
@ -777,39 +750,37 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
}
if (tmpbase[0] == '-') {
f_putc(sno, (int) '-');
f_putc(sno, (int)'-');
ptr++;
}
if (ch == 'D') {
int first = TRUE;
while (siz > repeats) {
if ((siz-repeats) % 3 == 0 &&
!first) {
f_putc(sno, (int) ',');
if ((siz - repeats) % 3 == 0 && !first) {
f_putc(sno, (int)',');
}
f_putc(sno, (int) (*ptr++));
f_putc(sno, (int)(*ptr++));
first = FALSE;
siz--;
}
} else {
while (siz > repeats) {
f_putc(sno, (int) (*ptr++));
f_putc(sno, (int)(*ptr++));
siz--;
}
}
if (repeats) {
if (ptr == tmpbase ||
ptr[-1] == '-') {
f_putc(sno, (int) '0');
if (ptr == tmpbase || ptr[-1] == '-') {
f_putc(sno, (int)'0');
}
f_putc(sno, (int) '.');
f_putc(sno, (int)'.');
while (repeats > siz) {
f_putc(sno, (int) '0');
f_putc(sno, (int)'0');
repeats--;
}
while (repeats) {
f_putc(sno, (int) (*ptr++));
f_putc(sno, (int)(*ptr++));
repeats--;
}
}
@ -817,14 +788,13 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
free(tmpbase);
break;
case 'r':
case 'R':
{
case 'R': {
Int numb, radix;
UInt divfactor = 1, size = 1, i;
wchar_t och;
/* print a decimal, using weird . stuff */
if (targ > tnum-1)
if (targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
@ -840,7 +810,8 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
char *pt, *res;
tmpbase = tmp1;
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, radix))) {
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE,
radix))) {
if (tmpbase == tmp1) {
tmpbase = NULL;
} else {
@ -862,14 +833,14 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
numb = IntegerOfTerm(t);
if (numb < 0) {
numb = -numb;
f_putc(sno, (int) '-');
f_putc(sno, (int)'-');
}
while (numb/divfactor >= radix) {
while (numb / divfactor >= radix) {
divfactor *= radix;
size++;
}
for (i = 1; i < size; i++) {
Int dig = numb/divfactor;
Int dig = numb / divfactor;
och = base_dig(dig, ch);
f_putc(sno, och);
numb %= divfactor;
@ -880,28 +851,28 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
break;
}
case 's':
if (targ > tnum-1)
if (targ > tnum - 1)
goto do_consistency_error;
t = targs[targ++];
if (IsVarTerm(t))
goto do_instantiation_error;
if (!format_print_str (sno, repeats, has_repeats, t, f_putc)) {
if (!format_print_str(sno, repeats, has_repeats, t, f_putc)) {
goto do_default_error;
}
break;
case 'i':
if (targ > tnum-1 || has_repeats)
if (targ > tnum - 1 || has_repeats)
goto do_consistency_error;
targ++;
break;
case 'k':
if (targ > tnum-1 || has_repeats)
if (targ > tnum - 1 || has_repeats)
goto do_consistency_error;
t = targs[targ++];
yhandle_t sl = Yap_StartSlots();
Yap_plwrite (t, GLOBAL_Stream+sno,0, Quote_illegal_f|Ignore_ops_f|To_heap_f , 1200);
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
Quote_illegal_f | Ignore_ops_f | To_heap_f, 1200);
Yap_CloseSlots(sl);
LOCAL_FormatInfo = &finfo;
break;
case '@':
t = targs[targ++];
@ -920,25 +891,26 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
sl2 = Yap_InitSlot(ta[1]);
ts = Yap_MkApplTerm(FunctorGFormatAt, 2, ta);
res = Yap_execute_goal(ts, 0, CurrentModule, true);
LOCAL_FormatInfo = &finfo;
args = Yap_GetFromSlot(sl);
if (EX) goto ex_handler;
if (!res) return FALSE;
if (EX)
goto ex_handler;
if (!res)
return FALSE;
ts = Yap_GetFromSlot(sl2);
Yap_CloseSlots(sl0);
if (!format_print_str (sno, repeats, has_repeats, ts, f_putc)) {
if (!format_print_str(sno, repeats, has_repeats, ts, f_putc)) {
goto do_default_error;
}
}
break;
case 'p':
if (targ > tnum-1 || has_repeats)
if (targ > tnum - 1 || has_repeats)
goto do_consistency_error;
t = targs[targ++];
{
Int sl = Yap_InitSlot(args);
Yap_plwrite(t, GLOBAL_Stream+sno, 0, Handle_vars_f|Use_portray_f|To_heap_f, 1200);
LOCAL_FormatInfo = &finfo;
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
Handle_vars_f | Use_portray_f | To_heap_f, 1200);
args = Yap_GetFromSlot(sl);
Yap_CloseSlots(sl);
}
@ -956,39 +928,39 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
if (GLOBAL_Stream[sno].status & InMemory_Stream_f) {
GLOBAL_Stream[sno].u.mem_string.error_handler = old_handler;
}
format_clean_up( sno, (char *)fstr, targs);
format_clean_up(sno, (char *)fstr, targs);
Yap_JumpToEnv(ball);
return FALSE;
}
break;
case 'q':
if (targ > tnum-1 || has_repeats)
if (targ > tnum - 1 || has_repeats)
goto do_consistency_error;
t = targs[targ++];
yhandle_t sl0 = Yap_StartSlots();
Yap_plwrite (t, GLOBAL_Stream+sno, 0, Handle_vars_f|Quote_illegal_f|To_heap_f, 1200);
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
Handle_vars_f | Quote_illegal_f | To_heap_f, 1200);
Yap_CloseSlots(sl0);
LOCAL_FormatInfo = &finfo;
break;
case 'w':
if (targ > tnum-1 || has_repeats)
if (targ > tnum - 1 || has_repeats)
goto do_consistency_error;
t = targs[targ++];
yhandle_t slf = Yap_StartSlots();
Yap_plwrite (t, GLOBAL_Stream+sno, 0, Handle_vars_f|To_heap_f, 1200);
Yap_plwrite(t, GLOBAL_Stream + sno, 0, Handle_vars_f | To_heap_f,
1200);
Yap_CloseSlots(slf);
LOCAL_FormatInfo = &finfo;
break;
case '~':
if (has_repeats)
goto do_consistency_error;
f_putc(sno, (int) '~');
f_putc(sno, (int)'~');
break;
case 'n':
if (!has_repeats)
repeats = 1;
while (repeats--) {
f_putc(sno, (int) '\n');
f_putc(sno, (int)'\n');
}
finfo.padders = 0;
break;
@ -1015,7 +987,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
}
repeats -= GLOBAL_Stream[sno].linepos;
repeats = (repeats < 0 ? 0 : repeats);
fill_pads( sno, repeats, &finfo PASS_REGS);
fill_pads(sno, repeats, &finfo PASS_REGS);
break;
case '+':
if (osno) {
@ -1024,17 +996,17 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
osno = 0;
}
repeats = (repeats < 0 ? 0 : repeats);
fill_pads( sno, repeats, &finfo PASS_REGS);
fill_pads(sno, repeats, &finfo PASS_REGS);
break;
case 't':
{
case 't': {
int nsno;
finfo.pad_entries[finfo.padders].len = sz;
finfo.pad_entries[finfo.padders].pad = (char *)bufp;
bufp = NULL;
sz = 0;
nsno = Yap_open_buf_write_stream((char *)bufp, sz, &GLOBAL_Stream[sno].encoding, 0);
nsno = Yap_open_buf_write_stream((char *)bufp, sz,
&GLOBAL_Stream[sno].encoding, 0);
if (osno) {
GLOBAL_Stream[nsno].linepos = GLOBAL_Stream[sno].linepos;
GLOBAL_Stream[nsno].linecount = GLOBAL_Stream[sno].linecount;
@ -1047,12 +1019,12 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
GLOBAL_Stream[nsno].charcount = GLOBAL_Stream[sno].charcount;
}
sno = nsno;
finfo.padders++;
finfo.pad_entries[finfo.padders].start = GLOBAL_Stream[sno].linepos;
if (!has_repeats)
finfo.pad_entries[finfo.padders].filler = ' ';
else
finfo.pad_entries[finfo.padders].filler = fptr[-2];
finfo.padders++;
}
break;
do_instantiation_error:
@ -1086,12 +1058,14 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
Term ta[2];
ta[0] = otail;
ta[1] = oargs;
Yap_Error(LOCAL_Error_TYPE, Yap_MkApplTerm(Yap_MkFunctor(AtomFormat,2),2,ta), "format/2");
Yap_Error(LOCAL_Error_TYPE,
Yap_MkApplTerm(Yap_MkFunctor(AtomFormat, 2), 2, ta),
"format/2");
}
if (GLOBAL_Stream[sno].status & InMemory_Stream_f) {
GLOBAL_Stream[sno].u.mem_string.error_handler = old_handler;
}
format_clean_up( sno, fstr, targs);
format_clean_up(sno, fstr, targs);
LOCAL_Error_TYPE = YAP_NO_ERROR;
return FALSE;
}
@ -1117,7 +1091,7 @@ doformat(volatile Term otail, volatile Term oargs, int sno USES_REGS)
if (GLOBAL_Stream[sno].status & InMemory_Stream_f) {
GLOBAL_Stream[sno].u.mem_string.error_handler = old_handler;
}
format_clean_up( sno, fstr, targs);
format_clean_up(sno, fstr, targs);
return (TRUE);
}
@ -1141,29 +1115,35 @@ X = [104, 101, 108, 108, 111]
~~~~~
+ A Stream handle or alias
Temporary switch current output to the given stream. Redirection using with_output_to/2 guarantees the original output is restored, also if Goal fails or raises an exception. See also call_cleanup/2.
Temporary switch current output to the given stream. Redirection using
with_output_to/2 guarantees the original output is restored, also if Goal fails
or raises an exception. See also call_cleanup/2.
+ atom(- _Atom_)
Create an atom from the emitted characters.
Applications should generally avoid creating atoms by breaking and
concatenating other atoms as the creation of large numbers of
intermediate atoms puts pressure on the atom table and the data-base. This may lead to collisions in the hash tables used to implement atoms, and may result in frequent calls to the garbage collector. In multi-threaded applications, access to the atom table is controlled by locks. This predicate supports creating the therms by expanding
intermediate atoms puts pressure on the atom table and the data-base. This may
lead to collisions in the hash tables used to implement atoms, and may result in
frequent calls to the garbage collector. In multi-threaded applications, access
to the atom table is controlled by locks. This predicate supports creating the
therms by expanding
difference-list.
+ string(- _String_)
Create a string-object, notice that strings are atomic objects.
+ codes(- _Codes_)
Create a list of character codes from the emitted characters, similar to atom_codes/2.
Create a list of character codes from the emitted characters, similar to
atom_codes/2.
+ codes(- _Codes_, - _Tail_)
Create a list of character codes as a difference-list.
+ chars(- _Chars_)
Create a list of one-character-atoms codes from the emitted characters, similar to atom_chars/2.
Create a list of one-character-atoms codes from the emitted characters, similar
to atom_chars/2.
+ chars(- _Chars_, - _Tail_)
Create a list of one-character-atoms as a difference-list.
*/
static Int
with_output_to( USES_REGS1 )
{
static Int with_output_to(USES_REGS1) {
int old_out = LOCAL_c_output_stream;
int output_stream;
Term tin = Deref(ARG1);
@ -1171,25 +1151,22 @@ with_output_to( USES_REGS1 )
bool out;
bool mem_stream = false;
if (IsVarTerm(tin)) {
Yap_Error(INSTANTIATION_ERROR,tin,"with_output_to/3");
Yap_Error(INSTANTIATION_ERROR, tin, "with_output_to/3");
return false;
}
if (IsApplTerm(tin) &&
(f = FunctorOfTerm(tin)) &&
(f == FunctorAtom || f == FunctorString ||
f == FunctorCodes1 || f == FunctorCodes ||
f == FunctorChars1 || f == FunctorChars) )
{
output_stream = Yap_OpenBufWriteStream( PASS_REGS1);
if (IsApplTerm(tin) && (f = FunctorOfTerm(tin)) &&
(f == FunctorAtom || f == FunctorString || f == FunctorCodes1 ||
f == FunctorCodes || f == FunctorChars1 || f == FunctorChars)) {
output_stream = Yap_OpenBufWriteStream(PASS_REGS1);
} else {
/* needs to change LOCAL_c_output_stream for write */
output_stream = Yap_CheckStream (ARG1, Output_Stream_f, "format/3");
output_stream = Yap_CheckStream(ARG1, Output_Stream_f, "format/3");
}
if (output_stream == -1) {
return false;
}
UNLOCK(GLOBAL_Stream[output_stream].streamlock);
out = Yap_Execute( Deref(ARG2) PASS_REGS);
out = Yap_Execute(Deref(ARG2) PASS_REGS);
LOCK(GLOBAL_Stream[output_stream].streamlock);
LOCAL_c_output_stream = old_out;
if (mem_stream) {
@ -1202,11 +1179,11 @@ with_output_to( USES_REGS1 )
if (f == FunctorAtom) {
tat = MkAtomTerm(Yap_LookupAtom(s));
} else if (f == FunctorCodes) {
tat = Yap_CharsToDiffListOfCodes(s, ArgOfTerm(2,inp), enc PASS_REGS);
tat = Yap_CharsToDiffListOfCodes(s, ArgOfTerm(2, inp), enc PASS_REGS);
} else if (f == FunctorCodes1) {
tat = Yap_CharsToListOfCodes(s, enc PASS_REGS);
} else if (f == FunctorChars) {
tat = Yap_CharsToDiffListOfAtoms(s, ArgOfTerm(2,inp), enc PASS_REGS);
tat = Yap_CharsToDiffListOfAtoms(s, ArgOfTerm(2, inp), enc PASS_REGS);
} else if (f == FunctorChars1) {
tat = Yap_CharsToListOfAtoms(s, enc PASS_REGS);
} else if (f == FunctorString1) {
@ -1214,34 +1191,30 @@ with_output_to( USES_REGS1 )
} else {
return false;
}
out = Yap_unify(tat,ArgOfTerm(1,inp));
out = Yap_unify(tat, ArgOfTerm(1, inp));
}
}
return out;
}
static Int
format(Term tout, Term tf, Term tas USES_REGS)
{
static Int format(Term tout, Term tf, Term tas USES_REGS) {
bool mem_stream = false;
int output_stream;
Functor f;
Int out;
if (IsVarTerm(tout)) {
Yap_Error(INSTANTIATION_ERROR,tout,"format/3");
Yap_Error(INSTANTIATION_ERROR, tout, "format/3");
return false;
}
if (IsApplTerm(tout) &&
(f = FunctorOfTerm(tout)) &&
(f == FunctorAtom || f == FunctorString1 ||
f == FunctorCodes1 || f == FunctorCodes ||
f == FunctorChars1 || f == FunctorChars) ) {
output_stream = Yap_OpenBufWriteStream( PASS_REGS1);
if (IsApplTerm(tout) && (f = FunctorOfTerm(tout)) &&
(f == FunctorAtom || f == FunctorString1 || f == FunctorCodes1 ||
f == FunctorCodes || f == FunctorChars1 || f == FunctorChars)) {
output_stream = Yap_OpenBufWriteStream(PASS_REGS1);
mem_stream = true;
} else {
/* needs to change LOCAL_c_output_stream for write */
output_stream = Yap_CheckStream (tout, Output_Stream_f, "format/3");
output_stream = Yap_CheckStream(tout, Output_Stream_f, "format/3");
}
if (output_stream == -1) {
return false;
@ -1249,9 +1222,9 @@ format(Term tout, Term tf, Term tas USES_REGS)
} else {
yhandle_t sls = Yap_CurrentSlot(PASS_REGS1);
out = doformat(tf,tas,output_stream PASS_REGS);
out = doformat(tf, tas, output_stream PASS_REGS);
Yap_CloseSlots( sls );
Yap_CloseSlots(sls);
UNLOCK(GLOBAL_Stream[output_stream].streamlock);
}
if (mem_stream) {
@ -1264,19 +1237,19 @@ format(Term tout, Term tf, Term tas USES_REGS)
if (f == FunctorAtom) {
tat = MkAtomTerm(Yap_LookupAtom(s));
} else if (f == FunctorCodes) {
tat = Yap_CharsToDiffListOfCodes(s, ArgOfTerm(2,inp), enc PASS_REGS);
tat = Yap_CharsToDiffListOfCodes(s, ArgOfTerm(2, inp), enc PASS_REGS);
} else if (f == FunctorCodes1) {
tat = Yap_CharsToListOfCodes(s, enc PASS_REGS);
} else if (f == FunctorChars) {
tat = Yap_CharsToDiffListOfAtoms(s, ArgOfTerm(2,inp), enc PASS_REGS);
tat = Yap_CharsToDiffListOfAtoms(s, ArgOfTerm(2, inp), enc PASS_REGS);
} else if (f == FunctorChars1) {
tat = Yap_CharsToListOfAtoms(s, enc PASS_REGS);
} else if (f == FunctorString1) {
tat = Yap_CharsToString (s, enc PASS_REGS);
tat = Yap_CharsToString(s, enc PASS_REGS);
} else {
return false;
}
if (!Yap_unify(tat,ArgOfTerm(1,inp)))
if (!Yap_unify(tat, ArgOfTerm(1, inp)))
return FALSE;
}
Yap_CloseStream(output_stream);
@ -1288,33 +1261,27 @@ format(Term tout, Term tf, Term tas USES_REGS)
*
* Print formatted output to the current output stream.
*/
static Int
format2( USES_REGS1 )
{ /* 'format'(Stream,Control,Args) */
static Int format2(USES_REGS1) { /* 'format'(Stream,Control,Args) */
Int res;
res = doformat( Deref(ARG1),Deref(ARG2), LOCAL_c_output_stream PASS_REGS);
res = doformat(Deref(ARG1), Deref(ARG2), LOCAL_c_output_stream PASS_REGS);
return res;
}
/** @pred format(+_Stream_+ _T_, :ListWithArguments)
*
* Print formatted output to the stream _Stream_.
*/
static Int
format3( USES_REGS1 )
{
static Int format3(USES_REGS1) {
Int res;
res = format(Deref(ARG1), Deref(ARG2),Deref(ARG3) PASS_REGS);
res = format(Deref(ARG1), Deref(ARG2), Deref(ARG3) PASS_REGS);
return res;
}
void
Yap_InitFormat(void)
{
Yap_InitCPred ("format", 2, format2, SyncPredFlag);
Yap_InitCPred ("format", 3, format3, SyncPredFlag);
Yap_InitCPred ("with_output_to", 2, with_output_to, SyncPredFlag);
void Yap_InitFormat(void) {
Yap_InitCPred("format", 2, format2, SyncPredFlag);
Yap_InitCPred("format", 3, format3, SyncPredFlag);
Yap_InitCPred("with_output_to", 2, with_output_to, SyncPredFlag);
}
/// @}