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

Annotation of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations)
Mon Jan 7 23:31:34 2002 UTC (22 years, 3 months ago) by teddy
Branch: MAIN
Changes since 1.2: +5 -0 lines
File MIME type: text/plain
Added some comments.

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

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26