1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 /* Lefteris Koutsofios - AT&T Labs Research */
15 
16 #include "common.h"
17 #include "g.h"
18 #include "mem.h"
19 #include "leftyio.h"
20 #include "code.h"
21 #include "tbl.h"
22 #include "parse.h"
23 #include "exec.h"
24 #include "display.h"
25 #include "txtview.h"
26 #include "gfxview.h"
27 #ifdef FEATURE_DOT
28 #include "dot2l.h"
29 #endif
30 #ifdef FEATURE_GMAP
31 #include "gmap2l.h"
32 #endif
33 #include "internal.h"
34 #ifndef FEATURE_MS
35 #include <sys/time.h>
36 #endif
37 
38 int Idump (int, Tonm_t *);
39 int Itypeof (int, Tonm_t *);
40 int Icopy (int, Tonm_t *);
41 int Iremove (int, Tonm_t *);
42 int Itablesize (int, Tonm_t *);
43 int Iopenio (int, Tonm_t *);
44 int Icloseio (int, Tonm_t *);
45 int Ireadline (int, Tonm_t *);
46 int Iread (int, Tonm_t *);
47 int Iwriteline (int, Tonm_t *);
48 int Iatan (int, Tonm_t *);
49 int Itan (int, Tonm_t *);
50 int Icos (int, Tonm_t *);
51 int Isin (int, Tonm_t *);
52 int Isqrt (int, Tonm_t *);
53 int Irandom (int, Tonm_t *);
54 int Intos (int, Tonm_t *);
55 int Iston (int, Tonm_t *);
56 int Isplit (int, Tonm_t *);
57 int Iconcat (int, Tonm_t *);
58 int Iquote (int, Tonm_t *);
59 int Ihtmlquote (int, Tonm_t *);
60 int Itoint (int, Tonm_t *);
61 int Istrlen (int, Tonm_t *);
62 int Iload (int, Tonm_t *);
63 int Irun (int, Tonm_t *);
64 int Imonitor (int, Tonm_t *);
65 int Iidlerun (int, Tonm_t *);
66 int Itime (int, Tonm_t *);
67 int Isleep (int, Tonm_t *);
68 int Iecho (int, Tonm_t *);
69 int Igetenv (int, Tonm_t *);
70 int Iputenv (int, Tonm_t *);
71 int Isystem (int, Tonm_t *);
72 int Iexit (int, Tonm_t *);
73 #ifdef FEATURE_DOT
74 int Iparsegraphlabel (int, Tonm_t *);
75 int Ireadgraph (int, Tonm_t *);
76 int Iwritegraph (int, Tonm_t *);
77 #endif
78 #ifdef FEATURE_CS
79 int C2Lreadcsmessage (int, Tonm_t *);
80 #endif
81 
82 #define MAXN 10000
83 
84 Ifunc_t Ifuncs[] = {
85     { "createwidget",  GFXcreatewidget,  2,    2 },
86     { "setwidgetattr", GFXsetwidgetattr, 2,    2 },
87     { "getwidgetattr", GFXgetwidgetattr, 2,    2 },
88     { "destroywidget", GFXdestroywidget, 1,    1 },
89     { "clear",         GFXclear,         1,    1 },
90     { "setgfxattr",    GFXsetgfxattr,    2,    2 },
91     { "getgfxattr",    GFXgetgfxattr,    2,    2 },
92     { "arrow",         GFXarrow,         4,    5 },
93     { "line",          GFXline,          4,    5 },
94     { "box",           GFXbox,           3,    4 },
95     { "polygon",       GFXpolygon,       3,    4 },
96     { "splinegon",     GFXsplinegon,     3,    4 },
97     { "arc",           GFXarc,           4,    5 },
98     { "text",          GFXtext,          7,    8 },
99     { "textsize",      GFXtextsize,      4,    4 },
100     { "createbitmap",  GFXcreatebitmap,  2,    2 },
101     { "destroybitmap", GFXdestroybitmap, 1,    1 },
102     { "readbitmap",    GFXreadbitmap,    2,    2 },
103     { "writebitmap",   GFXwritebitmap,   2,    2 },
104     { "bitblt",        GFXbitblt,        6,    7 },
105     { "clearpick",     GFXclearpick,     2,    2 },
106     { "setpick",       GFXsetpick,       3,    3 },
107     { "displaymenu",   GFXdisplaymenu,   2,    2 },
108     { "colormap",      GFXcolormap,      1,    1 },
109     { "txtview",       TXTmode,          1,    1 },
110     { "ask",           TXTask,           1,    3 },
111     { "dump",          Idump,            0, MAXN },
112     { "typeof",        Itypeof,          1,    1 },
113     { "copy",          Icopy,            1,    1 },
114     { "remove",        Iremove,          1,    2 },
115     { "tablesize",     Itablesize,       1,    1 },
116     { "openio",        Iopenio,          3,    4 },
117     { "closeio",       Icloseio,         1,    2 },
118     { "readline",      Ireadline,        1,    1 },
119     { "read",          Iread,            1,    1 },
120     { "writeline",     Iwriteline,       2,    2 },
121     { "atan",          Iatan,            2,    2 },
122     { "tan",           Itan,             1,    1 },
123     { "cos",           Icos,             1,    1 },
124     { "sin",           Isin,             1,    1 },
125     { "sqrt",          Isqrt,            1,    1 },
126     { "random",        Irandom,          1,    1 },
127     { "ntos",          Intos,            1,    1 },
128     { "ston",          Iston,            1,    1 },
129     { "split",         Isplit,           2,    3 },
130     { "concat",        Iconcat,          1, MAXN },
131     { "quote",         Iquote,           1,    3 },
132     { "htmlquote",     Ihtmlquote,       1,    1 },
133     { "toint",         Itoint,           1,    1 },
134     { "strlen",        Istrlen,          1,    1 },
135     { "load",          Iload,            1,    1 },
136     { "run",           Irun,             1,    1 },
137     { "monitor",       Imonitor,         2,    2 },
138     { "idlerun",       Iidlerun,         1,    1 },
139     { "time",          Itime,            0,    0 },
140     { "sleep",         Isleep,           1,    1 },
141     { "echo",          Iecho,            1, MAXN },
142     { "getenv",        Igetenv,          1,    1 },
143     { "putenv",        Iputenv,          2,    2 },
144     { "system",        Isystem,          1, MAXN },
145     { "exit",          Iexit,            0,    0 },
146 #ifdef FEATURE_DOT
147     { "parsegraphlabel", Iparsegraphlabel, 2, 2 },
148     { "readgraph",       Ireadgraph,       1, 2 },
149     { "writegraph",      Iwritegraph,      3, 3 },
150 #endif
151 #ifdef FEATURE_CS
152     { "readcsmessage", C2Lreadcsmessage, 1, 1 },
153 #endif
154 #ifdef FEATURE_GMAP
155     { "createwindow",     G2Lcreatewindow,     2, 2 },
156     { "destroywindow",    G2Ldestroywindow,    1, 1 },
157     { "setwindowattr",    G2Lsetwindowattr,    2, 2 },
158     { "getwindowattr",    G2Lgetwindowattr,    2, 2 },
159     { "createchannel",    G2Lcreatechannel,    2, 2 },
160     { "destroychannel",   G2Ldestroychannel,   1, 1 },
161     { "setchannelattr",   G2Lsetchannelattr,   2, 2 },
162     { "getchannelattr",   G2Lgetchannelattr,   2, 2 },
163     { "getchannelcoord",  G2Lgetchannelcoord,  2, 3 },
164     { "loadgeometry",     G2Lloadgeometry,     1, 1 },
165     { "unloadgeometry",   G2Lunloadgeometry,   1, 1 },
166     { "setgeometryattr",  G2Lsetgeometryattr,  2, 2 },
167     { "getgeometryattr",  G2Lgetgeometryattr,  2, 2 },
168     { "getgeometryitems", G2Lgetgeometryitems, 3, 3 },
169     { "insertgeom2chan",  G2Linsertgeom2chan,  2, 2 },
170     { "removegeom2chan",  G2Lremovegeom2chan,  1, 1 },
171     { "loadvalue",        G2Lloadvalue,        1, 1 },
172     { "unloadvalue",      G2Lunloadvalue,      1, 1 },
173     { "setvalueattr",     G2Lsetvalueattr,     2, 2 },
174     { "getvalueattr",     G2Lgetvalueattr,     2, 2 },
175     { "getvalueitems",    G2Lgetvalueitems,    2, 2 },
176     { "insertval2geom",   G2Linsertval2geom,   3, 3 },
177     { "removeval2geom",   G2Lremoveval2geom,   1, 1 },
178     { "setval2geomattr",  G2Lsetval2geomattr,  2, 2 },
179     { "getval2geomattr",  G2Lgetval2geomattr,  2, 2 },
180     { "updatewindows",    G2Lupdatewindows,    0, 0 },
181 #endif
182     { 0, 0, 0, 0 }
183 };
184 int Ifuncn;
185 
186 static char *bufp;
187 static int bufn;
188 #define BUFINCR 10240
189 #define BUFSIZE sizeof (char)
190 static void growbufp (int);
191 
Iinit(void)192 void Iinit (void) {
193     int i;
194 
195     if (!(bufp = malloc (BUFINCR * BUFSIZE)))
196         panic1 (POS, "Iinit", "buf malloc failed");
197     bufn = BUFINCR;
198     for (i = 0; Ifuncs[i].name; i++)
199         Efunction (Pfunction (Ifuncs[i].name, i), Ifuncs[i].name);
200     Ifuncn = sizeof (Ifuncs) / sizeof (Ifunc_t) - 1;
201 }
202 
Iterm(void)203 void Iterm (void) {
204     int i;
205 
206     for (i = 0; i < Ifuncn; i++)
207         Tdels (root, Ifuncs[i].name);
208     Ifuncn = 0;
209     free (bufp), bufp = NULL, bufn = 0;
210 }
211 
Igetfunc(char * name)212 int Igetfunc (char *name) {
213     int i = 0;
214 
215     while (Ifuncs[i].name && strcmp (Ifuncs[i].name, name) != 0)
216         i++;
217     return (Ifuncs[i].name) ? i : -1;
218 }
219 
220 /* display.c functions */
221 
Idump(int argc,lvar_t * argv)222 int Idump (int argc, lvar_t *argv) {
223     int i;
224 
225     if (argc == 0)
226         Dtrace (root, 0);
227     else
228         for (i = 0; i < argc; i++)
229             Dtrace (argv[i].o, 0);
230     return L_SUCCESS;
231 }
232 
233 /* tbl.c functions */
234 
Itypeof(int argc,lvar_t * argv)235 int Itypeof (int argc, lvar_t *argv) {
236     if (T_ISTABLE (argv[0].o))
237         rtno = Tstring ("table");
238     else if (T_ISSTRING (argv[0].o))
239         rtno = Tstring ("string");
240     else if (T_ISNUMBER (argv[0].o))
241         rtno = Tstring ("number");
242     return L_SUCCESS;
243 }
244 
Icopy(int argc,lvar_t * argv)245 int Icopy (int argc, lvar_t *argv) {
246     rtno = Tcopy (argv[0].o);
247     return L_SUCCESS;
248 }
249 
Iremove(int argc,lvar_t * argv)250 int Iremove (int argc, lvar_t *argv) {
251     Tobj tblo, keyo;
252 
253     if (argc == 2)
254         tblo = argv[1].o, keyo = argv[0].o;
255     else
256         tblo = root, keyo = argv[0].o;
257     if (T_ISTABLE (tblo) && (T_ISNUMBER (keyo) || T_ISSTRING (keyo)))
258         Tdelo (tblo, keyo);
259     return L_SUCCESS;
260 }
261 
Itablesize(int argc,lvar_t * argv)262 int Itablesize (int argc, lvar_t *argv) {
263     Tobj vo;
264 
265     if (Tgettype ((vo = argv[0].o)) != T_TABLE)
266         return L_FAILURE;
267     rtno = Tinteger (((Ttable_t *) vo)->n);
268     return L_SUCCESS;
269 }
270 
271 /* file.c functions */
272 
Iopenio(int argc,lvar_t * argv)273 int Iopenio (int argc, lvar_t *argv) {
274     int rtn;
275 
276     if (argc == 3)
277         rtn = IOopen (
278             Tgetstring (argv[0].o),
279             Tgetstring (argv[1].o), Tgetstring (argv[2].o), NULL
280         );
281     else
282         rtn = IOopen (
283             Tgetstring (argv[0].o),
284             Tgetstring (argv[1].o), Tgetstring (argv[2].o),
285             Tgetstring (argv[3].o)
286         );
287     rtno = NULL;
288     if (rtn == -1)
289         return L_SUCCESS;
290     rtno = Tinteger (rtn);
291     return L_SUCCESS;
292 }
293 
Icloseio(int argc,lvar_t * argv)294 int Icloseio (int argc, lvar_t *argv) {
295     if (argc == 1)
296         IOclose ((int) Tgetnumber (argv[0].o), NULL);
297     else
298         IOclose ((int) Tgetnumber (argv[0].o), Tgetstring (argv[1].o));
299     return L_SUCCESS;
300 }
301 
Ireadline(int argc,lvar_t * argv)302 int Ireadline (int argc, lvar_t *argv) {
303     char *s;
304     int m, n;
305 
306     s = bufp, n = bufn;
307     while ((m = IOreadline ((int) Tgetnumber (argv[0].o), s, n)) != -1) {
308         if (m < n - 1)
309             break;
310         m += (s - bufp);
311         growbufp (bufn + BUFINCR);
312         s = bufp + m, n = bufn - m;
313     }
314     if (m != -1)
315         rtno = Tstring (bufp);
316     else
317         rtno = NULL;
318     return L_SUCCESS;
319 }
320 
Iread(int argc,lvar_t * argv)321 int Iread (int argc, lvar_t *argv) {
322     if (IOread ((int) Tgetnumber (argv[0].o), bufp, bufn) > 0)
323         rtno = Tstring (bufp);
324     else
325         rtno = NULL;
326     return L_SUCCESS;
327 }
328 
Iwriteline(int argc,lvar_t * argv)329 int Iwriteline (int argc, lvar_t *argv) {
330     IOwriteline ((int) Tgetnumber (argv[0].o), Tgetstring (argv[1].o));
331     return L_SUCCESS;
332 }
333 
334 /* math functions */
335 
Iatan(int argc,lvar_t * argv)336 int Iatan (int argc, lvar_t *argv) {
337     double x, y;
338 
339     y = Tgetnumber (argv[0].o), x = Tgetnumber (argv[1].o);
340     rtno = Treal (180 * atan2 (y, x) / M_PI);
341     return L_SUCCESS;
342 }
343 
Itan(int argc,lvar_t * argv)344 int Itan (int argc, lvar_t *argv) {
345     rtno = Treal (tan (M_PI * Tgetnumber (argv[0].o) / 180.0));
346     return L_SUCCESS;
347 }
348 
Icos(int argc,lvar_t * argv)349 int Icos (int argc, lvar_t *argv) {
350     rtno = Treal (cos (M_PI * Tgetnumber (argv[0].o) / 180.0));
351     return L_SUCCESS;
352 }
353 
Isin(int argc,lvar_t * argv)354 int Isin (int argc, lvar_t *argv) {
355     rtno = Treal (sin (M_PI * Tgetnumber (argv[0].o) / 180.0));
356     return L_SUCCESS;
357 }
358 
Isqrt(int argc,lvar_t * argv)359 int Isqrt (int argc, lvar_t *argv) {
360     rtno = Treal (sqrt (Tgetnumber (argv[0].o)));
361     return L_SUCCESS;
362 }
363 
364 #if !defined(HAVE_LRAND48) || defined(FEATURE_MS)
365 #define lrand48 rand
366 #endif
367 
Irandom(int argc,lvar_t * argv)368 int Irandom (int argc, lvar_t *argv) {
369     rtno = Treal (
370         (Tgetnumber (argv[0].o) *
371         (lrand48 () & 0xffff)) / (double) (0xffff)
372     );
373     return L_SUCCESS;
374 }
375 
376 /* conversion functions */
377 
Intos(int argc,lvar_t * argv)378 int Intos (int argc, lvar_t *argv) {
379     double d;
380 
381     d = Tgetnumber (argv[0].o);
382     if ((long) d == d)
383         sprintf (bufp, "%ld", (long) d);
384     else
385         sprintf (bufp, "%f", d);
386     rtno = Tstring (bufp);
387     return L_SUCCESS;
388 }
389 
Iston(int argc,lvar_t * argv)390 int Iston (int argc, lvar_t *argv) {
391     rtno = Treal ((double) atof (Tgetstring (argv[0].o)));
392     return L_SUCCESS;
393 }
394 
Isplit(int argc,lvar_t * argv)395 int Isplit (int argc, lvar_t *argv) {
396     Tobj so, fo;
397     char *sp, *sp2, *s;
398     char fc, tc, qmode;
399     long rtnm, rtni;
400     int bufi, qflag;
401 
402     if (
403         Tgettype ((so = argv[0].o)) != T_STRING ||
404         Tgettype ((fo = argv[1].o)) != T_STRING
405     )
406         return L_FAILURE;
407     qflag = (argc == 3) ? FALSE : TRUE;
408     sp = Tgetstring (so);
409     s = Tgetstring (fo);
410     if (s[0] == '\\' && s[1] == 'n')
411         fc = '\n';
412     else
413         fc = s[0];
414     rtno = Ttable (4);
415     rtnm = Mpushmark (rtno);
416     rtni = 0;
417     if (s[0] == 0) {
418         for (sp2 = sp; *sp2; sp2++) {
419             tc = *(sp2 + 1), *(sp2 + 1) = '\000';
420             Tinsi (rtno, rtni++, Tstring (sp2));
421             *(sp2 + 1) = tc;
422         }
423     } else if (qflag && (fc == ' ' || fc == '	')) {
424         while (*sp == fc)
425             sp++;
426         while (*sp) {
427             bufi = 0;
428             qmode = 0;
429             for (sp2 = sp; *sp2; sp2++) {
430                 if (bufi == bufn)
431                     growbufp (bufn + BUFINCR);
432                 if (*sp2 == '"' || *sp2 == '\'') {
433                     if (qmode) {
434                         if (qmode == *sp2)
435                             qmode = 0;
436                         else
437                             bufp[bufi++] = *sp2;
438                     } else
439                         qmode = *sp2;
440                 } else if (*sp2 == fc && !qmode)
441                     break;
442                 else
443                     bufp[bufi++] = *sp2;
444             }
445             if (bufi == bufn)
446                 growbufp (bufn + BUFINCR);
447             bufp[bufi] = 0;
448             Tinsi (rtno, rtni++, Tstring (bufp));
449             while (*sp2 == fc)
450                 sp2++;
451             sp = sp2;
452         }
453     } else {
454         while (*sp) {
455             for (sp2 = sp; *sp2 && *sp2 != fc; sp2++)
456                 ;
457             tc = *sp2, *sp2 = '\000';
458             Tinsi (rtno, rtni++, Tstring (sp));
459             *sp2 = tc;
460             if (*sp2) {
461                 sp2++;
462                 if (!*sp2)
463                     Tinsi (rtno, rtni++, Tstring (""));
464             }
465             sp = sp2;
466         }
467     }
468     Mpopmark (rtnm);
469     return L_SUCCESS;
470 }
471 
Iconcat(int argc,lvar_t * argv)472 int Iconcat (int argc, lvar_t *argv) {
473     Tobj ao;
474     char buf2[50];
475     char *s;
476     int i, n, bufi;
477 
478     for (bufi = 0, i = 0; i < argc; i++) {
479         ao = argv[i].o;
480         switch (Tgettype (argv[i].o)) {
481         case T_STRING:
482             if (bufi + (n = strlen (Tgetstring (ao)) + 1) > bufn)
483                 growbufp (bufi + n);
484             for (s = Tgetstring (ao); *s; s++)
485                 bufp[bufi++] = *s;
486             break;
487         case T_INTEGER:
488             if (bufi + 50 > bufn)
489                 growbufp (bufi + 50);
490             sprintf (buf2, "%ld", Tgetinteger (ao));
491             for (s = buf2; *s; s++)
492                 bufp[bufi++] = *s;
493             break;
494         case T_REAL:
495             if (bufi + 50 > bufn)
496                 growbufp (bufi + 50);
497             sprintf (buf2, "%f", Tgetreal (ao));
498             for (s = buf2; *s; s++)
499                 bufp[bufi++] = *s;
500             break;
501         }
502     }
503     bufp[bufi] = '\000';
504     rtno = Tstring (bufp);
505     return L_SUCCESS;
506 }
507 
Iquote(int argc,lvar_t * argv)508 int Iquote (int argc, lvar_t *argv) {
509     Tobj so, ao=NULL, qo=NULL;
510     char *s=NULL, *s1, *s2, *qs, *as;
511     char buf2[50];
512     int n, bufi;
513 
514     if (
515         (Tgettype ((so = argv[0].o)) != T_STRING && !T_ISNUMBER (so)) ||
516         (argc > 1 && Tgettype ((qo = argv[1].o)) != T_STRING) ||
517         (argc > 2 && Tgettype ((ao = argv[2].o)) != T_STRING)
518     )
519         return L_FAILURE;
520     switch (Tgettype (so)) {
521     case T_STRING:
522         s = Tgetstring (so);
523         break;
524     case T_INTEGER:
525         sprintf (buf2, "%ld", Tgetinteger (so));
526         s = &buf2[0];
527         break;
528     case T_REAL:
529         sprintf (buf2, "%f", Tgetreal (so));
530         s = &buf2[0];
531         break;
532     }
533     if (argc > 1)
534         qs = Tgetstring (qo);
535     else
536         qs = "'\"";
537     if (argc > 2)
538         as = Tgetstring (ao);
539     else
540         as = NULL;
541     bufi = 0;
542     if ((n = strlen (s) + 3) * 2 > bufn)
543         growbufp (n * 2); /* the *2 is max for chars to quote */
544     if (as)
545         bufp[bufi++] = *as;
546     for (s1 = s; *s1; s1++) {
547         for (s2 = qs; *s2; s2++)
548             if (*s1 == *s2) {
549                 bufp[bufi++] = '\\', bufp[bufi++] = *s1;
550                 break;
551             }
552         if (!*s2) {
553             switch (*s1) {
554             case '\n': bufp[bufi++] = '\\', bufp[bufi++] = 'n'; break;
555             case '\r': bufp[bufi++] = '\\', bufp[bufi++] = 'r'; break;
556             default: bufp[bufi++] = *s1; break;
557             }
558         }
559     }
560     if (as)
561         bufp[bufi++] = *as;
562     bufp[bufi] = '\000';
563     rtno = Tstring (bufp);
564     return L_SUCCESS;
565 }
566 
Ihtmlquote(int argc,lvar_t * argv)567 int Ihtmlquote (int argc, lvar_t *argv) {
568     Tobj so;
569     char *s, *s1;
570     int n, bufi;
571 
572     if (Tgettype ((so = argv[0].o)) != T_STRING)
573         return L_FAILURE;
574     s = Tgetstring (so);
575     bufi = 0;
576     if ((n = strlen (s) + 1) * 4 > bufn)
577         growbufp (n * 4); /* the *4 is max for chars to quote */
578     for (s1 = s; *s1; s1++) {
579         switch (*s1) {
580         case '/':
581             bufp[bufi++] = '%';
582             bufp[bufi++] = '2';
583             bufp[bufi++] = 'F';
584             break;
585         case '%':
586             bufp[bufi++] = '%';
587             bufp[bufi++] = '2';
588             bufp[bufi++] = '5';
589             break;
590         case ' ':
591             bufp[bufi++] = '+';
592             break;
593         default:
594             bufp[bufi++] = *s1;
595             break;
596         }
597     }
598     bufp[bufi] = '\000';
599     rtno = Tstring (bufp);
600     return L_SUCCESS;
601 }
602 
Itoint(int argc,lvar_t * argv)603 int Itoint (int argc, lvar_t *argv) {
604     rtno = Tinteger ((long) Tgetnumber (argv[0].o));
605     return L_SUCCESS;
606 }
607 
Istrlen(int argc,lvar_t * argv)608 int Istrlen (int argc, lvar_t *argv) {
609     rtno = Tinteger (strlen (Tgetstring (argv[0].o)));
610     return L_SUCCESS;
611 }
612 
613 /* script loading functions */
614 
Iload(int argc,lvar_t * argv)615 int Iload (int argc, lvar_t *argv) {
616     Psrc_t src;
617     char *fn;
618     FILE *fp;
619     Tobj co;
620 
621     if ((fn = Tgetstring (argv[0].o))) {
622         if (fn[0] == '-' && fn[1] == '\000')
623             fp = stdin;
624         else {
625             fp = NULL;
626             if ((fn = buildpath (fn, FALSE)))
627                 fp = fopen (fn, "r");
628         }
629         if (fp) {
630             src.flag = FILESRC, src.s = NULL, src.fp = fp;
631             src.tok = -1, src.lnum = 1;
632             while ((co = Punit (&src)))
633                 Eoktorun = TRUE, Eunit (co);
634             if (fp != stdin)
635                 fclose (fp);
636         } else
637             return L_FAILURE;
638     }
639     return L_SUCCESS;
640 }
641 
Irun(int argc,lvar_t * argv)642 int Irun (int argc, lvar_t *argv) {
643     Psrc_t src;
644     char *s;
645     Tobj co;
646 
647     if ((s = Tgetstring (argv[0].o))) {
648         src.flag = CHARSRC, src.s = s, src.fp = NULL;
649         src.tok = -1, src.lnum = 1;
650         while ((co = Punit (&src)))
651             Eoktorun = TRUE, Eunit (co);
652     }
653     return L_SUCCESS;
654 }
655 
656 /* mode setting functions */
657 
Imonitor(int argc,lvar_t * argv)658 int Imonitor (int argc, lvar_t *argv) {
659     Tobj mo, io;
660     char *ms;
661     int ioi;
662 
663     if (
664         Tgettype ((mo = argv[0].o)) != T_STRING ||
665         (Tgettype ((io = argv[1].o)) != T_INTEGER && Tgettype (io) != T_REAL)
666     )
667         return L_FAILURE;
668     ms = Tgetstring (mo), ioi = Tgetnumber (io);
669     if (ioi < 0 || ioi >= ion)
670         return L_FAILURE;
671     if (strcmp (ms, "on") == 0)
672         IOmonitor (ioi, inputfds);
673     else if (strcmp (ms, "off") == 0)
674         IOunmonitor (ioi, inputfds);
675     else
676         return L_FAILURE;
677     return L_SUCCESS;
678 }
679 
Iidlerun(int argc,lvar_t * argv)680 int Iidlerun (int argc, lvar_t *argv) {
681     Tobj mo;
682     char *ms;
683     int mode;
684 
685     if (Tgettype ((mo = argv[0].o)) != T_STRING)
686         return L_SUCCESS;
687     ms = Tgetstring (mo);
688     if (strcmp (ms, "on") == 0)
689         mode = 1;
690     else if (strcmp (ms, "off") == 0)
691         mode = 0;
692     else
693         return L_FAILURE;
694     idlerunmode = mode;
695     return L_SUCCESS;
696 }
697 
698 /* system functions */
699 
Itime(int argc,lvar_t * argv)700 int Itime (int argc, lvar_t *argv) {
701 #ifndef FEATURE_MS
702     struct timeval tz;
703 
704     gettimeofday (&tz, NULL);
705     rtno = Treal (tz.tv_sec + tz.tv_usec / 1000000.0);
706 #else
707     rtno = Treal (0);
708 #endif
709     return L_SUCCESS;
710 }
711 
Isleep(int argc,lvar_t * argv)712 int Isleep (int argc, lvar_t *argv) {
713 #ifndef FEATURE_MS
714     struct timeval tz;
715     float f;
716 
717     Gsync ();
718     f = Tgetnumber (argv[0].o);
719     tz.tv_sec = f;
720     tz.tv_usec = (f - tz.tv_sec) * 1000000;
721     if (select (0, NULL, NULL, NULL, &tz) == -1)
722         return L_FAILURE;
723 #endif
724     return L_SUCCESS;
725 }
726 
Iecho(int argc,lvar_t * argv)727 int Iecho (int argc, lvar_t *argv) {
728     int i;
729 
730     rtno = NULL;
731     for (i = 0; i < argc; i++) {
732         switch (Tgettype (argv[i].o)) {
733         case T_STRING:  printf ("%s", Tgetstring (argv[i].o));   break;
734         case T_INTEGER: printf ("%ld", Tgetinteger (argv[i].o)); break;
735         case T_REAL:    printf ("%f", Tgetreal (argv[i].o));     break;
736         case T_TABLE:   printf ("[\n"), Dtrace (argv[i].o, 4);   break;
737         }
738     }
739     printf ("\n");
740     return L_SUCCESS;
741 }
742 
Igetenv(int argc,lvar_t * argv)743 int Igetenv (int argc, lvar_t *argv) {
744     char *s;
745 
746     if (!T_ISSTRING (argv[0].o))
747         return L_FAILURE;
748     rtno = NULL;
749     if (!(s = getenv (Tgetstring (argv[0].o))) || !*s)
750         return L_SUCCESS;
751     rtno = Tstring (s);
752     return L_SUCCESS;
753 }
754 
Iputenv(int argc,lvar_t * argv)755 int Iputenv (int argc, lvar_t *argv) {
756     if (!T_ISSTRING (argv[0].o) || !T_ISSTRING (argv[1].o))
757         return L_FAILURE;
758     bufp[0] = 0;
759     strcat (bufp, Tgetstring (argv[0].o));
760     strcat (bufp, "=");
761     strcat (bufp, Tgetstring (argv[1].o));
762     putenv (bufp);
763     return L_SUCCESS;
764 }
765 
Isystem(int argc,lvar_t * argv)766 int Isystem (int argc, lvar_t *argv) {
767     int i;
768 
769     bufp[0] = 0;
770     strcat (bufp, Tgetstring (argv[0].o));
771     for (i = 1; i < argc; i++)
772         strcat (bufp, " "), strcat (bufp, Tgetstring (argv[i].o));
773 #ifndef FEATURE_MS
774     system (bufp);
775 #else
776     {
777         UINT handle;
778         handle = WinExec (bufp, SW_SHOW);
779     }
780 #endif
781     return L_SUCCESS;
782 }
783 
Iexit(int argc,lvar_t * argv)784 int Iexit (int argc, lvar_t *argv) {
785     longjmp (exitljbuf, 1);
786     return L_SUCCESS; /* NOT REACHED */
787 }
788 
789 #ifdef FEATURE_DOT
790 /* dot related functions */
791 
Iparsegraphlabel(int argc,lvar_t * argv)792 int Iparsegraphlabel (int argc, lvar_t *argv) {
793     rtno = D2Lparsegraphlabel (argv[0].o, argv[1].o);
794     return L_SUCCESS;
795 }
796 
Ireadgraph(int argc,lvar_t * argv)797 int Ireadgraph (int argc, lvar_t *argv) {
798     int ioi;
799 
800     if ((ioi = Tgetnumber (argv[0].o)) < 0 || ioi >= ion)
801         return L_FAILURE;
802     if (argc == 2 && !T_ISTABLE (argv[1].o))
803         return L_FAILURE;
804     if (!(rtno = D2Lreadgraph (ioi, (argc == 2 ? argv[1].o : NULL))))
805         return L_FAILURE;
806     return L_SUCCESS;
807 }
808 
Iwritegraph(int argc,lvar_t * argv)809 int Iwritegraph (int argc, lvar_t *argv) {
810     int ioi;
811 
812     if (
813         !T_ISNUMBER (argv[0].o) || !T_ISTABLE (argv[1].o) ||
814         !T_ISINTEGER (argv[2].o)
815     )
816         return L_FAILURE;
817     if ((ioi = Tgetnumber (argv[0].o)) < 0 || ioi >= ion)
818         return L_FAILURE;
819     D2Lwritegraph (ioi, argv[1].o, Tgetinteger (argv[2].o));
820     return L_SUCCESS;
821 }
822 #endif
823 
growbufp(int newsize)824 static void growbufp (int newsize) {
825     if (!(bufp = realloc (
826         bufp, ((newsize + BUFINCR - 1) / BUFINCR) * BUFINCR * BUFSIZE
827     )))
828         panic1 (POS, "growbufp", "buf realloc failed");
829     bufn = ((newsize + BUFINCR - 1) / BUFINCR) * BUFINCR;
830 }
831