148 struct expression *ret;
149 struct string *string;
150 int len;
151
152 len = strlen(str) + 1;
153 string = (void *)__alloc_sname(4 + len);
154 string->length = len;
155 string->immutable = 0;
156 memcpy(string->data, str, len);
157
158 ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
159 ret->wide = 0;
160 ret->string = string;
161
162 return ret;
163 }
164
165 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
166 {
167 struct expression *ret;
168 struct token *token, *end;
169 const char *p = key;
170 char buf[4095];
171 char *alloc;
172 size_t len;
173
174 /* The idea is that we can parse either $0->foo or $->foo */
175 if (key[0] != '$')
176 return NULL;
177 p++;
178 while (*p >= '0' && *p <= '9')
179 p++;
180 len = snprintf(buf, sizeof(buf), "%s\n", p);
181 alloc = alloc_string(buf);
182
183 token = tokenize_buffer(alloc, len, &end);
184 if (!token)
185 return NULL;
186 if (token_type(token) != TOKEN_STREAMBEGIN)
187 return NULL;
188 token = token->next;
189
190 ret = arg;
191 while (token_type(token) == TOKEN_SPECIAL &&
192 token->special == SPECIAL_DEREFERENCE) {
193 token = token->next;
194 if (token_type(token) != TOKEN_IDENT)
195 return NULL;
196 ret = deref_expression(ret);
197 ret = member_expression(ret, '*', token->ident);
198 token = token->next;
199 }
200
201 if (token_type(token) != TOKEN_STREAMEND)
202 return NULL;
203
204 return ret;
205 }
206
207 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
208 {
209 if (!expr)
210 return;
211 if (parent->smatch_flags & Fake)
212 return;
213
214 expr->parent = (unsigned long)parent | 0x1UL;
215 }
216
217 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
|
148 struct expression *ret;
149 struct string *string;
150 int len;
151
152 len = strlen(str) + 1;
153 string = (void *)__alloc_sname(4 + len);
154 string->length = len;
155 string->immutable = 0;
156 memcpy(string->data, str, len);
157
158 ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
159 ret->wide = 0;
160 ret->string = string;
161
162 return ret;
163 }
164
165 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
166 {
167 struct expression *ret;
168 struct token *token, *prev, *end;
169 const char *p = key;
170 char buf[4095];
171 char *alloc;
172 size_t len;
173
174 /* The idea is that we can parse either $0->foo or $->foo */
175 if (key[0] != '$')
176 return NULL;
177 p++;
178 while (*p >= '0' && *p <= '9')
179 p++;
180 len = snprintf(buf, sizeof(buf), "%s\n", p);
181 alloc = alloc_string(buf);
182
183 token = tokenize_buffer(alloc, len, &end);
184 if (!token)
185 return NULL;
186 if (token_type(token) != TOKEN_STREAMBEGIN)
187 return NULL;
188 token = token->next;
189
190 ret = arg;
191 while (token_type(token) == TOKEN_SPECIAL &&
192 (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
193 prev = token;
194 token = token->next;
195 if (token_type(token) != TOKEN_IDENT)
196 return NULL;
197 ret = deref_expression(ret);
198 ret = member_expression(ret,
199 (prev->special == SPECIAL_DEREFERENCE) ? '*' : '.',
200 token->ident);
201 token = token->next;
202 }
203
204 if (token_type(token) != TOKEN_STREAMEND)
205 return NULL;
206
207 return ret;
208 }
209
210 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
211 {
212 if (!expr)
213 return;
214 if (parent->smatch_flags & Fake)
215 return;
216
217 expr->parent = (unsigned long)parent | 0x1UL;
218 }
219
220 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
|