2 engine.c - MaLa core engine
4 Copyright (C) 2004, 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.
23 #include "mala_types.h"
25 #include "actiondesc.h"
27 #include "stringlist.h"
31 static const char * mala_common_strings
[]=
49 "--FLAG-LITERAL-EXPANSION",
50 "--FLAG-EXCLAM-EXPANSION",
51 "--FLAG-NO-EXPANSION",
52 "--FLAG-NUMSPLIT-EXPANSION",
53 "--FLAG-CHAR-EXPANSION",
54 "--FLAG-ASSIGN-EXPANSION",
55 "--FLAG-SETENV-EXPANSION",
56 "--FLAG-ENVVAR-EXPANSION",
57 "--FLAG-UNDERSCORE-EXPANSION",
58 "--FLAG-BRACKET-EXPANSION",
59 "--FLAG-ASSIGN-CONTRACTION",
60 "--ERROR-MISSING-ARGUMENT",
61 "--ERROR-MISSING-END",
69 * function definitions
78 self
= malloc (sizeof(mala_engine
));
85 self
->state
= MALA_SUCCESS
;
87 mala_stringbucket_init (&self
->words
, MALA_STRING_FWD
, (void(*)(void*)) mala_actiondesc_free
);
89 for (i
= 0; i
< MALA_MAX_COMMON_STRING
; ++i
)
91 self
->common_string
[i
] = mala_string_new (mala_common_strings
[i
], &self
->words
);
92 if (!self
->common_string
[i
])
96 mala_stringlist_init (&self
->program
);
97 mala_stringlist_init (&self
->arguments
);
103 mala_string_free (self
->common_string
[i
]);
110 mala_engine_new_main (int (*initfunc
) (MalaEngine
),
111 int argc
, char **argv
,
112 mala_actioninit
* actions_init
)
114 /*TODO convinience function*/
119 mala_engine_macro_define (MalaEngine self
, const char * name
, int argc
, char ** argv
)
123 MalaStringListNode itr
;
128 return MALA_EINVALID
;
129 if(self
->state
> MALA_EFAULT
)
132 mala_stringlist_init (&pre
);
134 for (i
= 0; i
!= argc
&& *argv
; ++i
,++argv
)
136 if (!mala_stringlist_tail_new_cstr (&pre
, *argv
, &self
->words
))
140 list
= mala_stringlist_new ();
144 /*TODO preprocess in own function*/
145 while (!mala_stringlist_is_empty (&pre
))
149 itr
= mala_stringlist_head (&pre
);
151 putaway
= mala_engine_expand (self
, &pre
, &itr
);
153 if (self
->state
> MALA_EFAULT
)
158 mala_stringlist_node_remove (&pre
, itr
);
159 mala_stringlist_tail_insert (list
, itr
);
160 if (putaway
&& mala_stringlist_is_empty (&pre
))
162 itr
= mala_stringlist_head (&pre
);
166 if (mala_stringlist_is_empty (list
))
168 /* empty substituted by --NULL, TODO use empty string instead? */
169 mala_stringlist_free (list
);
170 return mala_engine_add_action_cstr (self
, name
,
171 mala_string_copy (self
->common_string
[MALA_STRING_NULL
]),
172 mala_substitute_parser
,
173 (MalaDataFactory
)mala_string_factory
,
178 for (itr
= mala_stringlist_head (list
);
179 !mala_stringlist_is_end (list
, itr
);
180 mala_stringlist_fwd(&itr
))
181 if (mala_string_char_find (itr
->string
, '%') != SIZE_MAX
)
190 return mala_engine_add_action_cstr (self
, name
, list
,
192 (MalaDataFactory
)mala_stringlist_factory
,
195 else if (mala_stringlist_is_tail (list
, mala_stringlist_head (list
)))
200 subst
= mala_string_copy (mala_stringlist_head (list
) -> string
);
201 mala_stringlist_free (list
);
203 return mala_engine_add_action_cstr (self
, name
, subst
,
204 mala_substitute_parser
,
205 (MalaDataFactory
)mala_string_factory
,
211 return mala_engine_add_action_cstr (self
, name
, list
,
213 (MalaDataFactory
) mala_stringlist_factory
,
218 mala_stringlist_free (list
);
219 mala_stringlist_erase (&pre
);
220 return self
->state
= MALA_ESYNTAX
;
224 mala_stringlist_erase (&pre
);
225 return self
->state
= MALA_EALLOC
;
229 mala_engine_pushback_word (MalaEngine self
, const char * word
)
232 return MALA_EINVALID
;
233 if(self
->state
> MALA_EFAULT
)
236 if (!mala_stringlist_tail_new_cstr (&self
->program
, word
, &self
->words
))
237 return self
->state
= MALA_EALLOC
;
243 mala_engine_add_action_cstr (MalaEngine self
, const char * cname
, void * data
,
244 MalaParserFunc parser
, MalaDataFactory factory
,
250 /*TODO such checks everywhere*/
252 return MALA_EINVALID
;
253 if(self
->state
> MALA_EFAULT
)
256 name
= mala_string_new (cname
, &self
->words
);
260 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
264 if (mala_action_attach (action
) != MALA_SUCCESS
)
267 mala_string_free (name
);
271 mala_action_free (action
);
273 mala_string_free (name
);
275 return self
->state
= MALA_EALLOC
;
279 mala_engine_add_action (MalaEngine self
, MalaString name
, void * data
,
280 MalaParserFunc parser
, MalaDataFactory factory
,
285 /*TODO such checks everywhere*/
287 return MALA_EINVALID
;
288 if(self
->state
> MALA_EFAULT
)
291 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
295 if (mala_action_attach (action
) != MALA_SUCCESS
)
301 mala_action_free (action
);
303 return self
->state
= MALA_EALLOC
;
308 mala_engine_new_initfunc (int (*initfunc
)(MalaEngine
))
312 self
= mala_engine_new ();
316 self
->state
= initfunc (self
);
321 mala_engine_free (MalaEngine self
)
328 mala_stringlist_erase (&self
->program
);
329 mala_stringlist_erase (&self
->arguments
);
331 mala_stringbucket_erase (&self
->words
);
333 for (i
= 0; i
< MALA_MAX_COMMON_STRING
; ++i
)
334 mala_string_free (self
->common_string
[i
]);
340 mala_engine_actions_register (MalaEngine self
, mala_actioninit
* actioninit
)
345 return MALA_EINVALID
;
347 if (self
->state
> MALA_EFAULT
)
350 while (actioninit
->command
)
352 action
= mala_action_new_actioninit (actioninit
, &self
->words
);
356 if (mala_action_attach (action
) != MALA_SUCCESS
)
365 return self
->state
= MALA_EINIT
;
369 /*TODO make some inlines { */
372 mala_engine_getprogram (MalaEngine self
)
374 return &self
->program
;
378 mala_engine_state_get (MalaEngine self
)
384 mala_engine_clearstate (MalaEngine self
)
386 self
->state
= MALA_SUCCESS
;
390 mala_engine_negated (MalaEngine self
)
392 return self
->negated
;
396 mala_engine_clear_negated (MalaEngine self
)
400 /* } TODO make some inlines */
404 mala_engine_dumpprogram (MalaEngine self
, const char * prefix
, const char * suffix
)
406 MalaStringListNode node
;
408 for (node
= mala_stringlist_head (&self
->program
);
409 node
!= (void *)&self
->program
;
410 mala_stringlist_fwd (&node
))
412 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
417 mala_engine_dumpargs (MalaEngine self
, const char * prefix
, const char * suffix
)
419 MalaStringListNode node
;
421 for (node
= mala_stringlist_head (&self
->arguments
);
422 node
!= (void *)&self
->arguments
;
423 mala_stringlist_fwd (&node
))
425 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
431 mala_engine_run (MalaEngine self
)
433 MalaStringListNode pptr
;
435 while (self
->state
< MALA_EFAULT
&&
436 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
438 if (self
->state
== MALA_LITERAL
)
440 mala_stringlist_elem_remove (&self
->program
, pptr
);
441 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
442 self
->state
= MALA_SUCCESS
;
445 mala_engine_eval (self
, &pptr
);
451 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
456 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
458 return self
->state
= MALA_LITERAL
;
460 act
= mala_actiondesc_top (desc
);
463 self
->state
= mala_action_execute (act
, pptr
, self
);
465 if (self
->state
== MALA_EXCEPTION
)
466 self
->state
= MALA_ENOACTION
;
472 mala_engine_try_eval_arg_n (MalaEngine self
, MalaStringListNode_ref pptr
, unsigned n
)
474 MalaStringListNode next
;
476 n
&& !mala_stringlist_is_tail (&self
->program
, next
);
477 mala_stringlist_fwd (&next
), --n
);
479 while (!mala_stringlist_is_tail (&self
->program
, *pptr
) && self
->state
< MALA_EXCEPTION
)
481 mala_engine_eval (self
, &next
);
486 mala_engine_exception (MalaEngine self
,
487 MalaStringListNode_ref pptr
,
488 MalaStringListNode here
,
491 MalaStringListNode tmp
;
493 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
495 return self
->state
= MALA_EALLOC
;
497 if (!mala_stringlist_after_new (&self
->program
, here
,
498 self
->common_string
[MALA_STRING_HERE
]))
499 return self
->state
= MALA_EALLOC
;
503 /*TODO self-state needs to be preserved somehow?*/
504 return self
->state
= MALA_EXCEPTION
;
509 mala_engine_expand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
513 if (self
->state
> MALA_EFAULT
)
514 return MALA_EXPANSION_ERROR
;
516 #define mala_run_expansion(name) \
517 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
519 mala_run_expansion (literal_expansion
);
520 mala_run_expansion (numsplit_expansion
);
521 mala_run_expansion (exclam_expansion
);
522 mala_run_expansion (no_expansion
);
523 mala_run_expansion (assign_expansion
);
524 mala_run_expansion (char_expansion
);
525 mala_run_expansion (underscore_expansion
);
526 mala_run_expansion (bracket_expansion
);
527 mala_run_expansion (assign_contraction
);
528 mala_run_expansion (envvar_expansion
);
529 mala_run_expansion (setenv_expansion
);
530 mala_run_expansion (backquote_expansion
);
531 #undef mala_run_expansion
537 mala_engine_literal_expansion (MalaEngine self
,
539 MalaStringListNode_ref pptr
)
541 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
542 && mala_string_check_prefix ((*pptr
)->string
, "`")
543 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
546 MalaStringListNode newnode1
;
547 MalaStringListNode newnode2
;
549 newnode1
= mala_stringlist_after_new (list
,
551 self
->common_string
[MALA_STRING_LITERAL
]);
553 goto ealloc_newnode1
;
555 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
556 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
558 goto ealloc_newnode2
;
560 mala_stringlist_elem_delete (list
, pptr
);
566 mala_stringlist_elem_delete (list
, &newnode1
);
568 self
->state
= MALA_EALLOC
;
569 return MALA_EXPANSION_ERROR
;
571 return MALA_NO_EXPANSION
;
576 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
578 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
579 && mala_string_check_prefix ((*pptr
)->string
, "``"))
582 MalaStringListNode newnode
;
584 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
585 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
589 mala_stringlist_elem_delete (list
, pptr
);
595 self
->state
= MALA_EALLOC
;
596 return MALA_EXPANSION_ERROR
;
598 return MALA_NO_EXPANSION
;
602 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
604 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
605 && mala_string_length ((*pptr
)->string
) > 2
606 && mala_string_at ((*pptr
)->string
, 0) == '-'
607 && isalpha (mala_string_at ((*pptr
)->string
, 1))
612 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
614 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
619 MalaStringListNode na
;
620 MalaStringListNode nb
;
622 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
623 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
627 na
= mala_stringlist_after_new (list
, *pptr
, a
);
631 nb
= mala_stringlist_after_new (list
, na
, b
);
635 mala_stringlist_elem_delete (list
, pptr
);
638 mala_string_free (a
);
639 mala_string_free (b
);
644 mala_stringlist_elem_delete (list
, &na
);
647 mala_string_free (a
);
648 mala_string_free (b
);
649 self
->state
= MALA_EALLOC
;
650 return MALA_EXPANSION_ERROR
;
654 return MALA_NO_EXPANSION
;
659 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
661 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
662 && mala_string_length ((*pptr
)->string
) == 1
663 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
665 MalaStringListNode newnode
;
667 newnode
= mala_stringlist_after_new (list
,
669 self
->common_string
[MALA_STRING_NOT
]);
671 return self
->state
= MALA_EALLOC
;
673 mala_stringlist_elem_delete (list
, pptr
);
677 return MALA_NO_EXPANSION
;
682 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
684 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
685 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
686 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
690 MalaStringListNode n1
;
691 MalaStringListNode n2
;
693 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
694 aa
= mala_string_new_prefix ("--", a
);
698 n1
= mala_stringlist_after_new (list
,
699 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
703 n2
= mala_stringlist_after_new (list
, n1
, aa
);
707 mala_string_free (a
);
708 mala_string_free (aa
);
709 mala_stringlist_elem_delete (list
, pptr
);
714 mala_stringlist_elem_delete (list
, &n1
);
716 mala_string_free (a
);
717 mala_string_free (aa
);
719 self
->state
= MALA_EALLOC
;
720 return MALA_EXPANSION_ERROR
;
722 return MALA_NO_EXPANSION
;
727 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
731 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
732 && mala_string_check_prefix ((*pptr
)->string
, "--")
733 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
734 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
739 MalaStringListNode na
;
740 MalaStringListNode nb
;
742 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
743 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
747 na
= mala_stringlist_after_new (list
, *pptr
, a
);
751 nb
= mala_stringlist_after_new (list
, na
, b
);
755 mala_stringlist_elem_delete (list
, pptr
);
758 mala_string_free (a
);
759 mala_string_free (b
);
765 mala_stringlist_elem_delete (list
, &na
);
768 mala_string_free (a
);
769 mala_string_free (b
);
770 self
->state
= MALA_EALLOC
;
771 return MALA_EXPANSION_ERROR
;
773 return MALA_NO_EXPANSION
;
778 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
780 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
781 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
783 MalaStringListNode newnode
;
785 newnode
= mala_stringlist_before_new (list
,
787 self
->common_string
[MALA_STRING_ENVSUBST
]);
795 self
->state
= MALA_EALLOC
;
796 return MALA_EXPANSION_ERROR
;
799 return MALA_NO_EXPANSION
;
804 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
806 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
807 && mala_string_length ((*pptr
)->string
) > 2
808 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
809 || mala_string_at ((*pptr
)->string
, 0) == '+')
810 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
812 char prefix
[2] = "-";
813 char current
[2] = " ";
818 MalaStringListNode node
= NULL
;
819 MalaStringListNode pred
= *pptr
;
822 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
824 if (*i
== '-' || *i
== '+')
826 else if (isalpha (*i
))
830 str
= mala_string_new_cat2 (prefix
, current
,
831 mala_string_bucket_get ((*pptr
)->string
));
835 node
= mala_stringlist_after_new (list
,
841 mala_string_free (str
);
848 mala_stringlist_fwd (&pred
);
849 mala_stringlist_elem_delete (list
, pptr
);
854 mala_string_free (str
);
855 /* cleanup from pred downto pptr */
856 while (pred
!= *pptr
)
858 // TODO use stringlist func
859 MalaStringListNode tmp
= pred
->node
.cqe_prev
;
860 mala_stringlist_elem_delete (list
, &pred
);
863 self
->state
= MALA_EALLOC
;
864 return MALA_EXPANSION_ERROR
;
866 return MALA_NO_EXPANSION
;
871 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
873 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
874 && mala_string_check_prefix ((*pptr
)->string
, "--")
875 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
878 MalaStringListNode node
;
882 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
886 for (i
= cstr
+ 2; *i
; ++i
)
892 str
= mala_string_new (cstr
, &self
->words
);
896 node
= mala_stringlist_after_new (list
,
903 mala_string_free (str
);
905 mala_stringlist_elem_delete (list
, pptr
);
910 mala_string_free (str
);
914 self
->state
= MALA_EALLOC
;
915 return MALA_EXPANSION_ERROR
;
917 return MALA_NO_EXPANSION
;
922 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
926 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
927 && mala_string_length ((*pptr
)->string
) > 1
928 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
931 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
935 MalaStringListNode n1
;
936 MalaStringListNode n2
;
937 MalaStringListNode n3
;
939 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
943 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
947 n1
= mala_stringlist_after_new (list
,
948 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
952 n2
= mala_stringlist_after_new (list
, n1
, key
);
956 n3
= mala_stringlist_after_new (list
, n2
, value
);
960 mala_string_free (key
);
961 mala_string_free (value
);
962 mala_stringlist_elem_delete (list
, pptr
);
967 mala_stringlist_elem_delete (list
, &n2
);
969 mala_stringlist_elem_delete (list
, &n1
);
971 mala_string_free (value
);
973 mala_string_free (key
);
975 self
->state
= MALA_EALLOC
;
976 return MALA_EXPANSION_ERROR
;
978 return MALA_NO_EXPANSION
;
983 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
985 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
986 && mala_string_at ((*pptr
)->string
, 0) == '[')
988 MalaStringListNode nitr
;
989 MalaStringListNode node
;
991 MalaString str1
= NULL
;
992 MalaStringListNode node1
;
994 MalaString str2
= NULL
;
995 MalaStringListNode node2
;
997 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
1001 if (mala_string_length((*pptr
)->string
) > 1)
1003 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
1004 node1
= mala_stringlist_after_new (list
, node
, str1
);
1011 mala_stringlist_fwd (&node1
);
1014 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlist_fwd (&nitr
))
1016 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1020 if ((void*)nitr
!= (void*)list
)
1022 if (mala_string_length(nitr
->string
) > 1)
1024 str2
= mala_string_new_substr (nitr
->string
, 0,
1025 mala_string_length(nitr
->string
) - 1);
1026 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1035 mala_string_free (str1
);
1036 mala_string_free (str2
);
1037 mala_stringlist_elem_delete (list
, pptr
);
1038 mala_stringlist_elem_delete (list
, &nitr
);
1044 mala_string_free (str1
);
1045 mala_stringlist_elem_delete (list
, &node1
);
1046 mala_stringlist_elem_delete (list
, &node
);
1047 self
->state
= MALA_ESYNTAX
;
1048 return MALA_EXPANSION_ERROR
;
1051 mala_string_free (str1
);
1052 mala_stringlist_elem_delete (list
, &node1
);
1054 mala_stringlist_elem_delete (list
, &node
);
1056 self
->state
= MALA_EALLOC
;
1057 return MALA_EXPANSION_ERROR
;
1059 return MALA_NO_EXPANSION
;
1064 mala_engine_assign_contraction (MalaEngine self
,
1065 MalaStringList list
,
1066 MalaStringListNode_ref pptr
)
1068 MalaStringListNode assign
;
1069 MalaStringListNode value
;
1072 mala_stringlist_fwd (&assign
);
1075 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1076 && !mala_stringlist_is_tail (list
, *pptr
)
1077 && !mala_stringlist_is_tail (list
, assign
)
1078 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1081 MalaStringListNode node
;
1083 mala_stringlist_fwd (&value
);
1085 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1087 mala_string_cstr ((*pptr
)->string
),
1088 mala_string_cstr (value
->string
));
1091 node
= mala_stringlist_after_new (list
,
1097 mala_string_free (str
);
1098 mala_stringlist_elem_delete (list
, pptr
);
1099 mala_stringlist_elem_delete (list
, &assign
);
1100 mala_stringlist_elem_delete (list
, &value
);
1105 mala_string_free (str
);
1106 self
->state
= MALA_EALLOC
;
1107 return MALA_EXPANSION_ERROR
;
1109 return MALA_NO_EXPANSION
;
1116 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1119 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1120 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1127 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1129 MalaActionDesc desc
;
1130 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1134 /*only enabled when the topmost action is a subtitution to --TRUE*/
1135 if (desc
->actions
.lh_first
)
1136 return desc
->actions
.lh_first
->data
== self
->common_string
[MALA_STRING_TRUE
];
1155 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1159 if (self
->state
> MALA_EFAULT
)
1162 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1166 mala_actiondict_destroy_action (self
->actions
, act
);
1168 return MALA_SUCCESS
;
1171 self
->state
= MALA_ENOACTION
;
1178 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1180 MalaStringListNode base
= llist_get_prev (pptr
);
1181 while (mala_engine_eval (self
, llist_get_next (base
)) < MALA_EVAL
)
1182 if (llist_get_next (base
) == &self
->program
)
1183 return MALA_ENOACTION
;
1191 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1193 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1199 mala_engine_argc (MalaEngine self
)
1201 return llist_count (&self
->arguments
) + 1;
1205 mala_engine_argv (MalaEngine self
, int n
)
1207 MalaStringListNode p
;
1208 p
= llist_get_next (&self
->arguments
);
1211 return self
->argv_0
;
1215 if (p
== &self
->arguments
)
1217 p
= llist_get_next (p
);
1219 return (const char *)(p
)->data
;
1225 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1226 MalaParserFunc parser
, MalaDataDestructor destructor
)
1230 act
= mala_action_new (name
, data
, parser
, destructor
);
1234 self
->state
= mala_actiondict_push (self
->actions
, act
);
1241 mala_action_destroy (act
);
1247 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1251 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1253 return MALA_NO_EXPANSION
;
1255 if (act
->parser
!= mala_substitute_parser
)
1256 return MALA_EPARSER
;
1258 return mala_string_check ((t_uchar
*) act
->data
);
1263 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1265 return mala_actiondict_lookupaction (self
->actions
, name
);
1269 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1271 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1283 // c-file-style: "gnu"
1285 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100