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

Annotation of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide 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 masse 1.1 /* printf */
2     #include <stdio.h>
3     /* EXIT_SUCCESS */
4     #include <stdlib.h>
5     /* NULL */
6     #include <stddef.h>
7 teddy 1.3 /* dlopen, dlsym, dlerror */
8 masse 1.1 #include <dlfcn.h>
9    
10     #define HASHTBLSIZE 65536
11    
12     typedef struct stack_item
13     {
14 masse 1.7 enum {value, string, ref, func, symbol, list} type;
15 masse 1.1 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 masse 1.4 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 masse 1.1 int push_ref(stackitem** stack_head, hashtbl in_hash, const char* in_string)
123     {
124 masse 1.6 static void* handle= NULL;
125 masse 1.1 void* symbol;
126 masse 1.6
127 masse 1.1 stackitem* new_item= malloc(sizeof(stackitem));
128     new_item->content.ptr= *hash(in_hash, in_string);
129     new_item->type= ref;
130    
131 masse 1.9 if(new_item->content.ptr==NULL) {
132     if(handle==NULL)
133     handle= dlopen(NULL, RTLD_LAZY);
134 masse 1.6
135 masse 1.1 symbol= dlsym(handle, in_string);
136 masse 1.4 if(dlerror()==NULL)
137 masse 1.1 def_func(in_hash, symbol, in_string);
138 masse 1.4 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 masse 1.1 }
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 masse 1.7 if((*stack_head)==NULL)
154     return;
155    
156     if((*stack_head)->type==string)
157     free((*stack_head)->content.ptr);
158    
159 masse 1.1 *stack_head= (*stack_head)->next;
160     free(temp);
161     }
162    
163 masse 1.8 extern void nl()
164     {
165     printf("\n");
166     }
167 masse 1.1
168 masse 1.11 void print_(stackitem** stack_head)
169 masse 1.8 {
170     if((*stack_head)==NULL)
171     return;
172 masse 1.1
173 masse 1.8 switch((*stack_head)->type) {
174 teddy 1.2 case value:
175 masse 1.8 printf("%d", (*stack_head)->content.val);
176 teddy 1.2 break;
177     case string:
178 masse 1.8 printf("%s", (char*)(*stack_head)->content.ptr);
179 teddy 1.2 break;
180     case ref:
181 masse 1.8 printf("%s", ((stackitem*)(*stack_head)->content.ptr)->id);
182 masse 1.6 break;
183 masse 1.4 case symbol:
184 masse 1.7 default:
185 masse 1.8 printf("%p", (*stack_head)->content.ptr);
186 teddy 1.2 break;
187     }
188 masse 1.1 }
189    
190 masse 1.8 extern void print(stackitem** stack_head)
191     {
192 masse 1.11 print_(stack_head);
193 masse 1.8 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 masse 1.11 print_(&stack_head);
204 masse 1.8 nl();
205     }
206    
207 masse 1.1 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 masse 1.13 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 masse 1.1 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 masse 1.7 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 masse 1.1
296 masse 1.8 extern void expand(stackitem** stack_head)
297 masse 1.1 {
298 masse 1.8 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 teddy 1.5 }
312    
313 masse 1.10 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 masse 1.11
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 masse 1.12 swap(stack_head);
335     right= (*stack_head)->content.ptr;
336 masse 1.11 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 masse 1.12
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 masse 1.10
377 teddy 1.5 extern void quit()
378     {
379     exit(EXIT_SUCCESS);
380 masse 1.1 }
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 masse 1.10 exit(EXIT_SUCCESS);
398 masse 1.1 }
399 teddy 1.3
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