/[cvs]/stack/stack.c
ViewVC logotype

Contents of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Wed Jan 9 05:01:24 2002 UTC (22 years, 3 months ago) by masse
Branch: MAIN
Changes since 1.12: +3 -1 lines
File MIME type: text/plain
stack_read modified to accept single characters escaped with backslash.

1 /* printf */
2 #include <stdio.h>
3 /* EXIT_SUCCESS */
4 #include <stdlib.h>
5 /* NULL */
6 #include <stddef.h>
7 /* dlopen, dlsym, dlerror */
8 #include <dlfcn.h>
9
10 #define HASHTBLSIZE 65536
11
12 typedef struct stack_item
13 {
14 enum {value, string, ref, func, symbol, list} type;
15 union {
16 void* ptr;
17 int val;
18 } content;
19
20 char* id;
21 struct stack_item* next;
22 } stackitem;
23
24
25 typedef stackitem* hashtbl[HASHTBLSIZE];
26 typedef void (*funcp)(stackitem**);
27
28 void init_hashtbl(hashtbl out_hash)
29 {
30 long i;
31
32 for(i= 0; i<HASHTBLSIZE; i++)
33 out_hash[i]= NULL;
34 }
35
36 stackitem** hash(hashtbl in_hashtbl, const char* in_string)
37 {
38 long i= 0;
39 unsigned long out_hash= 0;
40 char key= 0;
41 stackitem** position;
42
43 while(1){
44 key= in_string[i++];
45 if(key=='\0')
46 break;
47 out_hash= out_hash*32+key;
48 }
49
50 out_hash= out_hash%HASHTBLSIZE;
51 position= &(in_hashtbl[out_hash]);
52
53 while(1){
54 if(*position==NULL)
55 return position;
56
57 if(strcmp(in_string, (*position)->id)==0)
58 return position;
59
60 position= &((*position)->next);
61 }
62 }
63
64
65 int push(stackitem** stack_head, stackitem* in_item)
66 {
67 in_item->next= *stack_head;
68 *stack_head= in_item;
69 return 1;
70 }
71
72 int push_val(stackitem** stack_head, int in_val)
73 {
74 stackitem* new_item= malloc(sizeof(stackitem));
75 new_item->content.val= in_val;
76 new_item->type= value;
77
78 push(stack_head, new_item);
79 return 1;
80 }
81
82 int push_cstring(stackitem** stack_head, const char* in_string)
83 {
84 stackitem* new_item= malloc(sizeof(stackitem));
85 new_item->content.ptr= malloc(strlen(in_string)+1);
86 strcpy(new_item->content.ptr, in_string);
87 new_item->type= string;
88
89 push(stack_head, new_item);
90 return 1;
91 }
92
93 int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)
94 {
95 in_item->id= malloc(strlen(id)+1);
96
97 strcpy(in_item->id, id);
98 push(hash(in_hashtbl, id), in_item);
99
100 return 1;
101 }
102
103 void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)
104 {
105 stackitem* temp= malloc(sizeof(stackitem));
106
107 temp->type= func;
108 temp->content.ptr= in_func;
109
110 mk_hashentry(in_hashtbl, temp, id);
111 }
112
113 void def_sym(hashtbl in_hashtbl, const char* id)
114 {
115 stackitem* temp= malloc(sizeof(stackitem));
116
117 temp->type= symbol;
118
119 mk_hashentry(in_hashtbl, temp, id);
120 }
121
122 int push_ref(stackitem** stack_head, hashtbl in_hash, const char* in_string)
123 {
124 static void* handle= NULL;
125 void* symbol;
126
127 stackitem* new_item= malloc(sizeof(stackitem));
128 new_item->content.ptr= *hash(in_hash, in_string);
129 new_item->type= ref;
130
131 if(new_item->content.ptr==NULL) {
132 if(handle==NULL)
133 handle= dlopen(NULL, RTLD_LAZY);
134
135 symbol= dlsym(handle, in_string);
136 if(dlerror()==NULL)
137 def_func(in_hash, symbol, in_string);
138 else
139 def_sym(in_hash, in_string);
140
141 new_item->content.ptr= *hash(in_hash, in_string);
142 new_item->type= ref;
143 }
144
145 push(stack_head, new_item);
146 return 1;
147 }
148
149 extern void toss(stackitem** stack_head)
150 {
151 stackitem* temp= *stack_head;
152
153 if((*stack_head)==NULL)
154 return;
155
156 if((*stack_head)->type==string)
157 free((*stack_head)->content.ptr);
158
159 *stack_head= (*stack_head)->next;
160 free(temp);
161 }
162
163 extern void nl()
164 {
165 printf("\n");
166 }
167
168 void print_(stackitem** stack_head)
169 {
170 if((*stack_head)==NULL)
171 return;
172
173 switch((*stack_head)->type) {
174 case value:
175 printf("%d", (*stack_head)->content.val);
176 break;
177 case string:
178 printf("%s", (char*)(*stack_head)->content.ptr);
179 break;
180 case ref:
181 printf("%s", ((stackitem*)(*stack_head)->content.ptr)->id);
182 break;
183 case symbol:
184 default:
185 printf("%p", (*stack_head)->content.ptr);
186 break;
187 }
188 }
189
190 extern void print(stackitem** stack_head)
191 {
192 print_(stack_head);
193 toss(stack_head);
194 }
195
196 /* print_stack(stack); */
197 void print_st(stackitem* stack_head, long counter)
198 {
199 if(stack_head->next != NULL)
200 print_st(stack_head->next, counter+1);
201
202 printf("%ld: ", counter);
203 print_(&stack_head);
204 nl();
205 }
206
207 extern void printstack(stackitem** stack_head)
208 {
209 if(*stack_head != NULL) {
210 print_st(*stack_head, 1);
211 printf("\n");
212 }
213 }
214
215
216 extern void eval(stackitem** stack_head)
217 {
218 funcp in_func;
219
220 if((*stack_head)==NULL || (*stack_head)->type!=ref)
221 return;
222
223 if(((stackitem*)(*stack_head)->content.ptr)->type==func) {
224 in_func= (funcp)((stackitem*)(*stack_head)->content.ptr)->content.ptr;
225 toss(stack_head);
226 (*in_func)(stack_head);
227 return;
228 }
229 }
230
231 int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)
232 {
233 char *temp, *rest;
234 int itemp;
235 size_t inlength= strlen(in_line)+1;
236 int convert= 0;
237
238 temp= malloc(inlength);
239 rest= malloc(inlength);
240
241 if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest)) >= 1)
242 push_cstring(stack_head, temp);
243 else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)
244 push_val(stack_head, itemp);
245 else if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest)) >= 1) {
246 temp[1]= '\0'; push_ref(stack_head, in_hash, temp);
247 } else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)
248 push_ref(stack_head, in_hash, temp);
249 else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)
250 if(*temp==';')
251 eval(stack_head);
252
253 free(temp);
254
255 if(convert<2) {
256 free(rest);
257 return 0;
258 }
259
260 stack_read(stack_head, in_hash, rest);
261
262 free(rest);
263 return 1;
264 }
265
266 extern void pack(stackitem** stack_head)
267 {
268 void* delimiter;
269 stackitem *iterator, *temp, *pack;
270
271 if((*stack_head)==NULL)
272 return;
273
274 delimiter= (*stack_head)->content.ptr;
275 toss(stack_head);
276
277 iterator= *stack_head;
278
279 while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)
280 iterator= iterator->next;
281
282 temp= *stack_head;
283 *stack_head= iterator->next;
284 iterator->next= NULL;
285
286 if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)
287 toss(stack_head);
288
289 pack= malloc(sizeof(stackitem));
290 pack->type= list;
291 pack->content.ptr= temp;
292
293 push(stack_head, pack);
294 }
295
296 extern void expand(stackitem** stack_head)
297 {
298 stackitem *temp, *new_head;
299
300 if((*stack_head)==NULL || (*stack_head)->type!=list)
301 return;
302
303 new_head= temp= (*stack_head)->content.ptr;
304 toss(stack_head);
305
306 while(temp->next!=NULL)
307 temp= temp->next;
308
309 temp->next= *stack_head;
310 *stack_head= new_head;
311 }
312
313 extern void swap(stackitem** stack_head)
314 {
315 stackitem* temp= (*stack_head);
316
317 if((*stack_head)==NULL || (*stack_head)->next==NULL)
318 return;
319
320 *stack_head= (*stack_head)->next;
321 temp->next= (*stack_head)->next;
322 (*stack_head)->next= temp;
323 }
324
325 extern void eq(stackitem** stack_head)
326 {
327 void *left, *right;
328 int result;
329
330 if((*stack_head)==NULL || (*stack_head)->next==NULL)
331 return;
332
333 left= (*stack_head)->content.ptr;
334 swap(stack_head);
335 right= (*stack_head)->content.ptr;
336 result= (left==right);
337
338 toss(stack_head); toss(stack_head);
339 push_val(stack_head, (left==right));
340 }
341
342 extern void not(stackitem** stack_head)
343 {
344 int value;
345
346 if((*stack_head)==NULL)
347 return;
348
349 value= (*stack_head)->content.val;
350 toss(stack_head);
351 push_val(stack_head, !value);
352 }
353
354 extern void neq(stackitem** stack_head)
355 {
356 eq(stack_head);
357 not(stack_head);
358 }
359
360 extern void def(stackitem** stack_head)
361 {
362 stackitem *temp, *value;
363
364 if(*stack_head==NULL || (*stack_head)->next==NULL
365 || (*stack_head)->type!=ref)
366 return;
367
368 temp= (*stack_head)->content.ptr;
369 value= (*stack_head)->next;
370 temp->content= value->content;
371 value->content.ptr=NULL;
372 temp->type= value->type;
373
374 toss(stack_head); toss(stack_head);
375 }
376
377 extern void quit()
378 {
379 exit(EXIT_SUCCESS);
380 }
381
382 int main()
383 {
384 stackitem* s= NULL;
385 hashtbl myhash;
386 char in_string[100];
387
388 init_hashtbl(myhash);
389
390 printf("okidok\n ");
391
392 while(fgets(in_string, 100, stdin) != NULL) {
393 stack_read(&s, myhash, in_string);
394 printf("okidok\n ");
395 }
396
397 exit(EXIT_SUCCESS);
398 }
399
400 /* Local Variables: */
401 /* compile-command:"make CFLAGS=\"-Wall -g -rdynamic -ldl\" stack" */
402 /* End: */

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26