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

Annotation of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Mon Jan 7 23:13:14 2002 UTC (22 years, 3 months ago) by teddy
Branch: MAIN
Changes since 1.1: +9 -3 lines
File MIME type: text/plain
(print_st): Changed if...else to a switch...case.

1 masse 1.1 /* printf */
2     #include <stdio.h>
3     /* EXIT_SUCCESS */
4     #include <stdlib.h>
5     /* NULL */
6     #include <stddef.h>
7     #include <dlfcn.h>
8    
9     #define HASHTBLSIZE 65536
10    
11     typedef struct stack_item
12     {
13     enum {value, string, ref, func} type;
14     union {
15     void* ptr;
16     int val;
17     } content;
18    
19     char* id;
20     struct stack_item* next;
21     } stackitem;
22    
23    
24     typedef stackitem* hashtbl[HASHTBLSIZE];
25     typedef void (*funcp)(stackitem**);
26    
27     void init_hashtbl(hashtbl out_hash)
28     {
29     long i;
30    
31     for(i= 0; i<HASHTBLSIZE; i++)
32     out_hash[i]= NULL;
33     }
34    
35     stackitem** hash(hashtbl in_hashtbl, const char* in_string)
36     {
37     long i= 0;
38     unsigned long out_hash= 0;
39     char key= 0;
40     stackitem** position;
41    
42     while(1){
43     key= in_string[i++];
44     if(key=='\0')
45     break;
46     out_hash= out_hash*32+key;
47     }
48    
49     out_hash= out_hash%HASHTBLSIZE;
50     position= &(in_hashtbl[out_hash]);
51    
52     while(1){
53     if(*position==NULL)
54     return position;
55    
56     if(strcmp(in_string, (*position)->id)==0)
57     return position;
58    
59     position= &((*position)->next);
60     }
61     }
62    
63    
64     int push(stackitem** stack_head, stackitem* in_item)
65     {
66     in_item->next= *stack_head;
67     *stack_head= in_item;
68     return 1;
69     }
70    
71     int push_val(stackitem** stack_head, int in_val)
72     {
73     stackitem* new_item= malloc(sizeof(stackitem));
74     new_item->content.val= in_val;
75     new_item->type= value;
76    
77     push(stack_head, new_item);
78     return 1;
79     }
80    
81     int push_cstring(stackitem** stack_head, const char* in_string)
82     {
83     stackitem* new_item= malloc(sizeof(stackitem));
84     new_item->content.ptr= malloc(strlen(in_string)+1);
85     strcpy(new_item->content.ptr, in_string);
86     new_item->type= string;
87    
88     push(stack_head, new_item);
89     return 1;
90     }
91    
92     int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)
93     {
94     in_item->id= malloc(strlen(id)+1);
95    
96     strcpy(in_item->id, id);
97     push(hash(in_hashtbl, id), in_item);
98    
99     return 1;
100     }
101    
102     void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)
103     {
104     stackitem* temp= malloc(sizeof(stackitem));
105    
106     temp->type= func;
107     temp->content.ptr= in_func;
108    
109     mk_hashentry(in_hashtbl, temp, id);
110     }
111    
112     int push_ref(stackitem** stack_head, hashtbl in_hash, const char* in_string)
113     {
114     void* handle;
115     void* symbol;
116    
117     stackitem* new_item= malloc(sizeof(stackitem));
118     new_item->content.ptr= *hash(in_hash, in_string);
119     new_item->type= ref;
120    
121     if(new_item->content.ptr==NULL) {
122     handle= dlopen(NULL, RTLD_LAZY);
123     symbol= dlsym(handle, in_string);
124     if(dlerror()==NULL) {
125     def_func(in_hash, symbol, in_string);
126     new_item->content.ptr= *hash(in_hash, in_string);
127     new_item->type= ref;
128     }
129     }
130    
131     push(stack_head, new_item);
132     return 1;
133     }
134    
135     extern void toss(stackitem** stack_head)
136     {
137     stackitem* temp= *stack_head;
138    
139     *stack_head= (*stack_head)->next;
140     free(temp);
141     }
142    
143    
144     /* print_stack(stack); */
145     void print_st(stackitem* stack_head, long counter)
146     {
147     if(stack_head->next != NULL)
148     print_st(stack_head->next, counter+1);
149    
150 teddy 1.2 switch(stack_head->type){
151     case value:
152 masse 1.1 printf("%ld: %d\n", counter, (int)stack_head->content.val);
153 teddy 1.2 break;
154     case string:
155 masse 1.1 printf("%ld: \"%s\"\n", counter, (char*)stack_head->content.ptr);
156 teddy 1.2 break;
157     case ref:
158     case func:
159 masse 1.1 printf("%ld: %p\n", counter, stack_head->content.ptr);
160 teddy 1.2 break;
161     }
162 masse 1.1 }
163    
164     extern void printstack(stackitem** stack_head)
165     {
166     if(*stack_head != NULL) {
167     print_st(*stack_head, 1);
168     printf("\n");
169     }
170     }
171    
172    
173     extern void eval(stackitem** stack_head)
174     {
175     funcp in_func;
176    
177     if((*stack_head)==NULL || (*stack_head)->type!=ref)
178     return;
179    
180     if(((stackitem*)(*stack_head)->content.ptr)->type==func) {
181     in_func= (funcp)((stackitem*)(*stack_head)->content.ptr)->content.ptr;
182     toss(stack_head);
183     (*in_func)(stack_head);
184     return;
185     }
186     }
187    
188     int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)
189     {
190     char *temp, *rest;
191     int itemp;
192     size_t inlength= strlen(in_line)+1;
193     int convert= 0;
194    
195     temp= malloc(inlength);
196     rest= malloc(inlength);
197    
198     if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest)) >= 1)
199     push_cstring(stack_head, temp);
200     else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)
201     push_val(stack_head, itemp);
202     else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)
203     push_ref(stack_head, in_hash, temp);
204     else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)
205     if(*temp==';')
206     eval(stack_head);
207    
208     free(temp);
209    
210     if(convert<2) {
211     free(rest);
212     return 0;
213     }
214    
215     stack_read(stack_head, in_hash, rest);
216    
217     free(rest);
218     return 1;
219     }
220    
221     extern void print(stackitem** stack_head)
222     {
223     if((*stack_head)==NULL)
224     return;
225    
226     if((*stack_head)->type==value)
227     printf("%d", (*stack_head)->content.val);
228     else if((*stack_head)->type==string)
229     printf("%s", (char*)(*stack_head)->content.ptr);
230     else
231     printf("%p", (*stack_head)->content.ptr);
232    
233     toss(stack_head);
234     }
235    
236     extern void nl()
237     {
238     printf("\n");
239     }
240    
241     int main()
242     {
243     stackitem* s= NULL;
244     hashtbl myhash;
245     char in_string[100];
246    
247     init_hashtbl(myhash);
248    
249     printf("okidok\n ");
250    
251     while(fgets(in_string, 100, stdin) != NULL) {
252     stack_read(&s, myhash, in_string);
253     printf("okidok\n ");
254     }
255    
256    
257     return EXIT_SUCCESS;
258     }

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26