testmain.c revision 53633
1/* 2** stub main for testing FICL 3** 4*/ 5 6/* $FreeBSD: head/sys/boot/ficl/testmain.c 53633 1999-11-23 11:17:37Z dcs $ */ 7 8#include <stdlib.h> 9#include <stdio.h> 10#include <string.h> 11#include <time.h> 12#include <sys/types.h> 13#include <sys/stat.h> 14#include <unistd.h> 15 16#include "ficl.h" 17 18/* 19** Ficl interface to getcwd 20** Prints the current working directory using the VM's 21** textOut method... 22*/ 23static void ficlGetCWD(FICL_VM *pVM) 24{ 25 char *cp; 26 27 cp = getcwd(NULL, 80); 28 vmTextOut(pVM, cp, 1); 29 free(cp); 30 return; 31} 32 33/* 34** Ficl interface to chdir 35** Gets a newline (or NULL) delimited string from the input 36** and feeds it to chdir() 37** Example: 38** cd c:\tmp 39*/ 40static void ficlChDir(FICL_VM *pVM) 41{ 42 FICL_STRING *pFS = (FICL_STRING *)pVM->pad; 43 vmGetString(pVM, pFS, '\n'); 44 if (pFS->count > 0) 45 { 46 int err = chdir(pFS->text); 47 if (err) 48 { 49 vmTextOut(pVM, "Error: path not found", 1); 50 vmThrow(pVM, VM_QUIT); 51 } 52 } 53 else 54 { 55 vmTextOut(pVM, "Warning (chdir): nothing happened", 1); 56 } 57 return; 58} 59 60/* 61** Ficl interface to system (ANSI) 62** Gets a newline (or NULL) delimited string from the input 63** and feeds it to system() 64** Example: 65** system del *.* 66** \ ouch! 67*/ 68static void ficlSystem(FICL_VM *pVM) 69{ 70 FICL_STRING *pFS = (FICL_STRING *)pVM->pad; 71 72 vmGetString(pVM, pFS, '\n'); 73 if (pFS->count > 0) 74 { 75 int err = system(pFS->text); 76 if (err) 77 { 78 sprintf(pVM->pad, "System call returned %d", err); 79 vmTextOut(pVM, pVM->pad, 1); 80 vmThrow(pVM, VM_QUIT); 81 } 82 } 83 else 84 { 85 vmTextOut(pVM, "Warning (system): nothing happened", 1); 86 } 87 return; 88} 89 90/* 91** Ficl add-in to load a text file and execute it... 92** Cheesy, but illustrative. 93** Line oriented... filename is newline (or NULL) delimited. 94** Example: 95** load test.ficl 96*/ 97#define nLINEBUF 256 98static void ficlLoad(FICL_VM *pVM) 99{ 100 char cp[nLINEBUF]; 101 char filename[nLINEBUF]; 102 FICL_STRING *pFilename = (FICL_STRING *)filename; 103 int nLine = 0; 104 FILE *fp; 105 int result; 106 CELL id; 107 struct stat buf; 108 109 110 vmGetString(pVM, pFilename, '\n'); 111 112 if (pFilename->count <= 0) 113 { 114 vmTextOut(pVM, "Warning (load): nothing happened", 1); 115 return; 116 } 117 118 /* 119 ** get the file's size and make sure it exists 120 */ 121 result = stat( pFilename->text, &buf ); 122 123 if (result != 0) 124 { 125 vmTextOut(pVM, "Unable to stat file: ", 0); 126 vmTextOut(pVM, pFilename->text, 1); 127 vmThrow(pVM, VM_QUIT); 128 } 129 130 fp = fopen(pFilename->text, "r"); 131 if (!fp) 132 { 133 vmTextOut(pVM, "Unable to open file ", 0); 134 vmTextOut(pVM, pFilename->text, 1); 135 vmThrow(pVM, VM_QUIT); 136 } 137 138 id = pVM->sourceID; 139 pVM->sourceID.p = (void *)fp; 140 141 /* feed each line to ficlExec */ 142 while (fgets(cp, nLINEBUF, fp)) 143 { 144 int len = strlen(cp) - 1; 145 146 nLine++; 147 if (len <= 0) 148 continue; 149 150 result = ficlExecC(pVM, cp, len); 151 if (result != VM_QUIT && result != VM_USEREXIT && result != VM_OUTOFTEXT ) 152 { 153 pVM->sourceID = id; 154 fclose(fp); 155 vmThrowErr(pVM, "Error loading file <%s> line %d", pFilename->text, nLine); 156 break; 157 } 158 } 159 /* 160 ** Pass an empty line with SOURCE-ID == -1 to flush 161 ** any pending REFILLs (as required by FILE wordset) 162 */ 163 pVM->sourceID.i = -1; 164 ficlExec(pVM, ""); 165 166 pVM->sourceID = id; 167 fclose(fp); 168 169 return; 170} 171 172/* 173** Dump a tab delimited file that summarizes the contents of the 174** dictionary hash table by hashcode... 175*/ 176static void spewHash(FICL_VM *pVM) 177{ 178 FICL_HASH *pHash = ficlGetDict()->pForthWords; 179 FICL_WORD *pFW; 180 FILE *pOut; 181 unsigned i; 182 unsigned nHash = pHash->size; 183 184 if (!vmGetWordToPad(pVM)) 185 vmThrow(pVM, VM_OUTOFTEXT); 186 187 pOut = fopen(pVM->pad, "w"); 188 if (!pOut) 189 { 190 vmTextOut(pVM, "unable to open file", 1); 191 return; 192 } 193 194 for (i=0; i < nHash; i++) 195 { 196 int n = 0; 197 198 pFW = pHash->table[i]; 199 while (pFW) 200 { 201 n++; 202 pFW = pFW->link; 203 } 204 205 fprintf(pOut, "%d\t%d", i, n); 206 207 pFW = pHash->table[i]; 208 while (pFW) 209 { 210 fprintf(pOut, "\t%s", pFW->name); 211 pFW = pFW->link; 212 } 213 214 fprintf(pOut, "\n"); 215 } 216 217 fclose(pOut); 218 return; 219} 220 221static void ficlBreak(FICL_VM *pVM) 222{ 223 pVM->state = pVM->state; 224 return; 225} 226 227static void ficlClock(FICL_VM *pVM) 228{ 229 clock_t now = clock(); 230 stackPushUNS(pVM->pStack, (UNS32)now); 231 return; 232} 233 234static void clocksPerSec(FICL_VM *pVM) 235{ 236 stackPushUNS(pVM->pStack, CLOCKS_PER_SEC); 237 return; 238} 239 240 241static void execxt(FICL_VM *pVM) 242{ 243 FICL_WORD *pFW; 244#if FICL_ROBUST > 1 245 vmCheckStack(pVM, 1, 0); 246#endif 247 248 pFW = stackPopPtr(pVM->pStack); 249 ficlExecXT(pVM, pFW); 250 251 return; 252} 253 254 255void buildTestInterface(void) 256{ 257 ficlBuild("break", ficlBreak, FW_DEFAULT); 258 ficlBuild("clock", ficlClock, FW_DEFAULT); 259 ficlBuild("cd", ficlChDir, FW_DEFAULT); 260 ficlBuild("execxt", execxt, FW_DEFAULT); 261 ficlBuild("load", ficlLoad, FW_DEFAULT); 262 ficlBuild("pwd", ficlGetCWD, FW_DEFAULT); 263 ficlBuild("system", ficlSystem, FW_DEFAULT); 264 ficlBuild("spewhash", spewHash, FW_DEFAULT); 265 ficlBuild("clocks/sec", 266 clocksPerSec, FW_DEFAULT); 267 268 return; 269} 270 271 272int main(int argc, char **argv) 273{ 274 char in[256]; 275 FICL_VM *pVM; 276 277 ficlInitSystem(10000); 278 buildTestInterface(); 279 pVM = ficlNewVM(); 280 281 ficlExec(pVM, ".ver .( " __DATE__ " ) cr quit"); 282 283 /* 284 ** load file from cmd line... 285 */ 286 if (argc > 1) 287 { 288 sprintf(in, ".( loading %s ) cr load %s\n cr", argv[1], argv[1]); 289 ficlExec(pVM, in); 290 } 291 292 for (;;) 293 { 294 int ret; 295 if (fgets(in, sizeof(in) - 1, stdin) == NULL) 296 break; 297 ret = ficlExec(pVM, in); 298 if (ret == VM_USEREXIT) 299 { 300 ficlTermSystem(); 301 break; 302 } 303 } 304 305 return 0; 306} 307 308