1 |
/* |
2 |
* HT Editor |
3 |
* parsehelper.c |
4 |
* |
5 |
* Copyright (C) 2003 Stefan Weyergraf (stefan@weyergraf.de) |
6 |
* |
7 |
* This program is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License version 2 as |
9 |
* published by the Free Software Foundation. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 |
*/ |
20 |
|
21 |
#include <stdarg.h> |
22 |
#include <stdlib.h> |
23 |
#include <string.h> |
24 |
|
25 |
#include "tools/snprintf.h" |
26 |
#include "debugtype.h" |
27 |
#include "parsehelper.h" |
28 |
#include "lex.h" |
29 |
|
30 |
/* |
31 |
* ERROR HANDLING |
32 |
*/ |
33 |
static int eval_error; |
34 |
static int eval_error_pos; |
35 |
static char eval_errstr[MAX_ERRSTR_LEN]; |
36 |
|
37 |
void clear_eval_error() |
38 |
{ |
39 |
eval_error = 0; |
40 |
} |
41 |
|
42 |
int get_eval_error(char **str, int *pos) |
43 |
{ |
44 |
if (eval_error) { |
45 |
if (str) *str = eval_errstr; |
46 |
if (pos) *pos = eval_error_pos; |
47 |
return eval_error; |
48 |
} |
49 |
if (str) *str = "?"; |
50 |
if (pos) *pos = 0; |
51 |
return 0; |
52 |
} |
53 |
|
54 |
void set_eval_error(char *errmsg) |
55 |
{ |
56 |
strncpy(eval_errstr, errmsg, sizeof eval_errstr-1); |
57 |
eval_errstr[sizeof eval_errstr-1] = 0; |
58 |
eval_error_pos = lex_current_buffer_pos(); |
59 |
eval_error = 1; |
60 |
} |
61 |
|
62 |
/* |
63 |
* SCALARLIST |
64 |
*/ |
65 |
void scalarlist_set(struct eval_scalarlist *l, struct eval_scalar *s) |
66 |
{ |
67 |
l->count = 1; |
68 |
l->scalars = (struct eval_scalar*)malloc(sizeof (struct eval_scalar) * l->count); |
69 |
l->scalars[0] = *s; |
70 |
} |
71 |
|
72 |
void scalarlist_concat(struct eval_scalarlist *l, struct eval_scalarlist *a, struct eval_scalarlist *b) |
73 |
{ |
74 |
l->count = a->count+b->count; |
75 |
l->scalars = (struct eval_scalar*)malloc(sizeof (struct eval_scalar) * l->count); |
76 |
memmove(l->scalars, a->scalars, sizeof (struct eval_scalar) * a->count); |
77 |
memmove(l->scalars+a->count, b->scalars, sizeof (struct eval_scalar) * b->count); |
78 |
} |
79 |
|
80 |
void scalarlist_destroy(struct eval_scalarlist *l) |
81 |
{ |
82 |
int i; |
83 |
if (l && l->scalars) { |
84 |
for (i=0; i < l->count; i++) { |
85 |
scalar_destroy(&l->scalars[i]); |
86 |
} |
87 |
free(l->scalars); |
88 |
} |
89 |
} |
90 |
|
91 |
void scalarlist_destroy_flat(struct eval_scalarlist *l) |
92 |
{ |
93 |
if (l && l->scalars) free(l->scalars); |
94 |
} |
95 |
|
96 |
#ifdef EVAL_DEBUG |
97 |
|
98 |
void scalarlist_dump(struct eval_scalarlist *l) |
99 |
{ |
100 |
int i; |
101 |
for (i=0; i < l->count; i++) { |
102 |
scalar_dump(&l->scalars[i]); |
103 |
if (i != l->count-1) { |
104 |
printf(", "); |
105 |
} |
106 |
} |
107 |
} |
108 |
|
109 |
#endif |
110 |
|
111 |
/* |
112 |
* STRING |
113 |
*/ |
114 |
void string_destroy(struct eval_str *s) |
115 |
{ |
116 |
if (s->value) free(s->value); |
117 |
} |
118 |
|
119 |
/* |
120 |
* SCALAR |
121 |
*/ |
122 |
void scalar_destroy(struct eval_scalar *s) |
123 |
{ |
124 |
switch (s->type) { |
125 |
case SCALAR_STR: |
126 |
string_destroy(&s->scalar.str); |
127 |
break; |
128 |
default: |
129 |
break; |
130 |
} |
131 |
} |
132 |
|
133 |
/* |
134 |
* |
135 |
*/ |
136 |
void create_command(struct eval_command *result, eval_commandtype type, int args, ...) |
137 |
{ |
138 |
va_list vargs; |
139 |
int i; |
140 |
memset(result, 0, sizeof (struct eval_command)); |
141 |
result->type = type; |
142 |
va_start(vargs, args); |
143 |
result->paramcount = args; |
144 |
for (i=0; i<args; i++) { |
145 |
result->param[i] = *va_arg(vargs, struct eval_scalar*); |
146 |
} |
147 |
va_end(vargs); |
148 |
} |
149 |
|
150 |
void create_func_call(struct eval_scalar *result, const char *name, int args, ...) |
151 |
{ |
152 |
int i; |
153 |
va_list vargs; |
154 |
va_start(vargs, args); |
155 |
result->type = SCALAR_FUNCTION; |
156 |
result->scalar.function.name = strdup(name); |
157 |
result->scalar.function.param_count = args; |
158 |
result->scalar.function.params = (struct eval_scalar*)malloc(sizeof (struct eval_scalar)*args); |
159 |
for (i=0; i<args; i++) { |
160 |
result->scalar.function.params[i] = *va_arg(vargs, struct eval_scalar*); |
161 |
} |
162 |
va_end(vargs); |
163 |
} |
164 |
|
165 |
void create_func_call_list(struct eval_scalar *result, const char *name, struct eval_scalarlist *args) |
166 |
{ |
167 |
int i; |
168 |
result->type = SCALAR_FUNCTION; |
169 |
result->scalar.function.name = strdup(name); |
170 |
result->scalar.function.param_count = args->count; |
171 |
result->scalar.function.params = (struct eval_scalar*)malloc(sizeof (struct eval_scalar)*args->count); |
172 |
for (i=0; i<args->count; i++) { |
173 |
result->scalar.function.params[i] = args->scalars[i]; |
174 |
} |
175 |
} |
176 |
|
177 |
/* |
178 |
* |
179 |
*/ |
180 |
extern int yyparse(struct eval_command *result); |
181 |
|
182 |
int eval_parse(struct eval_command *result, const char *str) |
183 |
{ |
184 |
void *oldbuffer = lex_current_buffer(); |
185 |
void *strbuffer; |
186 |
strbuffer = lex_scan_string_buffer(str); |
187 |
|
188 |
clear_eval_error(); |
189 |
|
190 |
result->type = COMMAND_NOP; |
191 |
yyparse(result); |
192 |
|
193 |
lex_delete_buffer(strbuffer); |
194 |
if (oldbuffer) lex_switch_buffer(oldbuffer); |
195 |
|
196 |
if (get_eval_error(NULL, NULL)) return 0; |
197 |
|
198 |
return 1; |
199 |
} |