if_parser fix
[mala.git] / std / std_parsers.c
blob4687147a5ed10af2a0ce021a10907801c619ff06
1 /*
2 std_parsers.c - MaLa standard module parsers
4 Copyright (C) 2005, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
20 #include <stdio.h>
21 #include <string.h>
22 #include <time.h>
24 #include "mala.h"
25 #include "std.h"
27 static size_t
28 reserve_string (char ** s, size_t actual, size_t needed);
30 static void
31 mala_macrocheck_list (MalaStringList list, int * max_arg, int argt[10]);
33 static void
34 mala_macrocheck_string (MalaString string, int * max_arg, int argt[10]);
37 int
38 mala_substitute_parser (MalaEngine eng,
39 MalaStringListNode_ref pptr,
40 void * data)
42 (void) eng;
44 MALA_SIDEEFFECT_BEGIN
45 mala_stringlistnode_substitute_string (*pptr, (MalaString) data);
46 MALA_SIDEEFFECT_END;
48 return MALA_CONTINUE;
51 int
52 mala_expand_parser (MalaEngine eng,
53 MalaStringListNode_ref pptr,
54 void * data)
56 MalaStringListNode itr;
57 MalaStringListNode end;
59 MALA_SIDEEFFECT_BEGIN
61 end = mala_stringlistnode_next (*pptr);
63 for (itr = mala_stringlist_tail ((MalaStringList) data);
64 !mala_stringlist_is_end ((MalaStringList) data, itr);
65 mala_stringlistnode_rev (&itr))
67 if (!mala_stringlist_after_new (&eng->program, *pptr,
68 mala_stringlistnode_string (itr)))
69 goto ealloc_node;
72 MALA_SIDEEFFECT_END;
74 mala_engine_command_done (eng, pptr, 0);
75 return MALA_CONTINUE;
77 ealloc_node:
78 /* remove already added things */
79 for (itr = mala_stringlistnode_next (*pptr);
80 itr != end;
81 mala_stringlist_elem_delete_fwd (&eng->program, &itr));
83 return MALA_EALLOC;
87 int
88 mala_macro_parser (MalaEngine eng,
89 MalaStringListNode_ref pptr,
90 void * data)
92 MalaStringListNode itr;
93 MalaStringListNode last = NULL;
94 MalaStringList list;
95 const char* c;
96 int i;
97 int max_arg = 0;
98 int argt[10] = {0};
99 char *p;
100 MalaString args[10];
101 MalaString str = NULL;
103 // scan how much args are needed
104 mala_macrocheck_list ((MalaStringList) data, &max_arg, argt);
106 // evaluate args, fill arg-array
107 args[0] = mala_stringlistnode_string (*pptr);
109 for (i = 1; i <= max_arg; ++i)
111 if (!(last = mala_engine_arg_eval (eng, pptr, i, argt[i] == 1 ? -1 : 0, NULL))
112 || eng->state > MALA_EFAULT)
113 return eng->state;
115 args[i] = mala_stringlistnode_string (last);
118 MALA_SIDEEFFECT_BEGIN
120 // build list with substitutions
121 list = mala_stringlist_new ();
122 if (!list)
123 goto ealloc_list;
125 for (itr = mala_stringlist_head ((MalaStringList) data);
126 !mala_stringlist_is_end ((MalaStringList) data, itr);
127 mala_stringlistnode_fwd (&itr))
129 size_t size = 64;
130 if (!(p = malloc (size)))
131 goto ealloc_cstr;
133 for (c = mala_string_cstr (mala_stringlistnode_string (itr)), i = 0; *c; ++c,++i)
135 if (*c == '%')
137 ++c;
138 if (*c == '%')
140 // %% -> %
141 goto normal_char;
143 else if (*c >= '0' && *c <= '9')
145 // %0..%9
146 if (size <= i+mala_string_length (args[*c-'0'])
147 && !(size = reserve_string (&p,
148 size,
149 1 + i + mala_string_length (args[*c-'0']))))
150 goto ealloc_reserve;
151 strcpy(p+i, mala_string_cstr (args[*c-'0']));
152 i += (mala_string_length (args[*c-'0']) - 1);
154 else if (*c == '-')
156 ++c;
157 if (*c >= '0' && *c <= '9')
159 // %0..%9
160 if (size <= i+mala_string_length (args[*c-'0'])
161 && !(size = reserve_string (&p,
162 size,
163 1 + i +
164 mala_string_length (args[*c-'0']))))
165 goto ealloc_reserve;
166 strcpy(p+i, mala_string_cstr (args[*c-'0']));
167 i += (mala_string_length (args[*c-'0']) - 1);
171 else
173 normal_char:
174 // normal char
175 if (size <= (size_t) i && !(size = reserve_string (&p, size, (size_t) i+1)))
176 goto ealloc_reserve;
177 p[i] = *c;
181 p[i] = '\0';
183 char* ptmp;
184 if (!(ptmp = realloc (p, size)))
185 goto ealloc_realloc;
187 str = mala_string_new_cstr_attach (ptmp, &eng->words);
188 if (!str)
189 goto ealloc_string;
191 if (!mala_stringlist_tail_new (list, str))
192 goto ealloc_node;
194 mala_string_free (str);
198 // insert list
199 for (itr = mala_stringlist_tail (list);
200 !mala_stringlist_is_end (list, itr);
201 mala_stringlistnode_rev (&itr))
203 if (!mala_stringlist_after_new (&eng->program, last,
204 mala_stringlistnode_string (itr)))
205 goto ealloc_program;
208 // cleanup
209 mala_stringlist_free (list);
212 MALA_SIDEEFFECT_END;
214 mala_engine_command_done (eng, pptr, max_arg);
215 return MALA_CONTINUE;
217 ealloc_program:
218 ealloc_node:
219 mala_string_free (str);
220 ealloc_string:
221 ealloc_realloc:
222 ealloc_reserve:
223 free (p);
224 ealloc_cstr:
225 mala_stringlist_free (list);
226 ealloc_list:
227 return MALA_EALLOC;
231 mala_defined_parser (MalaEngine eng,
232 MalaStringListNode_ref pptr,
233 void * data)
235 MalaStringListNode result;
236 MalaActionDesc desc;
238 (void) data;
240 result = mala_engine_arg_eval (eng, pptr, 1, -1, NULL);
241 if (!result)
242 return eng->state;
244 MALA_SIDEEFFECT_BEGIN
246 desc = (MalaActionDesc) mala_stringlistnode_user_get (result);
248 mala_engine_command_done (eng, pptr, 1);
250 if (desc && mala_actiondesc_top (desc))
252 return MALA_SUCCESS;
254 else
256 return MALA_FAILURE;
259 MALA_SIDEEFFECT_END;
261 return MALA_REMOVE;
265 mala_if_parser (MalaEngine eng,
266 MalaStringListNode_ref pptr,
267 void * data)
269 MalaStringListNode result;
270 (void) data;
271 /*TODO negated, blocks, parse long double 0.0 as false*/
273 int state;
275 result = mala_engine_arg_eval (eng, pptr, 1, -1, NULL);
276 if (!result)
277 return eng->state;
279 MALA_SIDEEFFECT_BEGIN
281 if (eng->state == MALA_LITERAL)
283 if (mala_engine_string_istrue (eng, mala_stringlistnode_string (result)))
284 eng->state = MALA_SUCCESS;
285 else
286 eng->state = MALA_FAILURE;
289 state = eng->state;
291 if (eng->state == MALA_FAILURE)
292 eng->state = MALA_REMOVE;
294 result = mala_engine_arg_eval (eng, pptr, 2, -1, NULL);
295 if (!result)
296 return eng->state;
298 if (eng->state == MALA_REMOVE)
299 eng->state = MALA_FAILURE;
301 MALA_SIDEEFFECT_END;
303 if (eng->state == MALA_LITERAL)
304 mala_engine_command_done (eng, pptr, 1);
305 else
306 mala_engine_command_done (eng, pptr, 2);
307 return state;
311 mala_pass_parser (MalaEngine eng,
312 MalaStringListNode_ref pptr,
313 void * data)
315 (void) data;
317 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
319 return eng->state;
323 mala_trace_parser (MalaEngine eng,
324 MalaStringListNode_ref pptr,
325 void * data)
327 (void) data;
329 MALA_SIDEEFFECT_BEGIN
330 eng->trace = !eng->negated;
331 MALA_SIDEEFFECT_END;
333 mala_engine_command_done (eng, pptr, 0);
334 return MALA_SUCCESS;
337 /*TODO to predicates*/
338 static int
339 mala_predicate_greaterorequal_double (double * a, double * b)
341 return *a >= *b;
345 mala_sleep_parser (MalaEngine eng,
346 MalaStringListNode_ref pptr,
347 void * data)
349 double duration;
350 double zero = 0.0;
351 struct timespec req;
353 (void) data;
355 if (mala_engine_arg_eval_fmt (eng, pptr, 1, "%lf", &duration,
356 (MalaPredicate) mala_predicate_greaterorequal_double, &zero
357 ) >= MALA_EXCEPTION)
358 return eng->state;
360 MALA_SIDEEFFECT_BEGIN
362 req.tv_sec = (time_t) duration;
363 req.tv_nsec = (long) 1000000000 * (duration - ((double) req.tv_sec));
365 (void) nanosleep (&req, NULL);
367 MALA_SIDEEFFECT_END;
369 mala_engine_command_done (eng, pptr, 1);
370 return MALA_SUCCESS;
374 mala_literal_parser (MalaEngine eng,
375 MalaStringListNode_ref pptr,
376 void * data)
378 (void) data;
380 MALA_SIDEEFFECT_BEGIN
382 if (mala_stringlist_is_tail (&eng->program, *pptr))
383 return mala_engine_exception (eng, pptr, *pptr,
384 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
386 MALA_SIDEEFFECT_END;
388 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
389 return MALA_LITERAL;
393 mala_not_parser (MalaEngine eng,
394 MalaStringListNode_ref pptr,
395 void * data)
397 (void) data;
398 /*TODO evaluate %1*/
399 MALA_SIDEEFFECT_BEGIN
401 if (mala_stringlist_is_tail (&eng->program, *pptr))
402 return mala_engine_exception (eng, pptr, *pptr,
403 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
404 } /*TODO remove unfinished*/
405 MALA_SIDEEFFECT_END;
407 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
408 eng->negated = !eng->negated;
409 return MALA_SUCCESS; /*TODO*/
413 mala_begin_parser (MalaEngine eng,
414 MalaStringListNode_ref pptr,
415 void * data)
417 MalaStringListNode itr;
418 MalaStringListNode end;
419 MalaStringList list;
420 unsigned depth = 1;
421 MalaString name = NULL;
423 (void) data;
425 if (mala_stringlist_is_tail (&eng->program, *pptr))
426 return mala_engine_exception (eng, pptr, *pptr,
427 eng->common_string[MALA_STRING_ERROR_MISSING_END]);
429 // find matching --END
430 for (end = mala_stringlistnode_next (*pptr);
431 !mala_stringlist_is_end (&eng->program, end);
432 mala_stringlistnode_fwd (&end))
434 if (mala_string_same(mala_stringlistnode_string (end),
435 eng->common_string[MALA_STRING_BEGIN]))
436 ++depth;
437 else if (mala_string_same(mala_stringlistnode_string (end),
438 eng->common_string[MALA_STRING_END]))
439 --depth;
440 if (!depth)
441 break;
444 if (depth)
445 return mala_engine_exception (eng, pptr, mala_stringlistnode_prev (end),
446 eng->common_string[MALA_STRING_ERROR_MISSING_END]);
448 MALA_SIDEEFFECT_BEGIN
450 list = mala_stringlist_new ();
451 if (!list)
452 return MALA_EALLOC;
454 // copy the block content to list
455 for (itr = mala_stringlistnode_next (*pptr); itr != end; mala_stringlistnode_fwd (&itr))
456 if (!mala_stringlist_tail_new (list, mala_stringlistnode_string (itr)))
457 goto ealloc_node;
459 // allocate new block name
460 do {
461 mala_string_free (name);
462 name = mala_string_new_print (&eng->words, "--BLOCK_%08X", ++eng->blockcnt);
463 if (!name)
464 goto ealloc_name;
465 } while (mala_actiondesc_top ((MalaActionDesc)mala_string_user_get (name)));
467 if (MALA_SUCCESS != mala_engine_add_action (eng, name, list,
468 mala_block_parser,
469 (MalaDataFactory)mala_stringlist_factory,
470 NULL))
471 goto ealloc_action;
473 // insert new --BLOCK_... in program
474 if (!mala_stringlist_after_new (&eng->program, end, name))
475 goto ealloc_node;
476 mala_string_free (name);
478 else
480 if (!mala_stringlist_after_new (&eng->program,
481 end,
482 eng->common_string[MALA_STRING_PASS]))
483 goto ealloc_pass;
485 MALA_SIDEEFFECT_END;
487 // and remove definition
488 while (*pptr != end)
489 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
491 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
493 return MALA_SUCCESS;
495 ealloc_action:
496 mala_string_free (name);
497 ealloc_name:
498 ealloc_node:
499 mala_stringlist_free (list);
500 ealloc_pass:
501 return MALA_EALLOC;
505 mala_block_parser (MalaEngine eng,
506 MalaStringListNode_ref pptr,
507 void * data)
509 (void) data;
510 /*TODO expand instead?*/
511 MALA_SIDEEFFECT_BEGIN
512 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (*pptr));
513 MALA_SIDEEFFECT_END;
515 mala_engine_command_done (eng, pptr, 0);
516 return MALA_SUCCESS;
520 mala_macrodelete_parser (MalaEngine eng,
521 MalaStringListNode_ref pptr,
522 void * data)
524 (void) data;
526 mala_engine_arg_eval (eng, pptr, 1, -1, NULL);
528 MALA_SIDEEFFECT_BEGIN
530 if (mala_stringlist_is_tail (&eng->program, *pptr))
531 return mala_engine_exception (eng, pptr, *pptr,
532 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
534 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (mala_stringlistnode_next (*pptr)));
536 MALA_SIDEEFFECT_END;
538 mala_engine_command_done (eng, pptr, 1);
539 return MALA_SUCCESS;
543 mala_exception_parser (MalaEngine eng,
544 MalaStringListNode_ref pptr,
545 void * data)
547 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
549 (void) data;
551 mala_engine_arg_eval (eng, pptr, 1, -1, NULL);
553 //TODO MALA_SIDEEFFECT_BEGIN
554 // {
555 if (mala_stringlist_is_tail (&eng->program, *pptr))
556 return mala_engine_exception (eng, pptr, *pptr,
557 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
559 if (eng->state > MALA_EFAULT)
560 return eng->state;
562 MalaString ex = mala_string_new_print (&eng->words, "--ERROR-%s",
563 mala_stringlistnode_cstr (mala_stringlistnode_next (*pptr)));
565 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
566 int state = mala_engine_exception (eng, pptr, *pptr, ex);
567 mala_stringlist_elem_delete (&eng->program, mala_stringlistnode_next (*pptr));
569 mala_string_free (ex);
570 // MALA_SIDEEFFECT_END;
572 return state;
576 mala_end_parser (MalaEngine eng,
577 MalaStringListNode_ref pptr,
578 void * data)
580 (void) data;
582 return mala_engine_exception (eng, pptr, *pptr,
583 eng->common_string[MALA_STRING_ERROR_END_WITHOUT_BEGIN]);
586 static void
587 mala_macrocheck_list (MalaStringList list, int * max_arg, int argt[10])
589 MalaStringListNode itr;
590 for (itr = mala_stringlist_head (list);
591 !mala_stringlist_is_end (list, itr);
592 mala_stringlistnode_fwd (&itr))
594 mala_macrocheck_string (mala_stringlistnode_string (itr), max_arg, argt);
595 if (*max_arg == -1)
596 return;
600 static void
601 mala_macrocheck_string (MalaString string, int * max_arg, int argt[10])
603 const char * c;
604 for (c = mala_string_cstr (string); *c; ++c)
606 // "foo%1%-2"
607 if (*c == '%')
609 // %
610 ++c;
611 if (*c == '%')
612 // %%
613 continue;
614 if (*c == '-')
616 // %-
617 ++c;
618 if (*c >= '0' && *c <= '9')
620 // %-0 .. %-9
621 if (argt[*c - '0'] == 1)
622 goto esyntax;
623 if (*c > (char) *max_arg + '0')
624 *max_arg = *c - '0';
625 argt[*c - '0'] = -1;
627 else
628 goto esyntax;
630 else if (*c >= '0' && *c <= '9')
632 // %0 .. %9
633 if (argt[*c - '0'] == -1)
634 goto esyntax;
635 if (*c > (char) *max_arg + '0')
636 *max_arg = *c - '0';
637 argt[*c - '0'] = 1;
639 else
640 goto esyntax;
643 return;
645 esyntax:
646 *max_arg = -1;
647 return;
651 mala_macrodef_parser (MalaEngine eng,
652 MalaStringListNode_ref pptr,
653 void * data)
655 int i;
656 MalaStringListNode itr;
657 MalaStringListNode arg[2];
658 MalaString name;
659 MalaAction act;
661 (void) data;
663 // evaluate both args
664 if (!mala_engine_arg_eval (eng, pptr, 1, -1, NULL))
665 return eng->state;
666 if (!mala_engine_arg_eval (eng, pptr, 2, -1, NULL))
667 return eng->state;
669 MALA_SIDEEFFECT_BEGIN
671 // test if 2 arguments left and assign them to arg[], else error
672 for (i = 0, itr = *pptr; i<2; ++i, mala_stringlistnode_fwd(&itr))
674 if (mala_stringlist_is_tail (&eng->program, itr))
675 return mala_engine_exception (eng, pptr, itr,
676 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
677 arg[i] = mala_stringlistnode_next (itr);
680 // if name is a block then error
681 name = mala_stringlistnode_string (arg[0]);
682 act = mala_actiondesc_top ((MalaActionDesc) mala_string_user_get (name));
683 if (act && act->parser == mala_block_parser)
684 return mala_engine_exception (eng, pptr, arg[0],
685 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
687 //expansion check and optimize block
688 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (arg[1]));
689 if (act && act->factory == (MalaDataFactory) mala_stringlist_factory)
691 int max_arg = 0;
692 int argt[10] = {0};
693 mala_macrocheck_list ((MalaStringList) act->data, &max_arg, argt);
694 // convert block to expansion
695 if (max_arg > 0)
697 //macro
698 MalaActionDesc desc;
699 desc = mala_actiondesc_ensure (name);
700 if (!desc)
701 return MALA_EALLOC;
703 act = mala_actiondesc_pop ((MalaActionDesc) mala_stringlistnode_user_get (arg[1]));
704 act->name = name;
705 act->parser = mala_macro_parser;
706 mala_actiondesc_push_action (desc, act);
708 else if (mala_stringlist_is_single ((MalaStringList) act->data))
710 //substitute
711 MalaString subst;
712 subst = mala_stringlist_head_string_copy ((MalaStringList) act->data);
714 if (MALA_SUCCESS != mala_engine_add_action (eng, name, subst,
715 mala_substitute_parser,
716 (MalaDataFactory) mala_string_factory,
717 NULL))
718 return MALA_EALLOC;
720 mala_action_free(act);
722 else if (max_arg == 0)
724 //expand
725 MalaActionDesc desc;
726 desc = mala_actiondesc_ensure (name);
727 if (!desc)
728 return MALA_EALLOC;
730 act = mala_actiondesc_pop ((MalaActionDesc) mala_stringlistnode_user_get (arg[1]));
731 act->name = name;
732 act->parser = mala_expand_parser;
733 mala_actiondesc_push_action (desc, act);
735 else
736 return mala_engine_exception (eng, pptr, arg[1],
737 eng->common_string[MALA_STRING_ERROR_PARAMETER_SYNTAX]);
739 else //if (act && act->factory == (MalaDataFactory)mala_string_factory)
741 // single word
742 int max_arg = 0;
743 int argt[10] = {0};
744 mala_macrocheck_string (mala_stringlistnode_string (arg[1]), &max_arg, argt);
745 if (max_arg == 0)
747 // substitute
748 if (MALA_SUCCESS != mala_engine_add_action (eng, name,
749 mala_stringlistnode_string_copy (arg[1]),
750 mala_substitute_parser,
751 (MalaDataFactory) mala_string_factory,
752 NULL))
753 return MALA_EALLOC;
755 else if (max_arg > 0)
757 // macro
758 MalaStringList list;
760 list = mala_stringlist_new ();
761 if (!list)
762 return MALA_EALLOC;
764 mala_stringlist_tail_new (list, mala_stringlistnode_string (arg[1]));
766 if (MALA_SUCCESS != mala_engine_add_action (eng, name, list,
767 mala_macro_parser,
768 (MalaDataFactory) mala_stringlist_factory,
769 NULL))
770 return MALA_EALLOC;
772 else // syntax error
773 return mala_engine_exception (eng, pptr, arg[1],
774 eng->common_string[MALA_STRING_ERROR_PARAMETER_SYNTAX]);
777 MALA_SIDEEFFECT_END;
779 mala_engine_command_done (eng, pptr, 2);
780 return MALA_SUCCESS;
784 mala_foreach_word_parser (MalaEngine eng,
785 MalaStringListNode_ref pptr,
786 void * data)
788 MalaAction act;
789 MalaStringListNode first;
790 MalaStringListNode second;
791 MalaStringListNode last;
792 MalaStringListNode itr;
793 (void) data;
795 /*TODO bugs, rename to --APPLY fixit etc*/
797 first = mala_engine_arg_eval (eng, pptr, 1, -1, NULL);
798 if (!first)
799 return eng->state;
800 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (first));
801 // TODO allow blocks as first arg (define macro and delete it at later)
802 if (act && act->parser == mala_block_parser)
803 return mala_engine_exception (eng, pptr, first,
804 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
806 second = mala_engine_arg_eval (eng, pptr, 2, -1, (MalaDataFactory) mala_stringlist_factory);
807 if (!second)
808 return eng->state;
810 last = mala_stringlistnode_next (second);
812 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (second));
814 // expand second
815 if (eng->state != MALA_LITERAL)
816 for (itr = mala_stringlist_tail ((MalaStringList) act->data);
817 !mala_stringlist_is_end ((MalaStringList) act->data, itr);
818 mala_stringlistnode_rev (&itr))
820 if (!mala_stringlist_after_new (&eng->program,
821 second,
822 mala_stringlistnode_string (itr)))
823 goto ealloc_node;
824 if (!mala_stringlist_after_new (&eng->program,
825 second,
826 mala_stringlistnode_string (first)))
827 goto ealloc_node;
829 else
831 if (!mala_stringlist_after_new (&eng->program,
832 second,
833 mala_stringlistnode_string (second)))
834 goto ealloc_node;
835 if (!mala_stringlist_after_new (&eng->program,
836 second,
837 mala_stringlistnode_string (first)))
838 goto ealloc_node;
842 // was a block? delete it
843 if (act && act->parser == mala_block_parser)
844 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (second));
846 mala_engine_command_done (eng, pptr, 2);
847 return MALA_SUCCESS;
849 ealloc_node:
850 for (itr = mala_stringlistnode_next (second);
851 itr != last;
852 mala_stringlistnode_fwd (&itr))
854 mala_stringlist_elem_delete (&eng->program, itr);
857 return MALA_EALLOC; // TODO exception instead (needs pools, no allocation possible further)
864 realloc a string to at least needed size
865 return the amount really reserved or 0 on error
867 static size_t
868 reserve_string (char ** s, size_t actual, size_t needed)
870 size_t n;
871 char * r;
873 for (n = actual>64?actual:64; n <= needed; n += (n>>1)); /*n = n * 1.5*/
875 r = realloc (*s, n);
876 if (!r)
878 /* that was to much, try conservatively */
879 r = realloc (*s, n = needed);
880 if (!r)
881 return 0;
883 *s = r;
884 return n;
889 // Local Variables:
890 // mode: C
891 // c-file-style: "gnu"
892 // End:
893 // arch-tag: 687e1195-8aad-4425-983d-9767a25c3793
894 // end_of_file