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
[]=
46 "--FLAG-LITERAL-EXPANSION",
47 "--FLAG-EXCLAM-EXPANSION",
48 "--FLAG-NO-EXPANSION",
49 "--FLAG-NUMSPLIT-EXPANSION",
50 "--FLAG-CHAR-EXPANSION",
51 "--FLAG-ASSIGN-EXPANSION",
52 "--FLAG-SETENV-EXPANSION",
53 "--FLAG-ENVVAR-EXPANSION",
54 "--FLAG-UNDERSCORE-EXPANSION",
55 "--FLAG-BRACKET-EXPANSION",
56 "--FLAG-ASSIGN-CONTRACTION",
57 "--ERROR-MISSING-ARGUMENT",
65 * function definitions
74 self
= malloc (sizeof(mala_engine
));
80 self
->state
= MALA_SUCCESS
;
82 mala_stringbucket_init (&self
->words
, MALA_STRING_FWD
, (void(*)(void*)) mala_actiondesc_free
);
84 for (i
= 0; i
< MALA_MAX_COMMON_STRING
; ++i
)
86 self
->common_string
[i
] = mala_string_new (mala_common_strings
[i
], &self
->words
);
87 if (!self
->common_string
[i
])
91 mala_stringlist_init (&self
->program
);
92 mala_stringlist_init (&self
->arguments
);
98 mala_string_free (self
->common_string
[i
]);
105 mala_engine_new_main (int (*initfunc
) (MalaEngine
),
106 int argc
, char **argv
,
107 mala_actioninit
* actions_init
)
109 /*TODO convinience function*/
114 mala_engine_macro_define (MalaEngine self
, const char * name
, int argc
, char ** argv
)
118 MalaStringListNode itr
;
123 return MALA_EINVALID
;
124 if(self
->state
> MALA_EFAULT
)
127 mala_stringlist_init (&pre
);
129 for (i
= 0; i
!= argc
&& *argv
; ++i
,++argv
)
131 if (!mala_stringlist_tail_new_cstr (&pre
, *argv
, &self
->words
))
135 list
= mala_stringlist_new ();
139 /*TODO preprocess in own function*/
140 while (!mala_stringlist_is_empty (&pre
))
144 itr
= mala_stringlist_head (&pre
);
146 putaway
= mala_engine_expand (self
, &pre
, &itr
);
148 if (self
->state
> MALA_EFAULT
)
153 mala_stringlist_node_remove (&pre
, itr
);
154 mala_stringlist_tail_insert (list
, itr
);
155 if (putaway
&& mala_stringlist_is_empty (&pre
))
157 itr
= mala_stringlist_head (&pre
);
161 if (mala_stringlist_is_empty (list
))
163 /* empty substituted by --NULL, TODO use empty string instead? */
164 mala_stringlist_free (list
);
165 return mala_engine_add_action (self
, name
,
166 mala_string_copy(self
->common_string
[MALA_STRING_NULL
]),
167 mala_substitute_parser
,
168 (MalaDataFactory
)mala_string_factory
,
173 for (itr
= mala_stringlist_head (list
);
174 !mala_stringlist_is_end (list
, itr
);
175 mala_stringlist_fwd(&itr
))
176 if (mala_string_char_find (itr
->string
, '%') != SIZE_MAX
)
185 return mala_engine_add_action (self
, name
, list
,
187 (MalaDataFactory
)mala_stringlist_factory
,
190 else if (mala_stringlist_is_tail (list
, mala_stringlist_head (list
)))
195 subst
= mala_string_copy (mala_stringlist_head (list
) -> string
);
196 mala_stringlist_free (list
);
198 return mala_engine_add_action (self
, name
, subst
,
199 mala_substitute_parser
,
200 (MalaDataFactory
)mala_string_factory
,
206 return mala_engine_add_action (self
, name
, list
,
208 (MalaDataFactory
) mala_stringlist_factory
,
213 mala_stringlist_free (list
);
214 mala_stringlist_erase (&pre
);
215 return self
->state
= MALA_ESYNTAX
;
219 mala_stringlist_erase (&pre
);
220 return self
->state
= MALA_EALLOC
;
224 mala_engine_pushback_word (MalaEngine self
, const char * word
)
227 return MALA_EINVALID
;
228 if(self
->state
> MALA_EFAULT
)
231 if (!mala_stringlist_tail_new_cstr (&self
->program
, word
, &self
->words
))
232 return self
->state
= MALA_EALLOC
;
238 mala_engine_add_action (MalaEngine self
, const char * cname
, void * data
,
239 MalaParserFunc parser
, MalaDataFactory factory
,
245 /*TODO such checks everywhere*/
247 return MALA_EINVALID
;
248 if(self
->state
> MALA_EFAULT
)
251 name
= mala_string_new (cname
, &self
->words
);
255 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
259 if (mala_action_attach (action
) != MALA_SUCCESS
)
262 mala_string_free (name
);
266 mala_action_free (action
);
268 mala_string_free (name
);
270 return self
->state
= MALA_EALLOC
;
275 mala_engine_new_initfunc (int (*initfunc
)(MalaEngine
))
279 self
= mala_engine_new ();
283 self
->state
= initfunc (self
);
288 mala_engine_free (MalaEngine self
)
295 mala_stringlist_erase (&self
->program
);
296 mala_stringlist_erase (&self
->arguments
);
298 mala_stringbucket_erase (&self
->words
);
300 for (i
= 0; i
< MALA_MAX_COMMON_STRING
; ++i
)
301 mala_string_free (self
->common_string
[i
]);
307 mala_engine_actions_register (MalaEngine self
, mala_actioninit
* actioninit
)
312 return MALA_EINVALID
;
314 if (self
->state
> MALA_EFAULT
)
317 while (actioninit
->command
)
319 action
= mala_action_new_actioninit (actioninit
, &self
->words
);
323 if (mala_action_attach (action
) != MALA_SUCCESS
)
332 return self
->state
= MALA_EINIT
;
336 /*TODO make some inlines { */
339 mala_engine_getprogram (MalaEngine self
)
341 return &self
->program
;
345 mala_engine_state_get (MalaEngine self
)
351 mala_engine_clearstate (MalaEngine self
)
353 self
->state
= MALA_SUCCESS
;
357 mala_engine_negated (MalaEngine self
)
359 return self
->negated
;
363 mala_engine_clear_negated (MalaEngine self
)
367 /* } TODO make some inlines */
371 mala_engine_dumpprogram (MalaEngine self
, const char * prefix
, const char * suffix
)
373 MalaStringListNode node
;
375 for (node
= mala_stringlist_head (&self
->program
);
376 node
!= (void *)&self
->program
;
377 mala_stringlist_fwd (&node
))
379 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
384 mala_engine_dumpargs (MalaEngine self
, const char * prefix
, const char * suffix
)
386 MalaStringListNode node
;
388 for (node
= mala_stringlist_head (&self
->arguments
);
389 node
!= (void *)&self
->arguments
;
390 mala_stringlist_fwd (&node
))
392 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
398 mala_engine_run (MalaEngine self
)
400 MalaStringListNode pptr
;
402 while (self
->state
< MALA_EFAULT
&&
403 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
405 if (self
->state
== MALA_LITERAL
)
407 self
->state
= (mala_engine_string_istrue (self
, pptr
->string
) ^ self
->negated
)?
408 MALA_SUCCESS
: MALA_FAILURE
;
409 mala_stringlist_elem_remove (&self
->program
, pptr
);
410 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
413 mala_engine_eval (self
, &pptr
);
419 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
424 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
426 return self
->state
= MALA_LITERAL
;
428 act
= mala_actiondesc_top (desc
);
431 self
->state
= mala_action_execute(act
, pptr
, self
);
433 if (self
->state
== MALA_EXCEPTION
)
434 self
->state
= MALA_ENOACTION
;
440 mala_engine_try_eval_arg_n (MalaEngine self
, MalaStringListNode_ref pptr
, unsigned n
)
442 MalaStringListNode next
;
444 n
&& !mala_stringlist_is_tail (&self
->program
, next
);
445 mala_stringlist_fwd (&next
), --n
);
447 while (!mala_stringlist_is_tail (&self
->program
, *pptr
) && self
->state
< MALA_EXCEPTION
)
449 mala_engine_eval (self
, &next
);
454 mala_engine_exception (MalaEngine self
,
455 MalaStringListNode_ref pptr
,
456 MalaStringListNode here
,
459 MalaStringListNode tmp
;
461 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
463 return self
->state
= MALA_EALLOC
;
465 if (!mala_stringlist_after_new (&self
->program
, here
,
466 self
->common_string
[MALA_STRING_HERE
]))
467 return self
->state
= MALA_EALLOC
;
471 /*TODO self-state needs to be preserved somehow?*/
472 return self
->state
= MALA_EXCEPTION
;
477 mala_engine_expand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
481 if (self
->state
> MALA_EFAULT
)
482 return MALA_EXPANSION_ERROR
;
484 #define mala_run_expansion(name) \
485 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
487 mala_run_expansion (literal_expansion
);
488 mala_run_expansion (numsplit_expansion
);
489 mala_run_expansion (exclam_expansion
);
490 mala_run_expansion (no_expansion
);
491 mala_run_expansion (assign_expansion
);
492 mala_run_expansion (char_expansion
);
493 mala_run_expansion (underscore_expansion
);
494 mala_run_expansion (bracket_expansion
);
495 mala_run_expansion (assign_contraction
);
496 mala_run_expansion (envvar_expansion
);
497 mala_run_expansion (setenv_expansion
);
498 mala_run_expansion (backquote_expansion
);
499 #undef mala_run_expansion
505 mala_engine_literal_expansion (MalaEngine self
,
507 MalaStringListNode_ref pptr
)
509 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
510 && mala_string_check_prefix ((*pptr
)->string
, "`")
511 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
514 MalaStringListNode newnode1
;
515 MalaStringListNode newnode2
;
517 newnode1
= mala_stringlist_after_new (list
,
519 self
->common_string
[MALA_STRING_LITERAL
]);
521 goto ealloc_newnode1
;
523 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
524 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
526 goto ealloc_newnode2
;
528 mala_stringlist_elem_delete (list
, pptr
);
534 mala_stringlist_elem_delete (list
, &newnode1
);
536 self
->state
= MALA_EALLOC
;
537 return MALA_EXPANSION_ERROR
;
539 return MALA_NO_EXPANSION
;
544 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
546 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
547 && mala_string_check_prefix ((*pptr
)->string
, "``"))
550 MalaStringListNode newnode
;
552 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
553 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
557 mala_stringlist_elem_delete (list
, pptr
);
563 self
->state
= MALA_EALLOC
;
564 return MALA_EXPANSION_ERROR
;
566 return MALA_NO_EXPANSION
;
570 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
572 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
573 && mala_string_length ((*pptr
)->string
) > 2
574 && mala_string_at ((*pptr
)->string
, 0) == '-'
575 && isalpha (mala_string_at ((*pptr
)->string
, 1))
580 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
582 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
587 MalaStringListNode na
;
588 MalaStringListNode nb
;
590 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
591 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
595 na
= mala_stringlist_after_new (list
, *pptr
, a
);
599 nb
= mala_stringlist_after_new (list
, na
, b
);
603 mala_stringlist_elem_delete (list
, pptr
);
606 mala_string_free (a
);
607 mala_string_free (b
);
612 mala_stringlist_elem_delete (list
, &na
);
615 mala_string_free (a
);
616 mala_string_free (b
);
617 self
->state
= MALA_EALLOC
;
618 return MALA_EXPANSION_ERROR
;
622 return MALA_NO_EXPANSION
;
627 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
629 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
630 && mala_string_length ((*pptr
)->string
) == 1
631 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
633 MalaStringListNode newnode
;
635 newnode
= mala_stringlist_after_new (list
,
637 self
->common_string
[MALA_STRING_NOT
]);
639 return self
->state
= MALA_EALLOC
;
641 mala_stringlist_elem_delete (list
, pptr
);
645 return MALA_NO_EXPANSION
;
650 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
652 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
653 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
654 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
658 MalaStringListNode n1
;
659 MalaStringListNode n2
;
661 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
662 aa
= mala_string_new_prefix ("--", a
);
666 n1
= mala_stringlist_after_new (list
,
667 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
671 n2
= mala_stringlist_after_new (list
, n1
, aa
);
675 mala_string_free (a
);
676 mala_string_free (aa
);
677 mala_stringlist_elem_delete (list
, pptr
);
682 mala_stringlist_elem_delete (list
, &n1
);
684 mala_string_free (a
);
685 mala_string_free (aa
);
687 self
->state
= MALA_EALLOC
;
688 return MALA_EXPANSION_ERROR
;
690 return MALA_NO_EXPANSION
;
695 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
699 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
700 && mala_string_check_prefix ((*pptr
)->string
, "--")
701 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
702 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
707 MalaStringListNode na
;
708 MalaStringListNode nb
;
710 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
711 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
715 na
= mala_stringlist_after_new (list
, *pptr
, a
);
719 nb
= mala_stringlist_after_new (list
, na
, b
);
723 mala_stringlist_elem_delete (list
, pptr
);
726 mala_string_free (a
);
727 mala_string_free (b
);
733 mala_stringlist_elem_delete (list
, &na
);
736 mala_string_free (a
);
737 mala_string_free (b
);
738 self
->state
= MALA_EALLOC
;
739 return MALA_EXPANSION_ERROR
;
741 return MALA_NO_EXPANSION
;
746 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
748 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
749 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
751 MalaStringListNode newnode
;
753 newnode
= mala_stringlist_before_new (list
,
755 self
->common_string
[MALA_STRING_ENVSUBST
]);
763 self
->state
= MALA_EALLOC
;
764 return MALA_EXPANSION_ERROR
;
767 return MALA_NO_EXPANSION
;
772 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
774 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
775 && mala_string_length ((*pptr
)->string
) > 2
776 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
777 || mala_string_at ((*pptr
)->string
, 0) == '+')
778 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
780 char prefix
[2] = "-";
781 char current
[2] = " ";
786 MalaStringListNode node
= NULL
;
787 MalaStringListNode pred
= *pptr
;
790 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
792 if (*i
== '-' || *i
== '+')
794 else if (isalpha (*i
))
798 str
= mala_string_new_cat2 (prefix
, current
,
799 mala_string_bucket_get ((*pptr
)->string
));
803 node
= mala_stringlist_after_new (list
,
809 mala_string_free (str
);
816 mala_stringlist_fwd (&pred
);
817 mala_stringlist_elem_delete (list
, pptr
);
822 mala_string_free (str
);
823 /* cleanup from pred downto pptr */
824 while (pred
!= *pptr
)
826 // TODO use stringlist func
827 MalaStringListNode tmp
= pred
->node
.cqe_prev
;
828 mala_stringlist_elem_delete (list
, &pred
);
831 self
->state
= MALA_EALLOC
;
832 return MALA_EXPANSION_ERROR
;
834 return MALA_NO_EXPANSION
;
839 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
841 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
842 && mala_string_check_prefix ((*pptr
)->string
, "--")
843 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
846 MalaStringListNode node
;
850 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
854 for (i
= cstr
+ 2; *i
; ++i
)
860 str
= mala_string_new (cstr
, &self
->words
);
864 node
= mala_stringlist_after_new (list
,
871 mala_string_free (str
);
873 mala_stringlist_elem_delete (list
, pptr
);
878 mala_string_free (str
);
882 self
->state
= MALA_EALLOC
;
883 return MALA_EXPANSION_ERROR
;
885 return MALA_NO_EXPANSION
;
890 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
894 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
895 && mala_string_length ((*pptr
)->string
) > 1
896 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
899 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
903 MalaStringListNode n1
;
904 MalaStringListNode n2
;
905 MalaStringListNode n3
;
907 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
911 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
915 n1
= mala_stringlist_after_new (list
,
916 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
920 n2
= mala_stringlist_after_new (list
, n1
, key
);
924 n3
= mala_stringlist_after_new (list
, n2
, value
);
928 mala_string_free (key
);
929 mala_string_free (value
);
930 mala_stringlist_elem_delete (list
, pptr
);
935 mala_stringlist_elem_delete (list
, &n2
);
937 mala_stringlist_elem_delete (list
, &n1
);
939 mala_string_free (value
);
941 mala_string_free (key
);
943 self
->state
= MALA_EALLOC
;
944 return MALA_EXPANSION_ERROR
;
946 return MALA_NO_EXPANSION
;
951 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
953 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
954 && mala_string_at ((*pptr
)->string
, 0) == '[')
956 MalaStringListNode nitr
;
957 MalaStringListNode node
;
959 MalaString str1
= NULL
;
960 MalaStringListNode node1
;
962 MalaString str2
= NULL
;
963 MalaStringListNode node2
;
965 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
969 if (mala_string_length((*pptr
)->string
) > 1)
971 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
972 node1
= mala_stringlist_after_new (list
, node
, str1
);
979 mala_stringlist_fwd (&node1
);
982 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlist_fwd (&nitr
))
984 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
988 if ((void*)nitr
!= (void*)list
)
990 if (mala_string_length(nitr
->string
) > 1)
992 str2
= mala_string_new_substr (nitr
->string
, 0,
993 mala_string_length(nitr
->string
) - 1);
994 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1003 mala_string_free (str1
);
1004 mala_string_free (str2
);
1005 mala_stringlist_elem_delete (list
, pptr
);
1006 mala_stringlist_elem_delete (list
, &nitr
);
1012 mala_string_free (str1
);
1013 mala_stringlist_elem_delete (list
, &node1
);
1014 mala_stringlist_elem_delete (list
, &node
);
1015 self
->state
= MALA_ESYNTAX
;
1016 return MALA_EXPANSION_ERROR
;
1019 mala_string_free (str1
);
1020 mala_stringlist_elem_delete (list
, &node1
);
1022 mala_stringlist_elem_delete (list
, &node
);
1024 self
->state
= MALA_EALLOC
;
1025 return MALA_EXPANSION_ERROR
;
1027 return MALA_NO_EXPANSION
;
1032 mala_engine_assign_contraction (MalaEngine self
,
1033 MalaStringList list
,
1034 MalaStringListNode_ref pptr
)
1036 MalaStringListNode assign
;
1037 MalaStringListNode value
;
1040 mala_stringlist_fwd (&assign
);
1043 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1044 && !mala_stringlist_is_tail (list
, *pptr
)
1045 && !mala_stringlist_is_tail (list
, assign
)
1046 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1049 MalaStringListNode node
;
1051 mala_stringlist_fwd (&value
);
1053 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1055 mala_string_cstr ((*pptr
)->string
),
1056 mala_string_cstr (value
->string
));
1059 node
= mala_stringlist_after_new (list
,
1065 mala_string_free (str
);
1066 mala_stringlist_elem_delete (list
, pptr
);
1067 mala_stringlist_elem_delete (list
, &assign
);
1068 mala_stringlist_elem_delete (list
, &value
);
1073 mala_string_free (str
);
1074 self
->state
= MALA_EALLOC
;
1075 return MALA_EXPANSION_ERROR
;
1077 return MALA_NO_EXPANSION
;
1084 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1087 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1088 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1095 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1097 MalaActionDesc desc
;
1098 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1102 /*only enabled when the topmost action is a subtitution to --TRUE*/
1103 if (desc
->actions
.lh_first
)
1104 return desc
->actions
.lh_first
->data
== self
->common_string
[MALA_STRING_TRUE
];
1123 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1127 if (self
->state
> MALA_EFAULT
)
1130 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1134 mala_actiondict_destroy_action (self
->actions
, act
);
1136 return MALA_SUCCESS
;
1139 self
->state
= MALA_ENOACTION
;
1146 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1148 MalaStringListNode base
= llist_get_prev (pptr
);
1149 while (mala_engine_eval (self
, llist_get_next (base
)) < MALA_EVAL
)
1150 if (llist_get_next (base
) == &self
->program
)
1151 return MALA_ENOACTION
;
1159 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1161 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1167 mala_engine_argc (MalaEngine self
)
1169 return llist_count (&self
->arguments
) + 1;
1173 mala_engine_argv (MalaEngine self
, int n
)
1175 MalaStringListNode p
;
1176 p
= llist_get_next (&self
->arguments
);
1179 return self
->argv_0
;
1183 if (p
== &self
->arguments
)
1185 p
= llist_get_next (p
);
1187 return (const char *)(p
)->data
;
1193 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1194 MalaParserFunc parser
, MalaDataDestructor destructor
)
1198 act
= mala_action_new (name
, data
, parser
, destructor
);
1202 self
->state
= mala_actiondict_push (self
->actions
, act
);
1209 mala_action_destroy (act
);
1215 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1219 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1221 return MALA_NO_EXPANSION
;
1223 if (act
->parser
!= mala_substitute_parser
)
1224 return MALA_EPARSER
;
1226 return mala_string_check ((t_uchar
*) act
->data
);
1231 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1233 return mala_actiondict_lookupaction (self
->actions
, name
);
1237 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1239 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1251 // c-file-style: "gnu"
1253 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100