YAP 7.1.0
alias.c
Go to the documentation of this file.
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: alias.c *
12* Last rev: 5/2/88 *
13* mods: *
14* comments: Input/Output C implemented predicates *
15* *
16*************************************************************************/
17#ifdef SCCS
18static char SccsId[] = "%W% %G%";
19#endif
20
59#include "sysbits.h"
60#if HAVE_FCNTL_H
61/* for O_BINARY and O_TEXT in WIN32 */
62#include <fcntl.h>
63#endif
64#include "Yatom.h"
65#include "YapHeap.h"
66#include "yapio.h"
67#include "YapEval.h"
68#include "YapText.h"
69#include <stdlib.h>
70#if HAVE_STDARG_H
71#include <stdarg.h>
72#endif
73#ifdef HAVE_UNISTD_H
74#include <unistd.h>
75#endif
76#if HAVE_CTYPE_H
77#include <ctype.h>
78#endif
79#if HAVE_WCTYPE_H
80#include <wctype.h>
81#endif
82#if HAVE_SYS_PARAM_H
83#include <sys/param.h>
84#endif
85#if HAVE_SYS_TIME_H
86#include <sys/time.h>
87#endif
88#if HAVE_SYS_TYPES_H
89#include <sys/types.h>
90#endif
91#ifdef HAVE_SYS_STAT_H
92#include <sys/stat.h>
93#endif
94#if HAVE_SYS_SELECT_H && !_MSC_VER && !defined(__MINGW32__)
95#include <sys/select.h>
96#endif
97#if HAVE_STRING_H
98#include <string.h>
99#endif
100#if HAVE_SIGNAL_H
101#include <signal.h>
102#endif
103#ifdef _WIN32
104// WIN32 API support
105#if HAVE_IO_H
106/* Windows */
107#include <io.h>
108#endif
109#endif
110
111#if _MSC_VER || defined(__MINGW32__)
112#if HAVE_SOCKET
113#include <winsock2.h>
114#endif
115#include <windows.h>
116#endif
117#include "iopreds.h"
118
119#if _MSC_VER || defined(__MINGW32__)
120#define SYSTEM_STAT _stat
121#else
122#define SYSTEM_STAT stat
123#endif
124
126extern struct AliasDescS* GLOBAL_FileAliases;
127extern int GLOBAL_NOfFileAliases;
128extern int GLOBAL_SzOfFileAliases;
129
130 static Atom FetchAlias (int sno);
131static bool ExistsAliasForStream (int sno, Atom al);
132
143static Int add_alias_to_stream (USES_REGS1)
144{
145 Term tname = Deref(ARG1);
146 Term tstream = Deref(ARG2);
147 Atom at;
148 Int sno;
149
150 if (IsVarTerm(tname)) {
151 Yap_Error(INSTANTIATION_ERROR, tname, "$add_alias_to_stream");
152 return (FALSE);
153 } else if (!IsAtomTerm (tname)) {
154 Yap_Error(TYPE_ERROR_ATOM, tname, "$add_alias_to_stream");
155 return (FALSE);
156 }
157 if (IsVarTerm(tstream)) {
158 Yap_Error(INSTANTIATION_ERROR, tstream, "$add_alias_to_stream");
159 return (FALSE);
160 } else if (!IsApplTerm (tstream) || FunctorOfTerm (tstream) != FunctorStream ||
161 !IsIntTerm(ArgOfTerm(1,tstream))) {
162 Yap_Error(DOMAIN_ERROR_STREAM_OR_ALIAS, tstream, "$add_alias_to_stream");
163 return (FALSE);
164 }
165 at = AtomOfTerm(tname);
166 sno = (int)IntOfTerm(ArgOfTerm(1,tstream));
167 if (Yap_AddAlias(at, sno))
168 return(TRUE);
169 /* we could not create the alias, time to close the stream */
170 Yap_CloseStream(sno);
171 Yap_Error(PERMISSION_ERROR_NEW_ALIAS_FOR_STREAM, tname, "open/3");
172 return (FALSE);
173}
174
175static Int check_if_valid_new_alias (USES_REGS1)
176{
177 Term tname = Deref(ARG1);
178 Atom at;
179
180 if (IsVarTerm(tname)) {
181 Yap_Error(INSTANTIATION_ERROR, tname, "$add_alias_to_stream");
182 return (FALSE);
183 } else if (!IsAtomTerm (tname)) {
184 Yap_Error(TYPE_ERROR_ATOM, tname, "$add_alias_to_stream");
185 return (FALSE);
186 }
187 at = AtomOfTerm(tname);
188 return(Yap_CheckAlias(at) == -1);
189}
190
191
192bool
193Yap_FetchStreamAlias (int sno, Term t2 USES_REGS)
194{
195
196 if (IsVarTerm(t2)) {
197 Atom at = FetchAlias(sno);
198 if (at == NULL)
199 return false;
200 else {
201 return Yap_unify_constant(t2, MkAtomTerm(at));
202 }
203 } else if (IsAtomTerm(t2)) {
204 Atom at = AtomOfTerm(t2);
205 return ExistsAliasForStream(sno,at);
206 } else {
207 Yap_Error(TYPE_ERROR_ATOM, t2, "stream_property(_,alias( ))");
208 return false;
209 }
210}
211
212static void pack_aliases(void)
213{
214 AliasDesc max = GLOBAL_FileAliases+ GLOBAL_NOfFileAliases, src, dst;
215 src = dst = GLOBAL_FileAliases+5;
216 while (src < max) {
217 if (src->alias_stream < 0)
218 break;
219 src++;
220 }
221 dst = src;
222 while (src < max) {
223 if (src->alias_stream < 0) {
224 src++;
225 } else {
226 dst->name = src->name;
227 dst->alias_stream = src->alias_stream;
228 src++;
229 dst++;
230 }
231 }
232 GLOBAL_NOfFileAliases = dst-GLOBAL_FileAliases;
233}
234
235static void
236ExtendAliasArray(void)
237{
238 CACHE_REGS
239 AliasDesc new;
240 UInt new_size = GLOBAL_SzOfFileAliases+ALIASES_BLOCK_SIZE;
241
242 new = (AliasDesc)Yap_ReallocCodeSpace(GLOBAL_FileAliases,sizeof(AliasDesc *)*new_size);
243 GLOBAL_FileAliases = new;
244 GLOBAL_SzOfFileAliases = new_size;
245}
246
247static void set_system_alias(Atom al, int sno){
248 if (al == AtomUserIn) {
249 LOCAL_c_input_stream = sno;
250 } else if (al == AtomUserOut) {
251 LOCAL_c_output_stream = sno;
252 } else if (al == AtomUserErr) {
253 LOCAL_c_error_stream = sno;
254 }
255}
256
258void
259Yap_SetAlias (Atom arg, int sno)
260{
261 CACHE_REGS
262 Yap_AddAlias(arg,sno);
263}
264
266bool
268{
269 CACHE_REGS
270 AliasDesc aliasp0 = GLOBAL_FileAliases, aliasp = GLOBAL_FileAliases+ GLOBAL_NOfFileAliases;
271 while( --aliasp >= aliasp0+5) {
272 if (aliasp->alias_stream == sno) {
273 // printf("--: %d %d\n", sno, aliasp-GLOBAL_FileAliases);
274
275 aliasp->alias_stream = -1;
276 if (aliasp->name == AtomUserIn ||
277 aliasp->name == AtomUserOut ||
278 aliasp->name == AtomUserErr) {
279 set_system_alias(aliasp->name, Yap_FindStreamForAlias(aliasp->name));
280 }
281 aliasp->name = NULL;
282 }
283 }
284 pack_aliases();
285 /* avoid holes in alias array */
286 return true;
287}
288
289/* check if name is an alias */
290int
291Yap_CheckAlias (Atom arg)
292{
293 return Yap_FindStreamForAlias(arg);
294}
295
296/* check if stream has an alias */
297static Atom
298FetchAlias (int sno)
299{
300 CACHE_REGS
301 AliasDesc aliasp0 = GLOBAL_FileAliases, aliasp = GLOBAL_FileAliases+GLOBAL_NOfFileAliases;
302
303
304 while (aliasp-- >= aliasp0) {
305 if (aliasp->alias_stream == sno &&
306 aliasp->name) {
307 return(aliasp->name);
308 }
309 }
310 return NULL;
311}
312
313/* check if arg is an alias */
314static bool
315ExistsAliasForStream (int sno, Atom al)
316{
317 CACHE_REGS
318 AliasDesc aliasp0 = GLOBAL_FileAliases, aliasp = GLOBAL_FileAliases+GLOBAL_NOfFileAliases;
319
320 while (--aliasp > aliasp0) {
321 if (aliasp->name == al) {
322 return aliasp->alias_stream == sno;
323 }
324 }
325 return false;
326}
327
328//parkinsonporto@gmail.com
329
330/* check if arg is an alias */
331int
332Yap_FindStreamForAlias (Atom al)
333{
334 CACHE_REGS
336 aliasp = GLOBAL_FileAliases+GLOBAL_NOfFileAliases;
337 if (GLOBAL_FileAliases == NULL)
338 return -1;
339 while (--aliasp >= aliasp0) {
340 if (aliasp->name == al && aliasp->alias_stream >= 0) {
341 // printf("?: %s=>%d\n", RepAtom(al)->StrOfAE, aliasp->alias_stream);
342 return aliasp->alias_stream;
343 }
344 }
345 return -1;
346}
347
352int
353Yap_RemoveAlias (Atom arg, int sno)
354{
355 CACHE_REGS
356
357 AliasDesc aliasp0 = GLOBAL_FileAliases, aliasp = GLOBAL_FileAliases+ GLOBAL_NOfFileAliases;
358 while( --aliasp >= aliasp0+5) {
359 if (aliasp->alias_stream == sno &&
360 aliasp->name == arg) {
361 // printf("-: %s/%d %d\n", RepAtom(arg)->StrOfAE, sno, GLOBAL_NOfFileAliases);
362 aliasp->alias_stream = -1;
363 if (aliasp->name == AtomUserIn ||
364 aliasp->name == AtomUserOut ||
365 aliasp->name == AtomUserErr) {
366 set_system_alias(aliasp->name, Yap_FindStreamForAlias(aliasp->name));
367 }
368 aliasp->name = NULL;
369 break;
370 }
371 }
372 pack_aliases();
373 /* avoid holes in alias array */
374 return true;
375}
376
377/* create a new alias arg for stream sno */
378bool
379Yap_AddAlias (Atom arg, int sno)
380{
381 CACHE_REGS
382
383 AliasDesc aliasp = GLOBAL_FileAliases+GLOBAL_NOfFileAliases;
384 if (ExistsAliasForStream(sno,arg)) {
385 return true;
386 }
387 /* we have not found an alias neither a hole */
388 if (GLOBAL_SzOfFileAliases >= (GLOBAL_NOfFileAliases+5))
389 ExtendAliasArray();
390 aliasp = GLOBAL_FileAliases+GLOBAL_NOfFileAliases;
391 // printf("ADD %p at %d\n", arg, aliasp-GLOBAL_FileAliases);
392 aliasp->name = arg;
393 aliasp->alias_stream = sno;
394 // // printf("+: %s=%d %d\n", RepAtom(arg)->StrOfAE, sno, GLOBAL_NOfFileAliases);
395 set_system_alias(arg,sno);
396 GLOBAL_NOfFileAliases++;
397 return true;
398}
399
400/* create a new alias arg for stream sno */
401struct AliasDescS *
402Yap_InitStandardAliases(void)
403{
404 CACHE_REGS
405 /* init standard aliases */
407 GLOBAL_FileAliases = NULL;
408 /* alloca alias array */
409 GLOBAL_FileAliases = (AliasDesc)Yap_AllocCodeSpace(sizeof(struct AliasDescS)*(ALIASES_BLOCK_SIZE+5));
410
411 if (GLOBAL_FileAliases == NULL)
412 return NULL;
413
414 GLOBAL_FileAliases[0].name = AtomUserIn;
415 GLOBAL_FileAliases[0].alias_stream = 0;
416 GLOBAL_FileAliases[1].name = AtomUserOut;
417 GLOBAL_FileAliases[1].alias_stream = 1;
418 GLOBAL_FileAliases[2].name = AtomUserErr;
419 GLOBAL_FileAliases[2].alias_stream = 2;
420 GLOBAL_FileAliases[3].name = AtomLoopStream;
421 GLOBAL_FileAliases[3].alias_stream = 0;
422 GLOBAL_FileAliases[4].name = AtomDebuggerInput;
423 GLOBAL_FileAliases[4].alias_stream = 0;
424 GLOBAL_NOfFileAliases = 5;
425 GLOBAL_SzOfFileAliases = ALIASES_BLOCK_SIZE+5;
426
427 return GLOBAL_FileAliases;
428}
429 /* create a new alias arg for stream sno */
430void
431Yap_InitAliases(void)
432{
433 Yap_InitStandardAliases();
434 Yap_InitCPred ("$check_if_valid_new_alias", 1, check_if_valid_new_alias, TestPredFlag|SafePredFlag|SyncPredFlag|HiddenPredFlag);
435 Yap_InitCPred ("$add_alias_to_stream", 2, add_alias_to_stream, SafePredFlag|SyncPredFlag|HiddenPredFlag);
436}
void Yap_SetAlias(Atom arg, int sno)
set arg as an alias to sno, but first check if not done before
Definition: alias.c:259
struct AliasDescS * GLOBAL_FileAliases
alias table access
Definition: h0globals.h:140
bool Yap_DeleteAliases(int sno)
purge all aliases for stream sno
Definition: alias.c:267
int Yap_RemoveAlias(Atom arg, int sno)
remove an alias arg for a stream
Definition: alias.c:353