1 |
dpavlin |
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 |
|
|
} |