xref: /titanic_53/usr/src/common/ficl/extras.c (revision a1bf3f785ae05c419b339c3a2061f2b18c024f61)
1*a1bf3f78SToomas Soome #include "ficl.h"
2*a1bf3f78SToomas Soome #include <unistd.h>
3*a1bf3f78SToomas Soome #include <stdio.h>
4*a1bf3f78SToomas Soome #include <stdlib.h>
5*a1bf3f78SToomas Soome 
6*a1bf3f78SToomas Soome /*
7*a1bf3f78SToomas Soome  * Ficl interface to system (ANSI)
8*a1bf3f78SToomas Soome  * Gets a newline (or NULL) delimited string from the input
9*a1bf3f78SToomas Soome  * and feeds it to the ANSI system function...
10*a1bf3f78SToomas Soome  * Example:
11*a1bf3f78SToomas Soome  *    system del *.*
12*a1bf3f78SToomas Soome  *    \ ouch!
13*a1bf3f78SToomas Soome  */
14*a1bf3f78SToomas Soome static void
ficlPrimitiveSystem(ficlVm * vm)15*a1bf3f78SToomas Soome ficlPrimitiveSystem(ficlVm *vm)
16*a1bf3f78SToomas Soome {
17*a1bf3f78SToomas Soome 	ficlCountedString *counted = (ficlCountedString *)vm->pad;
18*a1bf3f78SToomas Soome 
19*a1bf3f78SToomas Soome 	ficlVmGetString(vm, counted, '\n');
20*a1bf3f78SToomas Soome 	if (FICL_COUNTED_STRING_GET_LENGTH(*counted) > 0) {
21*a1bf3f78SToomas Soome 		int returnValue = \
22*a1bf3f78SToomas Soome 		    system(FICL_COUNTED_STRING_GET_POINTER(*counted));
23*a1bf3f78SToomas Soome 		if (returnValue) {
24*a1bf3f78SToomas Soome 			sprintf(vm->pad, "System call returned %d\n",
25*a1bf3f78SToomas Soome 			    returnValue);
26*a1bf3f78SToomas Soome 			ficlVmTextOut(vm, vm->pad);
27*a1bf3f78SToomas Soome 			ficlVmThrow(vm, FICL_VM_STATUS_QUIT);
28*a1bf3f78SToomas Soome 		}
29*a1bf3f78SToomas Soome 	} else {
30*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, "Warning (system): nothing happened\n");
31*a1bf3f78SToomas Soome 	}
32*a1bf3f78SToomas Soome }
33*a1bf3f78SToomas Soome 
34*a1bf3f78SToomas Soome /*
35*a1bf3f78SToomas Soome  * Ficl add-in to load a text file and execute it...
36*a1bf3f78SToomas Soome  * Cheesy, but illustrative.
37*a1bf3f78SToomas Soome  * Line oriented... filename is newline (or NULL) delimited.
38*a1bf3f78SToomas Soome  * Example:
39*a1bf3f78SToomas Soome  *    load test.f
40*a1bf3f78SToomas Soome  */
41*a1bf3f78SToomas Soome #define	BUFFER_SIZE	256
42*a1bf3f78SToomas Soome static void
ficlPrimitiveLoad(ficlVm * vm)43*a1bf3f78SToomas Soome ficlPrimitiveLoad(ficlVm *vm)
44*a1bf3f78SToomas Soome {
45*a1bf3f78SToomas Soome 	char buffer[BUFFER_SIZE];
46*a1bf3f78SToomas Soome 	char filename[BUFFER_SIZE];
47*a1bf3f78SToomas Soome 	ficlCountedString *counted = (ficlCountedString *)filename;
48*a1bf3f78SToomas Soome 	int line = 0;
49*a1bf3f78SToomas Soome 	FILE *f;
50*a1bf3f78SToomas Soome 	int result = 0;
51*a1bf3f78SToomas Soome 	ficlCell oldSourceId;
52*a1bf3f78SToomas Soome 	ficlString s;
53*a1bf3f78SToomas Soome 
54*a1bf3f78SToomas Soome 	ficlVmGetString(vm, counted, '\n');
55*a1bf3f78SToomas Soome 
56*a1bf3f78SToomas Soome 	if (FICL_COUNTED_STRING_GET_LENGTH(*counted) <= 0) {
57*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, "Warning (load): nothing happened\n");
58*a1bf3f78SToomas Soome 		return;
59*a1bf3f78SToomas Soome 	}
60*a1bf3f78SToomas Soome 
61*a1bf3f78SToomas Soome 	/*
62*a1bf3f78SToomas Soome 	 * get the file's size and make sure it exists
63*a1bf3f78SToomas Soome 	 */
64*a1bf3f78SToomas Soome 
65*a1bf3f78SToomas Soome 	f = fopen(FICL_COUNTED_STRING_GET_POINTER(*counted), "r");
66*a1bf3f78SToomas Soome 	if (!f) {
67*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, "Unable to open file ");
68*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, FICL_COUNTED_STRING_GET_POINTER(*counted));
69*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, "\n");
70*a1bf3f78SToomas Soome 		ficlVmThrow(vm, FICL_VM_STATUS_QUIT);
71*a1bf3f78SToomas Soome 	}
72*a1bf3f78SToomas Soome 
73*a1bf3f78SToomas Soome 	oldSourceId = vm->sourceId;
74*a1bf3f78SToomas Soome 	vm->sourceId.p = (void *)f;
75*a1bf3f78SToomas Soome 
76*a1bf3f78SToomas Soome 	/* feed each line to ficlExec */
77*a1bf3f78SToomas Soome 	while (fgets(buffer, BUFFER_SIZE, f)) {
78*a1bf3f78SToomas Soome 		int length = strlen(buffer) - 1;
79*a1bf3f78SToomas Soome 
80*a1bf3f78SToomas Soome 		line++;
81*a1bf3f78SToomas Soome 		if (length <= 0)
82*a1bf3f78SToomas Soome 			continue;
83*a1bf3f78SToomas Soome 
84*a1bf3f78SToomas Soome 		if (buffer[length] == '\n')
85*a1bf3f78SToomas Soome 			buffer[length--] = '\0';
86*a1bf3f78SToomas Soome 
87*a1bf3f78SToomas Soome 		FICL_STRING_SET_POINTER(s, buffer);
88*a1bf3f78SToomas Soome 		FICL_STRING_SET_LENGTH(s, length + 1);
89*a1bf3f78SToomas Soome 		result = ficlVmExecuteString(vm, s);
90*a1bf3f78SToomas Soome 		/* handle "bye" in loaded files. --lch */
91*a1bf3f78SToomas Soome 		switch (result) {
92*a1bf3f78SToomas Soome 		case FICL_VM_STATUS_OUT_OF_TEXT:
93*a1bf3f78SToomas Soome 		case FICL_VM_STATUS_USER_EXIT:
94*a1bf3f78SToomas Soome 		break;
95*a1bf3f78SToomas Soome 
96*a1bf3f78SToomas Soome 		default:
97*a1bf3f78SToomas Soome 			vm->sourceId = oldSourceId;
98*a1bf3f78SToomas Soome 			fclose(f);
99*a1bf3f78SToomas Soome 			ficlVmThrowError(vm, "Error loading file <%s> line %d",
100*a1bf3f78SToomas Soome 			    FICL_COUNTED_STRING_GET_POINTER(*counted), line);
101*a1bf3f78SToomas Soome 		break;
102*a1bf3f78SToomas Soome 		}
103*a1bf3f78SToomas Soome 	}
104*a1bf3f78SToomas Soome 	/*
105*a1bf3f78SToomas Soome 	 * Pass an empty line with SOURCE-ID == -1 to flush
106*a1bf3f78SToomas Soome 	 * any pending REFILLs (as required by FILE wordset)
107*a1bf3f78SToomas Soome 	 */
108*a1bf3f78SToomas Soome 	vm->sourceId.i = -1;
109*a1bf3f78SToomas Soome 	FICL_STRING_SET_FROM_CSTRING(s, "");
110*a1bf3f78SToomas Soome 	ficlVmExecuteString(vm, s);
111*a1bf3f78SToomas Soome 
112*a1bf3f78SToomas Soome 	vm->sourceId = oldSourceId;
113*a1bf3f78SToomas Soome 	fclose(f);
114*a1bf3f78SToomas Soome 
115*a1bf3f78SToomas Soome 	/* handle "bye" in loaded files. --lch */
116*a1bf3f78SToomas Soome 	if (result == FICL_VM_STATUS_USER_EXIT)
117*a1bf3f78SToomas Soome 		ficlVmThrow(vm, FICL_VM_STATUS_USER_EXIT);
118*a1bf3f78SToomas Soome }
119*a1bf3f78SToomas Soome 
120*a1bf3f78SToomas Soome /*
121*a1bf3f78SToomas Soome  * Dump a tab delimited file that summarizes the contents of the
122*a1bf3f78SToomas Soome  * dictionary hash table by hashcode...
123*a1bf3f78SToomas Soome  */
124*a1bf3f78SToomas Soome static void
ficlPrimitiveSpewHash(ficlVm * vm)125*a1bf3f78SToomas Soome ficlPrimitiveSpewHash(ficlVm *vm)
126*a1bf3f78SToomas Soome {
127*a1bf3f78SToomas Soome 	ficlHash *hash = ficlVmGetDictionary(vm)->forthWordlist;
128*a1bf3f78SToomas Soome 	ficlWord *word;
129*a1bf3f78SToomas Soome 	FILE *f;
130*a1bf3f78SToomas Soome 	unsigned i;
131*a1bf3f78SToomas Soome 	unsigned hashSize = hash->size;
132*a1bf3f78SToomas Soome 
133*a1bf3f78SToomas Soome 	if (!ficlVmGetWordToPad(vm))
134*a1bf3f78SToomas Soome 		ficlVmThrow(vm, FICL_VM_STATUS_OUT_OF_TEXT);
135*a1bf3f78SToomas Soome 
136*a1bf3f78SToomas Soome 	f = fopen(vm->pad, "w");
137*a1bf3f78SToomas Soome 	if (!f) {
138*a1bf3f78SToomas Soome 		ficlVmTextOut(vm, "unable to open file\n");
139*a1bf3f78SToomas Soome 		return;
140*a1bf3f78SToomas Soome 	}
141*a1bf3f78SToomas Soome 
142*a1bf3f78SToomas Soome 	for (i = 0; i < hashSize; i++) {
143*a1bf3f78SToomas Soome 		int n = 0;
144*a1bf3f78SToomas Soome 
145*a1bf3f78SToomas Soome 		word = hash->table[i];
146*a1bf3f78SToomas Soome 		while (word) {
147*a1bf3f78SToomas Soome 			n++;
148*a1bf3f78SToomas Soome 			word = word->link;
149*a1bf3f78SToomas Soome 		}
150*a1bf3f78SToomas Soome 
151*a1bf3f78SToomas Soome 		fprintf(f, "%d\t%d", i, n);
152*a1bf3f78SToomas Soome 
153*a1bf3f78SToomas Soome 		word = hash->table[i];
154*a1bf3f78SToomas Soome 		while (word) {
155*a1bf3f78SToomas Soome 			fprintf(f, "\t%s", word->name);
156*a1bf3f78SToomas Soome 			word = word->link;
157*a1bf3f78SToomas Soome 		}
158*a1bf3f78SToomas Soome 
159*a1bf3f78SToomas Soome 		fprintf(f, "\n");
160*a1bf3f78SToomas Soome 	}
161*a1bf3f78SToomas Soome 
162*a1bf3f78SToomas Soome 	fclose(f);
163*a1bf3f78SToomas Soome }
164*a1bf3f78SToomas Soome 
165*a1bf3f78SToomas Soome static void
ficlPrimitiveBreak(ficlVm * vm)166*a1bf3f78SToomas Soome ficlPrimitiveBreak(ficlVm *vm)
167*a1bf3f78SToomas Soome {
168*a1bf3f78SToomas Soome 	vm->state = vm->state;
169*a1bf3f78SToomas Soome }
170*a1bf3f78SToomas Soome 
171*a1bf3f78SToomas Soome void
ficlSystemCompileExtras(ficlSystem * system)172*a1bf3f78SToomas Soome ficlSystemCompileExtras(ficlSystem *system)
173*a1bf3f78SToomas Soome {
174*a1bf3f78SToomas Soome 	ficlDictionary *dictionary = ficlSystemGetDictionary(system);
175*a1bf3f78SToomas Soome 
176*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "break", ficlPrimitiveBreak,
177*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
178*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "load", ficlPrimitiveLoad,
179*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
180*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "spewhash",
181*a1bf3f78SToomas Soome 	    ficlPrimitiveSpewHash, FICL_WORD_DEFAULT);
182*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "system", ficlPrimitiveSystem,
183*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
184*a1bf3f78SToomas Soome }
185