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

Contents of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Tue Jan 8 00:03:16 2002 UTC (22 years, 3 months ago) by teddy
Branch: MAIN
Changes since 1.4: +16 -3 lines
File MIME type: text/plain
(print): Changed if...else to a switch...case.
(quit): New function.

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} 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 void* handle;
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 handle= dlopen(NULL, RTLD_LAZY);
133 symbol= dlsym(handle, in_string);
134 if(dlerror()==NULL)
135 def_func(in_hash, symbol, in_string);
136 else
137 def_sym(in_hash, in_string);
138
139 new_item->content.ptr= *hash(in_hash, in_string);
140 new_item->type= ref;
141 }
142
143 push(stack_head, new_item);
144 return 1;
145 }
146
147 extern void toss(stackitem** stack_head)
148 {
149 stackitem* temp= *stack_head;
150
151 *stack_head= (*stack_head)->next;
152 free(temp);
153 }
154
155
156 /* print_stack(stack); */
157 void print_st(stackitem* stack_head, long counter)
158 {
159 if(stack_head->next != NULL)
160 print_st(stack_head->next, counter+1);
161
162 switch(stack_head->type){
163 case value:
164 printf("%ld: %d\n", counter, (int)stack_head->content.val);
165 break;
166 case string:
167 printf("%ld: \"%s\"\n", counter, (char*)stack_head->content.ptr);
168 break;
169 case ref:
170 case func:
171 case symbol:
172 printf("%ld: %p\n", counter, stack_head->content.ptr);
173 break;
174 }
175 }
176
177 extern void printstack(stackitem** stack_head)
178 {
179 if(*stack_head != NULL) {
180 print_st(*stack_head, 1);
181 printf("\n");
182 }
183 }
184
185
186 extern void eval(stackitem** stack_head)
187 {
188 funcp in_func;
189
190 if((*stack_head)==NULL || (*stack_head)->type!=ref)
191 return;
192
193 if(((stackitem*)(*stack_head)->content.ptr)->type==func) {
194 in_func= (funcp)((stackitem*)(*stack_head)->content.ptr)->content.ptr;
195 toss(stack_head);
196 (*in_func)(stack_head);
197 return;
198 }
199 }
200
201 int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)
202 {
203 char *temp, *rest;
204 int itemp;
205 size_t inlength= strlen(in_line)+1;
206 int convert= 0;
207
208 temp= malloc(inlength);
209 rest= malloc(inlength);
210
211 if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest)) >= 1)
212 push_cstring(stack_head, temp);
213 else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)
214 push_val(stack_head, itemp);
215 else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)
216 push_ref(stack_head, in_hash, temp);
217 else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)
218 if(*temp==';')
219 eval(stack_head);
220
221 free(temp);
222
223 if(convert<2) {
224 free(rest);
225 return 0;
226 }
227
228 stack_read(stack_head, in_hash, rest);
229
230 free(rest);
231 return 1;
232 }
233
234 extern void print(stackitem** stack_head)
235 {
236 if((*stack_head)==NULL)
237 return;
238
239 switch((*stack_head)->type){
240 case value:
241 printf("%d", (*stack_head)->content.val);
242 break;
243 case string:
244 printf("%s", (char*)(*stack_head)->content.ptr);
245 break;
246 case symbol:
247 printf("%s", (*stack_head)->id);
248 case ref:
249 default:
250 printf("%p", (*stack_head)->content.ptr);
251 break;
252 }
253
254 toss(stack_head);
255 }
256
257 extern void nl()
258 {
259 printf("\n");
260 }
261
262 extern void quit()
263 {
264 exit(EXIT_SUCCESS);
265 }
266
267 int main()
268 {
269 stackitem* s= NULL;
270 hashtbl myhash;
271 char in_string[100];
272
273 init_hashtbl(myhash);
274
275 printf("okidok\n ");
276
277 while(fgets(in_string, 100, stdin) != NULL) {
278 stack_read(&s, myhash, in_string);
279 printf("okidok\n ");
280 }
281
282
283 return EXIT_SUCCESS;
284 }
285
286 /* Local Variables: */
287 /* compile-command:"make CFLAGS=\"-Wall -g -rdynamic -ldl\" stack" */
288 /* End: */

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26