2 ** stub main for testing FICL under userland
3 ** $Id: testmain.c,v 1.13 2001/12/05 07:21:34 jsadler Exp $
6 ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
7 ** All rights reserved.
9 ** Get the latest Ficl release at http://ficl.sourceforge.net
11 ** I am interested in hearing from anyone who uses ficl. If you have
12 ** a problem, a success story, a defect, an enhancement request, or
13 ** if you would like to contribute to the ficl release, please
14 ** contact me by email at the address above.
16 ** L I C E N S E and D I S C L A I M E R
18 ** Redistribution and use in source and binary forms, with or without
19 ** modification, are permitted provided that the following conditions
21 ** 1. Redistributions of source code must retain the above copyright
22 ** notice, this list of conditions and the following disclaimer.
23 ** 2. Redistributions in binary form must reproduce the above copyright
24 ** notice, this list of conditions and the following disclaimer in the
25 ** documentation and/or other materials provided with the distribution.
27 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 #include <sys/types.h>
52 ** Ficl interface to getcwd
53 ** Prints the current working directory using the VM's
56 static void ficlGetCWD(FICL_VM
*pVM
)
60 cp
= getcwd(NULL
, 80);
61 vmTextOut(pVM
, cp
, 1);
67 ** Ficl interface to chdir
68 ** Gets a newline (or NULL) delimited string from the input
69 ** and feeds it to chdir()
73 static void ficlChDir(FICL_VM
*pVM
)
75 FICL_STRING
*pFS
= (FICL_STRING
*)pVM
->pad
;
76 vmGetString(pVM
, pFS
, '\n');
79 int err
= chdir(pFS
->text
);
82 vmTextOut(pVM
, "Error: path not found", 1);
83 vmThrow(pVM
, VM_QUIT
);
88 vmTextOut(pVM
, "Warning (chdir): nothing happened", 1);
94 ** Ficl interface to system (ANSI)
95 ** Gets a newline (or NULL) delimited string from the input
96 ** and feeds it to system()
101 static void ficlSystem(FICL_VM
*pVM
)
103 FICL_STRING
*pFS
= (FICL_STRING
*)pVM
->pad
;
105 vmGetString(pVM
, pFS
, '\n');
108 int err
= system(pFS
->text
);
111 sprintf(pVM
->pad
, "System call returned %d", err
);
112 vmTextOut(pVM
, pVM
->pad
, 1);
113 vmThrow(pVM
, VM_QUIT
);
118 vmTextOut(pVM
, "Warning (system): nothing happened", 1);
124 ** Ficl add-in to load a text file and execute it...
125 ** Cheesy, but illustrative.
126 ** Line oriented... filename is newline (or NULL) delimited.
131 static void ficlLoad(FICL_VM
*pVM
)
134 char filename
[nLINEBUF
];
135 FICL_STRING
*pFilename
= (FICL_STRING
*)filename
;
143 vmGetString(pVM
, pFilename
, '\n');
145 if (pFilename
->count
<= 0)
147 vmTextOut(pVM
, "Warning (load): nothing happened", 1);
152 ** get the file's size and make sure it exists
154 result
= stat( pFilename
->text
, &buf
);
158 vmTextOut(pVM
, "Unable to stat file: ", 0);
159 vmTextOut(pVM
, pFilename
->text
, 1);
160 vmThrow(pVM
, VM_QUIT
);
163 fp
= fopen(pFilename
->text
, "r");
166 vmTextOut(pVM
, "Unable to open file ", 0);
167 vmTextOut(pVM
, pFilename
->text
, 1);
168 vmThrow(pVM
, VM_QUIT
);
172 pVM
->sourceID
.p
= (void *)fp
;
174 /* feed each line to ficlExec */
175 while (fgets(cp
, nLINEBUF
, fp
))
177 int len
= strlen(cp
) - 1;
183 result
= ficlExecC(pVM
, cp
, len
);
184 if (result
!= VM_QUIT
&& result
!= VM_USEREXIT
&& result
!= VM_OUTOFTEXT
)
188 vmThrowErr(pVM
, "Error loading file <%s> line %d", pFilename
->text
, nLine
);
193 ** Pass an empty line with SOURCE-ID == -1 to flush
194 ** any pending REFILLs (as required by FILE wordset)
196 pVM
->sourceID
.i
= -1;
202 /* handle "bye" in loaded files. --lch */
203 if (result
== VM_USEREXIT
)
204 vmThrow(pVM
, VM_USEREXIT
);
209 ** Dump a tab delimited file that summarizes the contents of the
210 ** dictionary hash table by hashcode...
212 static void spewHash(FICL_VM
*pVM
)
214 FICL_HASH
*pHash
= vmGetDict(pVM
)->pForthWords
;
218 unsigned nHash
= pHash
->size
;
220 if (!vmGetWordToPad(pVM
))
221 vmThrow(pVM
, VM_OUTOFTEXT
);
223 pOut
= fopen(pVM
->pad
, "w");
226 vmTextOut(pVM
, "unable to open file", 1);
230 for (i
=0; i
< nHash
; i
++)
234 pFW
= pHash
->table
[i
];
241 fprintf(pOut
, "%d\t%d", i
, n
);
243 pFW
= pHash
->table
[i
];
246 fprintf(pOut
, "\t%s", pFW
->name
);
257 static void ficlBreak(FICL_VM
*pVM
)
259 pVM
->state
= pVM
->state
;
263 static void ficlClock(FICL_VM
*pVM
)
265 clock_t now
= clock();
266 stackPushUNS(pVM
->pStack
, (FICL_UNS
)now
);
270 static void clocksPerSec(FICL_VM
*pVM
)
272 stackPushUNS(pVM
->pStack
, CLOCKS_PER_SEC
);
277 static void execxt(FICL_VM
*pVM
)
281 vmCheckStack(pVM
, 1, 0);
284 pFW
= stackPopPtr(pVM
->pStack
);
285 ficlExecXT(pVM
, pFW
);
291 void buildTestInterface(FICL_SYSTEM
*pSys
)
293 ficlBuild(pSys
, "break", ficlBreak
, FW_DEFAULT
);
294 ficlBuild(pSys
, "clock", ficlClock
, FW_DEFAULT
);
295 ficlBuild(pSys
, "cd", ficlChDir
, FW_DEFAULT
);
296 ficlBuild(pSys
, "execxt", execxt
, FW_DEFAULT
);
297 ficlBuild(pSys
, "load", ficlLoad
, FW_DEFAULT
);
298 ficlBuild(pSys
, "pwd", ficlGetCWD
, FW_DEFAULT
);
299 ficlBuild(pSys
, "system", ficlSystem
, FW_DEFAULT
);
300 ficlBuild(pSys
, "spewhash", spewHash
, FW_DEFAULT
);
301 ficlBuild(pSys
, "clocks/sec",
302 clocksPerSec
, FW_DEFAULT
);
308 int main(int argc
, char **argv
)
314 pSys
= ficlInitSystem(10000);
315 buildTestInterface(pSys
);
316 pVM
= ficlNewVM(pSys
);
318 ficlEvaluate(pVM
, ".ver .( " __DATE__
" ) cr quit");
321 ** load file from cmd line...
325 sprintf(in
, ".( loading %s ) cr load %s\n cr", argv
[1], argv
[1]);
326 ficlEvaluate(pVM
, in
);
332 if (fgets(in
, sizeof(in
) - 1, stdin
) == NULL
)
334 ret
= ficlExec(pVM
, in
);
335 if (ret
== VM_USEREXIT
)
337 ficlTermSystem(pSys
);