added simple FLTK test (to be removed); added readLine method to Stream and File
[k8lst.git] / src / primlib / stdlib / lstpl_stdlib.c
blobd2b249a094ae0a96d952cfd275708dc1d2c168d8
1 /*
2 * Primitives of the LittleSmalltalk system
4 * ---------------------------------------------------------------
5 * Little Smalltalk, Version 5
7 * Copyright (C) 1987-2005 by Timothy A. Budd
8 * Copyright (C) 2007 by Charles R. Childers
9 * Copyright (C) 2005-2007 by Danny Reinhold
10 * Copyright (C) 2010 by Ketmar // Vampire Avalon
12 * ============================================================================
13 * This license applies to the virtual machine and to the initial image of
14 * the Little Smalltalk system and to all files in the Little Smalltalk
15 * packages except the files explicitly licensed with another license(s).
16 * ============================================================================
17 * Permission is hereby granted, free of charge, to any person obtaining a copy
18 * of this software and associated documentation files (the "Software"), to deal
19 * in the Software without restriction, including without limitation the rights
20 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 * copies of the Software, and to permit persons to whom the Software is
22 * furnished to do so, subject to the following conditions:
24 * The above copyright notice and this permission notice shall be included in
25 * all copies or substantial portions of the Software.
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 * DEALINGS IN THE SOFTWARE.
35 #include <ctype.h>
36 #include <fcntl.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <time.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
45 #include "lstcore/k8lst.h"
48 #ifdef LST_ON_WINDOWS
49 # include "windows.h" /* for Sleep() */
50 #else
51 # include <termios.h>
52 #endif
54 #include "lstpl_stdlib.h"
57 static const char *fileId = "FileHandle";
59 typedef struct {
60 const char *type;
61 FILE *fl;
62 } FileInfo;
65 LST_FINALIZER(lpFileHandleFinalizer) {
66 FileInfo *fi = (FileInfo *)udata;
67 if (fi) {
68 if (fi->fl) fclose(fi->fl);
69 free(fi);
74 static lstObject *newFileHandle (FILE *fl) {
75 FileInfo *fi;
76 lstObject *res = lstNewBinary(NULL, 0);
77 fi = malloc(sizeof(FileInfo));
78 if (!fi) { fclose(fl); return lstNilObj; }
79 fi->type = fileId;
80 fi->fl = fl;
81 lstSetFinalizer(res, lpFileHandleFinalizer, fi);
82 return res;
86 static FILE *getFile (lstObject *o) {
87 if (LST_IS_SMALLINT(o) || !LST_IS_BYTES(o) || LST_SIZE(o) || !o->fin || !o->fin->udata) return NULL;
88 FileInfo *fi = (FileInfo *)o->fin->udata;
89 if (fi->type != fileId) return NULL;
90 return fi->fl;
94 static char nameBuffer[8192], modeBuffer[64];
96 LST_PRIMFN(lpFileExists) {
97 if (LST_PRIMARGC != 1) return NULL;
98 lstObject *o = LST_PRIMARG(0);
99 if (!LST_IS_BYTES(o)) return NULL;
100 lstGetString(nameBuffer, 8190, LST_PRIMARG(0));
101 FILE *fp = fopen(nameBuffer, "rb");
102 if (fp == NULL) return lstFalseObj;
103 fclose(fp);
104 return lstTrueObj;
108 LST_PRIMFN(lpFileOpen) {
109 if (LST_PRIMARGC != 2) return NULL;
110 if (!LST_IS_BYTES(LST_PRIMARG(0))) return NULL;
111 if (!LST_IS_BYTES(LST_PRIMARG(1))) return NULL;
112 lstGetString(nameBuffer, 8190, LST_PRIMARG(0));
113 lstGetString(modeBuffer, 60, LST_PRIMARG(1));
114 FILE *fp = fopen(nameBuffer, modeBuffer);
115 if (fp == NULL) return lstNilObj;
116 return newFileHandle(fp);
120 #define TAKE_FHFP \
121 FILE *fp = getFile(LST_PRIMARG(0)); \
122 if (!fp) return NULL;
125 LST_PRIMFN(lpFileGetChar) {
126 if (LST_PRIMARGC != 1) return NULL;
127 TAKE_FHFP
128 int ch = fgetc(fp);
129 return ch==EOF ? lstNilObj : lstNewInt(ch);
133 LST_PRIMFN(lpFilePutChar) {
134 if (LST_PRIMARGC != 2) return NULL;
135 TAKE_FHFP
136 if (!LST_IS_SMALLINT(LST_PRIMARG(1))) return NULL;
137 return fputc(lstIntValue(LST_PRIMARG(1)), fp)==EOF ? lstFalseObj : lstTrueObj;
141 LST_PRIMFN(lpFileClose) {
142 if (LST_PRIMARGC != 1) return NULL;
143 TAKE_FHFP
144 FileInfo *fi = (FileInfo *)((LST_PRIMARG(0))->fin->udata);
145 fclose(fp);
146 fi->fl = NULL;
147 return lstTrueObj;
151 LST_PRIMFN(lpFileWriteImage) {
152 int noSrc = 0;
153 if (LST_PRIMARGC != 2) return NULL;
154 TAKE_FHFP
155 if (LST_IS_SMALLINT(LST_PRIMARG(1))) noSrc = lstIntValue(LST_PRIMARG(1));
156 else if (LST_PRIMARG(1) == lstTrueObj) noSrc = 1;
157 return lstNewInt(lstWriteImage(fp, noSrc));
161 LST_PRIMFN(lpFileReadByteArray) {
162 if (LST_PRIMARGC != 3) return NULL;
163 TAKE_FHFP
164 /* make sure we're populating an array of bytes */
165 lstObject *res = LST_PRIMARG(1);
166 if (!LST_IS_BYTES(res)) return NULL;
167 /* sanity check on I/O count */
168 if (!LST_IS_SMALLINT(LST_PRIMARG(2))) return NULL;
169 int len = lstIntValue(LST_PRIMARG(2));
170 if (len < 0 || len > LST_SIZE(res)) return NULL;
171 /* do the I/O */
172 if (len > 0) len = fread(lstBytePtr(res), 1, len, fp);
173 if (len < 0) return lstNilObj;
174 return lstNewInt(len);
178 LST_PRIMFN(lpFileWriteByteArray) {
179 if (LST_PRIMARGC != 3) return NULL;
180 TAKE_FHFP
181 /* make sure we're writing an array of bytes */
182 lstObject *res = LST_PRIMARG(1);
183 if (!LST_IS_BYTES(res)) return NULL;
184 /* sanity check on I/O count */
185 if (!LST_IS_SMALLINT(LST_PRIMARG(2))) return NULL;
186 int len = lstIntValue(LST_PRIMARG(2));
187 if (len < 0 || len > LST_SIZE(res)) return NULL;
188 /* do the I/O */
189 if (len > 0) len = fwrite(lstBytePtr(res), 1, len, fp);
190 if (len < 0) return lstNilObj;
191 return lstNewInt(len);
195 LST_PRIMFN(lpFileSeek) {
196 long ofs;
197 if (LST_PRIMARGC != 2) return NULL;
198 TAKE_FHFP
199 /* file position */
200 if (LST_IS_SMALLINT(LST_PRIMARG(1))) ofs = lstIntValue(LST_PRIMARG(1));
201 else if (LST_PRIMARG(1)->stclass == lstIntegerClass) ofs = lstLIntValue(LST_PRIMARG(1));
202 else return NULL;
203 if (ofs < 0 || fseek(fp, ofs, SEEK_SET)) return NULL;
204 /* return position as our value */
205 return LST_PRIMARG(1);
209 LST_PRIMFN(lpFileSize) {
210 long size, opos;
211 if (LST_PRIMARGC != 1) return NULL;
212 TAKE_FHFP
213 if ((opos = ftell(fp)) < 0) return NULL;
214 if (fseek(fp, 0, SEEK_END) < 0) return NULL;
215 size = ftell(fp);
216 fseek(fp, opos, SEEK_SET);
217 if (size < 0) return NULL;
218 return lstNewInteger(size);
222 LST_PRIMFN(lpFileGetFD) {
223 if (LST_PRIMARGC != 1) return NULL;
224 TAKE_FHFP
225 return lstNewInt(fileno(fp));
229 LST_PRIMFN(lpFileReadLine) {
230 static char buf[8192]; /*FIXME*/
231 if (LST_PRIMARGC != 1) return NULL;
232 TAKE_FHFP
233 if (!fgets(buf, sizeof(buf), fp)) return lstNilObj;
234 int len = strlen(buf)-1;
235 if (len >= 0 && buf[len] == '\n') {
236 if (len > 0 && buf[len-1] == '\r') buf[len-1] = '\0'; else buf[len] = '\0';
238 return lstNewString(buf);
242 LST_PRIMFN(lpSystemGetOSName) {
243 if (LST_PRIMARGC != 0) return NULL;
244 return lstNewString(lstOSName);
248 LST_PRIMFN(lpSystemIsATTY) {
249 if (LST_PRIMARGC != 1) return NULL;
250 return isatty(lstIntValue(LST_PRIMARG(0))) ? lstTrueObj : lstFalseObj;
254 LST_PRIMFN(lpSystemSleep) {
255 lstObject *o;
256 int pauseMs = 0;
257 if (LST_PRIMARGC != 1) return NULL;
258 o = LST_PRIMARG(0);
259 if (LST_IS_SMALLINT(o)) pauseMs = lstIntValue(o)*1000;
260 else if (o->stclass == lstIntegerClass) pauseMs = lstLIntValue(o)*1000;
261 else if (o->stclass == lstFloatClass) {
262 LstFloat fv = lstFloatValue(o);
263 pauseMs = (int)(fv*1000.0);
264 } else pauseMs = -1;
265 if (pauseMs < 0) return lstNilObj;
266 #ifndef _WIN32
267 if (pauseMs%1000) {
268 //2000000 == 2 seconds == 2000 milliseconds
269 int sec = pauseMs/1000;
270 if (sec > 0) sleep(sec);
271 usleep((pauseMs%1000)*1000);
272 } else {
273 sleep(pauseMs/1000);
275 #else
276 Sleep(pauseMs);
277 #endif
278 return lstNilObj;
282 LST_PRIMFN(lpSystemUnixTime) {
283 time_t t = time(NULL);
284 return LST_64FITS_SMALLINT(t) ? lstNewInt(t) : lstNewLongInt(t);
288 LST_PRIMFN(lpSystemLocalTime) {
289 time_t t;
290 if (LST_PRIMARGC > 0) {
291 lstObject *o = LST_PRIMARG(0);
292 if (LST_IS_SMALLINT(o)) t = lstIntValue(o);
293 else if (o->stclass == lstIntegerClass) t = lstLIntValue(o);
294 else if (o->stclass == lstFloatClass) {
295 LstFloat fv = lstFloatValue(o);
296 t = (time_t)(fv);
297 } else return NULL;
298 } else {
299 t = time(NULL);
301 struct tm *lt = localtime(&t);
302 lstObject *res = lstNewArray(9);
303 res->data[0] = lstNewInt(lt->tm_sec);
304 res->data[1] = lstNewInt(lt->tm_min);
305 res->data[2] = lstNewInt(lt->tm_hour);
306 res->data[3] = lstNewInt(lt->tm_mday);
307 res->data[4] = lstNewInt(lt->tm_mon+1); /* convert to 1..12 */
308 res->data[5] = lstNewInt(lt->tm_year+1900);
309 res->data[6] = lstNewInt(lt->tm_wday); /* 0: sunday */
310 res->data[7] = lstNewInt(lt->tm_yday);
311 res->data[8] = lt->tm_isdst ? lstTrueObj : lstFalseObj;
312 return res;
316 static char lstMyPath[8192];
317 static void initMyPath (void) {
318 #ifndef _WIN32
319 char buf[128];
320 pid_t pid = getpid();
321 sprintf(buf, "/proc/%u/exe", (unsigned int)pid);
322 if (readlink(buf, lstMyPath, sizeof(lstMyPath)-1) < 0) strcpy(lstMyPath, "./");
323 else {
324 char *p = (char *)strrchr(lstMyPath, '/');
325 if (!p) strcpy(lstMyPath, "./"); else p[1] = '\0';
327 #else
328 char *p;
329 memset(lstMyPath, 0, sizeof(lstMyPath));
330 GetModuleFileName(GetModuleHandle(NULL), lstMyPath, sizeof(lstMyPath)-1);
331 p = strrchr(lstMyPath, '\\');
332 if (!p) strcpy(lstMyPath, ".\\"); else p[1] = '\0';
333 #endif
337 LST_PRIMFN(lpSystemBinPath) {
338 return lstNewString(lstMyPath);
342 LST_PRIMFN(lpStringToURLEncoding) {
343 if (LST_PRIMARGC != 1) return NULL;
344 unsigned char *res, *src; int dp, slen;
345 lstObject *s = LST_PRIMARG(0);
346 if (LST_IS_SMALLINT(s) || s->stclass != lstStringClass) return NULL;
347 slen = LST_SIZE(s);
348 res = malloc(slen*3);
349 src = (unsigned char *)lstBytePtr(s);
350 for (dp = 0; slen > 0; src++, slen--) {
351 unsigned char ch = *src;
352 if (isalnum(ch)) {
353 res[dp++] = ch;
354 } else {
355 char buf[5];
356 sprintf(buf, "%%%02X", ch);
357 memcpy(res+dp, buf, 3);
358 dp += 3;
361 /*FIXME: memory leak on fail*/
362 s = (lstObject *)lstMemAllocBin(dp);
363 s->stclass = lstStringClass;
364 if (dp > 0) memcpy(lstBytePtr(s), res, dp);
365 free(res);
366 return s;
370 LST_PRIMFN(lpStringFromURLEncoding) {
371 if (LST_PRIMARGC < 1) return NULL;
372 unsigned char *res, *src; int dp, slen;
373 lstObject *s = LST_PRIMARG(0);
374 if (LST_IS_SMALLINT(s) || s->stclass != lstStringClass) return NULL;
375 slen = LST_SIZE(s);
376 res = malloc(slen);
377 src = (unsigned char *)lstBytePtr(s);
378 int doPlus = LST_PRIMARGC > 1;
379 for (dp = 0; slen > 0; src++, slen--) {
380 unsigned char ch = *src;
381 if (ch == '%' && slen >= 3 && isxdigit(src[1]) && isxdigit(src[2])) {
382 int n = toupper(src[1])-'0'; if (n > 9) n -= 7;
383 ch = n*16;
384 n = toupper(src[2])-'0'; if (n > 9) n -= 7;
385 ch += n;
386 res[dp++] = ch;
387 slen -= 2;
388 src += 2;
389 } else if (doPlus && ch == '+') {
390 res[dp++] = ' ';
391 } else {
392 res[dp++] = ch;
395 /*FIXME: memory leak on fail*/
396 s = (lstObject *)lstMemAllocBin(dp);
397 s->stclass = lstStringClass;
398 if (dp > 0) memcpy(lstBytePtr(s), res, dp);
399 free(res);
400 return s;
405 LST_PRIMFN(lpStringOpsExt) {
406 int action;
407 if (LST_PRIMARGC != 2) return NULL;
408 lstObject *op = LST_PRIMARG(0);
409 if (!LST_IS_SMALLINT(op)) return NULL;
410 action = lstIntValue(op);
411 lstObject *op = LST_PRIMARG(1);
412 if (LST_CLASS(op) != lstStringClass) return NULL;
413 switch (action) {
414 case 0: return lpStringToURLEncoding(op);
415 case 1: return lpStringFromURLEncoding(op);
417 return NULL;
422 LST_PRIMFN(lpSystemSystem) {
423 if (LST_PRIMARGC != 1) return NULL;
424 lstObject *o = LST_PRIMARG(0);
425 if (!LST_IS_BYTES(o)) return NULL;
426 int size = LST_SIZE(o);
427 if (size < 1) return lstNilObj;
428 char *cmd = malloc(sizeof(char)*(size+4));
429 if (!cmd) return NULL;
430 lstGetString(cmd, size+2, o);
431 int res = system(cmd);
432 free(cmd);
433 if (res < 0) return lstNilObj;
434 return lstNewInteger(res);
438 LST_PRIMFN(lpSystemTickCountMS) {
439 int64_t res;
440 if (LST_PRIMARGC != 0) return NULL;
441 #ifndef _WIN32
442 struct timespec ts;
443 clock_gettime(CLOCK_MONOTONIC, &ts);
444 res = ((uint64_t)ts.tv_sec)*1000UL;
445 res += ((uint64_t)ts.tv_nsec)/1000000UL; //1000000000
446 #else
447 res = GetTickCount();
448 #endif
449 return lstNewInteger(res);
453 #ifndef _WIN32
454 static int termInitialized = 0;
455 static struct termios origTIOS;
456 static int inRawMode = 0;
459 static void disableRawMode (void) {
460 tcsetattr(STDIN_FILENO, TCSAFLUSH, &origTIOS);
461 inRawMode = 0;
465 static void termCleanAtExit (void) {
466 disableRawMode();
470 static int enableRawMode (void) {
471 struct termios raw;
472 if (!isatty(STDIN_FILENO)) goto fatal;
473 atexit(termCleanAtExit);
474 if (tcgetattr(STDIN_FILENO, &origTIOS) == -1) goto fatal;
475 raw = origTIOS; /* modify the original mode */
476 /* input modes: no break, no CR to NL, no parity check, no strip char, no start/stop output control */
477 /*raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);*/
478 /* input modes: no break, no parity check, no strip char, no start/stop output control */
479 raw.c_iflag &= ~(BRKINT | INPCK | ISTRIP | IXON);
480 /* output modes - disable post processing */
481 raw.c_oflag &= ~(OPOST);
482 raw.c_oflag |= ONLCR;
483 raw.c_oflag = OPOST | ONLCR;
484 /* control modes - set 8 bit chars */
485 raw.c_cflag |= (CS8);
486 /* local modes - choing off, canonical off, no extended functions, no signal chars (^Z,^C) */
487 raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
488 /* control chars - set return condition: min number of bytes and timer;
489 * we want read to return every single byte, without timeout */
490 raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
491 /* put terminal in raw mode after flushing */
492 if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) goto fatal;
493 inRawMode = 1;
494 return 0;
495 fatal:
496 /*errno = ENOTTY;*/
497 return -1;
501 static inline void setRawMode (int rmFlag) {
502 if (rmFlag) enableRawMode(); else disableRawMode();
506 static int isKeyHit (void) {
507 struct timeval tv;
508 fd_set fds;
509 tv.tv_sec = 0;
510 tv.tv_usec = 0;
511 FD_ZERO(&fds);
512 FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
513 select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
514 return FD_ISSET(STDIN_FILENO, &fds);
518 static void setCanonical (int cnFlag) {
519 struct termios ttystate;
520 tcgetattr(STDIN_FILENO, &ttystate);
521 if (!cnFlag) {
522 ttystate.c_lflag &= ~ICANON; /* turn off canonical mode */
523 ttystate.c_cc[VMIN] = 1; /* minimum of number input read */
524 } else {
525 ttystate.c_lflag |= ICANON; /* turn on canonical mode */
527 tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttystate);
531 static void setEcho (int cnFlag) {
532 struct termios ttystate;
533 tcgetattr(STDIN_FILENO, &ttystate);
534 if (!cnFlag) {
535 ttystate.c_lflag &= ~ECHO;
536 } else {
537 ttystate.c_lflag |= ECHO;
539 tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttystate);
543 static int isCanonical (void) {
544 struct termios ttystate;
545 tcgetattr(STDIN_FILENO, &ttystate);
546 return ttystate.c_lflag&ICANON ? 1 : 0;
550 static int isEcho (void) {
551 struct termios ttystate;
552 tcgetattr(STDIN_FILENO, &ttystate);
553 return ttystate.c_lflag&ECHO ? 1 : 0;
557 LST_PRIMFN(lpSystemIsKeyHit) {
558 if (LST_PRIMARGC != 0) return NULL;
559 return isKeyHit() ? lstTrueObj : lstFalseObj;
563 LST_PRIMFN(lpSystemTermMode) {
564 lstObject *o;
565 int oldv, newv = -1;
566 if (LST_PRIMARGC < 1) return NULL;
567 o = LST_PRIMARG(0);
568 if (!LST_IS_SMALLINT(o)) return NULL;
569 if (LST_PRIMARGC > 1) {
570 lstObject *o = LST_PRIMARG(1);
571 if (o == lstNilObj || o == lstFalseObj) newv = 0;
572 else if (o == lstTrueObj) newv = 1;
573 else if (LST_IS_SMALLINT(o)) newv = lstIntValue(o) ? 1 : 0;
574 else return NULL;
576 switch (lstIntValue(o)) {
577 case 0: /* canonical */
578 oldv = isCanonical();
579 if (newv != -1) setCanonical(newv);
580 break;
581 case 1: /* echo */
582 oldv = isEcho();
583 if (newv != -1) setEcho(newv);
584 break;
585 case 2: /* raw */
586 oldv = inRawMode;
587 if (newv != -1) setRawMode(newv);
588 break;
589 default: return NULL;
591 return oldv ? lstTrueObj : lstFalseObj;
595 LST_PRIMCLEARFN(lpSystemKeyClean) {
596 disableRawMode();
598 #endif
601 static const LSTExtPrimitiveTable primFilesTbl[] = {
602 /*TODO: turn this into one primitive with numeric action */
603 {"FileExists", lpFileExists, NULL},
604 {"FileOpen", lpFileOpen, NULL},
605 {"FileGetChar", lpFileGetChar, NULL},
606 {"FilePutChar", lpFilePutChar, NULL},
607 {"FileClose", lpFileClose, NULL},
608 {"FileWriteImage", lpFileWriteImage, NULL},
609 {"FileReadByteArray", lpFileReadByteArray, NULL},
610 {"FileWriteByteArray", lpFileWriteByteArray, NULL},
611 {"FileSeek", lpFileSeek, NULL},
612 {"FileSize", lpFileSize, NULL},
613 {"FileGetFD", lpFileGetFD, NULL},
614 {"FileReadLine", lpFileReadLine, NULL},
615 {0}};
617 static const LSTExtPrimitiveTable primTbl[] = {
618 {"SystemGetOSName", lpSystemGetOSName, NULL},
619 {"SystemIsATTY", lpSystemIsATTY, NULL},
620 {"SystemSleep", lpSystemSleep, NULL},
621 {"SystemUnixTime", lpSystemUnixTime, NULL},
622 {"SystemLocalTime", lpSystemLocalTime, NULL},
623 {"SystemTickCountMS", lpSystemTickCountMS, NULL},
624 /* */
625 {"SystemBinPath", lpSystemBinPath, NULL},
626 #ifndef _WIN32
627 {"SystemIsKeyHit", lpSystemIsKeyHit, NULL},
628 {"SystemTermMode", lpSystemTermMode, lpSystemKeyClean},
629 #endif
630 /* */
631 {"StringFromURLEncoding", lpStringFromURLEncoding, NULL},
632 {"StringToURLEncoding", lpStringToURLEncoding, NULL},
633 {0}};
635 static const LSTExtPrimitiveTable primExecTbl[] = {
636 {"SystemSystem", lpSystemSystem, NULL},
637 {0}};
640 const char *lstBinDir (void) {
641 return lstMyPath;
645 void lstInitPrimitivesStdLib (void) {
646 initMyPath();
647 #ifndef _WIN32
648 tcgetattr(STDIN_FILENO, &origTIOS);
649 if (!termInitialized) {
650 termInitialized = 1;
651 atexit(termCleanAtExit);
653 #endif
654 lstRegisterExtPrimitiveTable(primTbl);
658 void lstInitPrimitivesFiles (void) {
659 lstRegisterExtPrimitiveTable(primFilesTbl);
663 void lstInitPrimitivesExec (void) {
664 lstRegisterExtPrimitiveTable(primExecTbl);