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 #define MALA_EXPAND(e,S) S
32 static const char * mala_common_strings
[] = MALA_COMMON_STRINGS
;
37 * function definitions
46 self
= malloc (sizeof(mala_engine
));
53 self
->state
= MALA_SUCCESS
;
55 mala_stringbucket_init (&self
->words
, MALA_STRING_FWD
, (void(*)(void*)) mala_actiondesc_free
);
57 for (i
= 0; i
< MALA_STRING_MAX
; ++i
)
59 self
->common_string
[i
] = mala_string_new (mala_common_strings
[i
], &self
->words
);
60 if (!self
->common_string
[i
])
64 mala_stringlist_init (&self
->program
);
65 mala_stringlist_init (&self
->arguments
);
71 mala_string_free (self
->common_string
[i
]);
78 mala_engine_new_main (int (*initfunc
) (MalaEngine
),
79 int argc
, char **argv
,
80 mala_actioninit
* actions_init
)
82 /*TODO convinience function*/
87 mala_engine_expand_define (MalaEngine self
, const char * name
, int argc
, char ** argv
)
91 MalaStringListNode itr
;
96 if(self
->state
> MALA_EFAULT
)
99 mala_stringlist_init (&pre
);
101 for (i
= 0; i
!= argc
&& *argv
; ++i
,++argv
)
103 if (!mala_stringlist_tail_new_cstr (&pre
, *argv
, &self
->words
))
107 list
= mala_stringlist_new ();
111 /*TODO preprocess in own function*/
112 while (!mala_stringlist_is_empty (&pre
))
116 itr
= mala_stringlist_head (&pre
);
118 putaway
= mala_engine_expand (self
, &pre
, &itr
);
120 if (self
->state
> MALA_EFAULT
)
125 mala_stringlist_node_remove (&pre
, itr
);
126 mala_stringlist_tail_insert (list
, itr
);
127 if (putaway
&& mala_stringlist_is_empty (&pre
))
129 itr
= mala_stringlist_head (&pre
);
133 if (mala_stringlist_is_empty (list
))
135 /* empty substituted by --NULL, TODO use empty string instead? */
136 mala_stringlist_free (list
);
137 return mala_engine_add_action_cstr (self
, name
,
138 mala_string_copy (self
->common_string
[MALA_STRING_NULL
]),
139 mala_substitute_parser
,
140 (MalaDataFactory
)mala_string_factory
,
144 if (mala_stringlist_is_tail (list
, mala_stringlist_head (list
)))
149 subst
= mala_string_copy (mala_stringlist_head (list
) -> string
);
150 mala_stringlist_free (list
);
152 return mala_engine_add_action_cstr (self
, name
, subst
,
153 mala_substitute_parser
,
154 (MalaDataFactory
)mala_string_factory
,
160 return mala_engine_add_action_cstr (self
, name
, list
,
162 (MalaDataFactory
) mala_stringlist_factory
,
167 mala_stringlist_free (list
);
168 mala_stringlist_erase (&pre
);
169 return self
->state
= MALA_ESYNTAX
;
173 mala_stringlist_erase (&pre
);
174 return self
->state
= MALA_EALLOC
;
178 mala_engine_pushback_word (MalaEngine self
, const char * word
)
181 return MALA_EINVALID
;
182 if(self
->state
> MALA_EFAULT
)
185 if (!mala_stringlist_tail_new_cstr (&self
->program
, word
, &self
->words
))
186 return self
->state
= MALA_EALLOC
;
192 mala_engine_add_action_cstr (MalaEngine self
, const char * cname
, void * data
,
193 MalaParserFunc parser
, MalaDataFactory factory
,
199 /*TODO such checks everywhere*/
201 return MALA_EINVALID
;
202 if(self
->state
> MALA_EFAULT
)
205 name
= mala_string_new (cname
, &self
->words
);
209 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
213 if (mala_action_attach (action
) != MALA_SUCCESS
)
216 mala_string_free (name
);
220 mala_action_free (action
);
222 mala_string_free (name
);
224 return self
->state
= MALA_EALLOC
;
228 mala_engine_add_action (MalaEngine self
, MalaString name
, void * data
,
229 MalaParserFunc parser
, MalaDataFactory factory
,
234 /*TODO such checks everywhere*/
236 return MALA_EINVALID
;
237 if(self
->state
> MALA_EFAULT
)
240 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
244 if (mala_action_attach (action
) != MALA_SUCCESS
)
250 mala_action_free (action
);
252 return self
->state
= MALA_EALLOC
;
257 mala_engine_new_initfunc (int (*initfunc
)(MalaEngine
))
261 self
= mala_engine_new ();
265 self
->state
= initfunc (self
);
270 mala_engine_free (MalaEngine self
)
277 mala_stringlist_erase (&self
->program
);
278 mala_stringlist_erase (&self
->arguments
);
280 mala_stringbucket_erase (&self
->words
);
282 for (i
= 0; i
< MALA_STRING_MAX
; ++i
)
283 mala_string_free (self
->common_string
[i
]);
289 mala_engine_actions_register (MalaEngine self
, mala_actioninit
* actioninit
)
294 return MALA_EINVALID
;
296 if (self
->state
> MALA_EFAULT
)
299 while (actioninit
->command
)
301 action
= mala_action_new_actioninit (actioninit
, &self
->words
);
305 if (mala_action_attach (action
) != MALA_SUCCESS
)
314 return self
->state
= MALA_EINIT
;
318 /*TODO make some inlines { */
321 mala_engine_getprogram (MalaEngine self
)
323 return &self
->program
;
327 mala_engine_state_get (MalaEngine self
)
333 mala_engine_clearstate (MalaEngine self
)
335 self
->state
= MALA_SUCCESS
;
339 mala_engine_negated (MalaEngine self
)
341 return self
->negated
;
345 mala_engine_clear_negated (MalaEngine self
)
349 /* } TODO make some inlines */
353 mala_engine_dumpprogram (MalaEngine self
, const char * prefix
, const char * suffix
)
355 MalaStringListNode node
;
357 for (node
= mala_stringlist_head (&self
->program
);
358 node
!= (void *)&self
->program
;
359 mala_stringlist_fwd (&node
))
361 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
366 mala_engine_dumpargs (MalaEngine self
, const char * prefix
, const char * suffix
)
368 MalaStringListNode node
;
370 for (node
= mala_stringlist_head (&self
->arguments
);
371 node
!= (void *)&self
->arguments
;
372 mala_stringlist_fwd (&node
))
374 fprintf (stderr
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
380 mala_engine_run (MalaEngine self
)
382 MalaStringListNode pptr
;
384 while (self
->state
< MALA_EFAULT
&&
385 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
387 if (self
->state
== MALA_LITERAL
)
389 mala_stringlist_elem_remove (&self
->program
, pptr
);
390 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
391 self
->state
= MALA_SUCCESS
;
394 mala_engine_eval (self
, &pptr
);
400 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
405 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
409 act
= mala_actiondesc_top (desc
);
412 self
->state
= mala_action_execute (act
, pptr
, self
);
416 if (!(*pptr
= mala_stringlist_before_new (&self
->program
,
418 self
->common_string
[MALA_STRING_DEFAULT_PARSER
])))
419 return self
->state
= MALA_EALLOC
;
422 if (self
->state
== MALA_EXCEPTION
)
423 self
->state
= MALA_ENOACTION
;
429 mala_engine_eval_arg_n (MalaEngine self
, MalaStringListNode_ref pptr
, unsigned n
)
431 MalaStringListNode next
;
433 if (self
->state
> MALA_EFAULT
)
437 n
&& !mala_stringlist_is_tail (&self
->program
, next
);
438 mala_stringlist_fwd (&next
), --n
);
443 self
->state
= MALA_SUCCESS
;
444 while (self
->state
< MALA_EXCEPTION
)
446 mala_engine_eval (self
, &next
);
447 if (mala_stringlist_is_end (&self
->program
, next
))
454 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
455 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
460 mala_engine_get_arg_n (MalaEngine self
, MalaStringListNode_ref pptr
, unsigned n
)
462 MalaStringListNode next
;
464 if (self
->state
> MALA_EFAULT
)
468 n
&& !mala_stringlist_is_tail (&self
->program
, next
);
469 mala_stringlist_fwd (&next
), --n
);
474 self
->state
= MALA_SUCCESS
;
476 if (mala_stringlist_is_end (&self
->program
, next
))
482 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
483 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
489 mala_engine_exception (MalaEngine self
,
490 MalaStringListNode_ref pptr
,
491 MalaStringListNode here
,
494 MalaStringListNode tmp
;
496 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
498 return self
->state
= MALA_EALLOC
;
500 if (!mala_stringlist_after_new (&self
->program
, here
,
501 self
->common_string
[MALA_STRING_HERE
]))
502 return self
->state
= MALA_EALLOC
;
506 /*TODO self-state needs to be preserved somehow?*/
507 return self
->state
= MALA_EXCEPTION
;
512 mala_engine_expand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
516 if (self
->state
> MALA_EFAULT
)
517 return MALA_EXPANSION_ERROR
;
519 #define mala_run_expansion(name) \
520 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
522 mala_run_expansion (literal_expansion
);
523 mala_run_expansion (numsplit_expansion
);
524 mala_run_expansion (exclam_expansion
);
525 mala_run_expansion (no_expansion
);
526 mala_run_expansion (assign_expansion
);
527 mala_run_expansion (char_expansion
);
528 mala_run_expansion (underscore_expansion
);
529 mala_run_expansion (bracket_expansion
);
530 mala_run_expansion (assign_contraction
);
531 mala_run_expansion (envvar_expansion
);
532 mala_run_expansion (setenv_expansion
);
533 mala_run_expansion (backquote_expansion
);
534 #undef mala_run_expansion
540 mala_engine_literal_expansion (MalaEngine self
,
542 MalaStringListNode_ref pptr
)
544 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
545 && mala_string_check_prefix ((*pptr
)->string
, "`")
546 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
549 MalaStringListNode newnode1
;
550 MalaStringListNode newnode2
;
552 newnode1
= mala_stringlist_after_new (list
,
554 self
->common_string
[MALA_STRING_LITERAL
]);
556 goto ealloc_newnode1
;
558 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
559 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
561 goto ealloc_newnode2
;
563 mala_stringlist_elem_delete (list
, *pptr
);
569 mala_stringlist_elem_delete (list
, newnode1
);
571 self
->state
= MALA_EALLOC
;
572 return MALA_EXPANSION_ERROR
;
574 return MALA_NO_EXPANSION
;
579 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
581 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
582 && mala_string_check_prefix ((*pptr
)->string
, "``"))
585 MalaStringListNode newnode
;
587 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
588 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
592 mala_stringlist_elem_delete (list
, *pptr
);
598 self
->state
= MALA_EALLOC
;
599 return MALA_EXPANSION_ERROR
;
601 return MALA_NO_EXPANSION
;
605 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
607 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
608 && mala_string_length ((*pptr
)->string
) > 2
609 && mala_string_at ((*pptr
)->string
, 0) == '-'
610 && isalpha (mala_string_at ((*pptr
)->string
, 1))
615 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
617 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
622 MalaStringListNode na
;
623 MalaStringListNode nb
;
625 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
626 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
630 na
= mala_stringlist_after_new (list
, *pptr
, a
);
634 nb
= mala_stringlist_after_new (list
, na
, b
);
638 mala_stringlist_elem_delete (list
, *pptr
);
641 mala_string_free (a
);
642 mala_string_free (b
);
647 mala_stringlist_elem_delete (list
, na
);
650 mala_string_free (a
);
651 mala_string_free (b
);
652 self
->state
= MALA_EALLOC
;
653 return MALA_EXPANSION_ERROR
;
657 return MALA_NO_EXPANSION
;
662 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
664 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
665 && mala_string_length ((*pptr
)->string
) == 1
666 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
668 MalaStringListNode newnode
;
670 newnode
= mala_stringlist_after_new (list
,
672 self
->common_string
[MALA_STRING_NOT
]);
674 return self
->state
= MALA_EALLOC
;
676 mala_stringlist_elem_delete (list
, *pptr
);
680 return MALA_NO_EXPANSION
;
685 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
687 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
688 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
689 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
693 MalaStringListNode n1
;
694 MalaStringListNode n2
;
696 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
697 aa
= mala_string_new_prefix ("--", a
);
701 n1
= mala_stringlist_after_new (list
,
702 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
706 n2
= mala_stringlist_after_new (list
, n1
, aa
);
710 mala_string_free (a
);
711 mala_string_free (aa
);
712 mala_stringlist_elem_delete (list
, *pptr
);
717 mala_stringlist_elem_delete (list
, n1
);
719 mala_string_free (a
);
720 mala_string_free (aa
);
722 self
->state
= MALA_EALLOC
;
723 return MALA_EXPANSION_ERROR
;
725 return MALA_NO_EXPANSION
;
730 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
734 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
735 && mala_string_check_prefix ((*pptr
)->string
, "--")
736 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
737 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
742 MalaStringListNode na
;
743 MalaStringListNode nb
;
745 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
746 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
750 na
= mala_stringlist_after_new (list
, *pptr
, a
);
754 nb
= mala_stringlist_after_new (list
, na
, b
);
758 mala_stringlist_elem_delete (list
, *pptr
);
761 mala_string_free (a
);
762 mala_string_free (b
);
768 mala_stringlist_elem_delete (list
, na
);
771 mala_string_free (a
);
772 mala_string_free (b
);
773 self
->state
= MALA_EALLOC
;
774 return MALA_EXPANSION_ERROR
;
776 return MALA_NO_EXPANSION
;
781 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
783 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
784 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
786 MalaStringListNode newnode
;
788 newnode
= mala_stringlist_before_new (list
,
790 self
->common_string
[MALA_STRING_ENVSUBST
]);
798 self
->state
= MALA_EALLOC
;
799 return MALA_EXPANSION_ERROR
;
802 return MALA_NO_EXPANSION
;
807 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
809 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
810 && mala_string_length ((*pptr
)->string
) > 2
811 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
812 || mala_string_at ((*pptr
)->string
, 0) == '+')
813 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
815 char prefix
[2] = "-";
816 char current
[2] = " ";
821 MalaStringListNode node
= NULL
;
822 MalaStringListNode pred
= *pptr
;
825 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
827 if (*i
== '-' || *i
== '+')
829 else if (isalpha (*i
))
833 str
= mala_string_new_cat2 (prefix
, current
,
834 mala_string_bucket_get ((*pptr
)->string
));
838 node
= mala_stringlist_after_new (list
,
844 mala_string_free (str
);
851 mala_stringlist_fwd (&pred
);
852 mala_stringlist_elem_delete (list
, *pptr
);
857 mala_string_free (str
);
858 /* cleanup from pred downto pptr */
859 while (pred
!= *pptr
)
861 // TODO use stringlist func
862 MalaStringListNode tmp
= pred
->node
.cqe_prev
;
863 mala_stringlist_elem_delete (list
, pred
);
866 self
->state
= MALA_EALLOC
;
867 return MALA_EXPANSION_ERROR
;
869 return MALA_NO_EXPANSION
;
874 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
876 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
877 && mala_string_check_prefix ((*pptr
)->string
, "--")
878 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
881 MalaStringListNode node
;
885 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
889 for (i
= cstr
+ 2; *i
; ++i
)
895 str
= mala_string_new (cstr
, &self
->words
);
899 node
= mala_stringlist_after_new (list
,
906 mala_string_free (str
);
908 mala_stringlist_elem_delete (list
, *pptr
);
913 mala_string_free (str
);
917 self
->state
= MALA_EALLOC
;
918 return MALA_EXPANSION_ERROR
;
920 return MALA_NO_EXPANSION
;
925 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
929 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
930 && mala_string_length ((*pptr
)->string
) > 1
931 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
934 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
938 MalaStringListNode n1
;
939 MalaStringListNode n2
;
940 MalaStringListNode n3
;
942 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
946 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
950 n1
= mala_stringlist_after_new (list
,
951 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
955 n2
= mala_stringlist_after_new (list
, n1
, key
);
959 n3
= mala_stringlist_after_new (list
, n2
, value
);
963 mala_string_free (key
);
964 mala_string_free (value
);
965 mala_stringlist_elem_delete (list
, *pptr
);
970 mala_stringlist_elem_delete (list
, n2
);
972 mala_stringlist_elem_delete (list
, n1
);
974 mala_string_free (value
);
976 mala_string_free (key
);
978 self
->state
= MALA_EALLOC
;
979 return MALA_EXPANSION_ERROR
;
981 return MALA_NO_EXPANSION
;
986 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
988 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
989 && mala_string_at ((*pptr
)->string
, 0) == '[')
991 MalaStringListNode nitr
;
992 MalaStringListNode node
;
994 MalaString str1
= NULL
;
995 MalaStringListNode node1
;
997 MalaString str2
= NULL
;
998 MalaStringListNode node2
;
1000 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
1004 if (mala_string_length((*pptr
)->string
) > 1)
1006 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
1007 node1
= mala_stringlist_after_new (list
, node
, str1
);
1014 mala_stringlist_fwd (&node1
);
1017 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlist_fwd (&nitr
))
1019 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1023 if ((void*)nitr
!= (void*)list
)
1025 if (mala_string_length(nitr
->string
) > 1)
1027 str2
= mala_string_new_substr (nitr
->string
, 0,
1028 mala_string_length(nitr
->string
) - 1);
1029 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1038 mala_string_free (str1
);
1039 mala_string_free (str2
);
1040 mala_stringlist_elem_delete (list
, *pptr
);
1041 mala_stringlist_elem_delete (list
, nitr
);
1047 mala_string_free (str1
);
1048 mala_stringlist_elem_delete (list
, node1
);
1049 mala_stringlist_elem_delete (list
, node
);
1050 self
->state
= MALA_ESYNTAX
;
1051 return MALA_EXPANSION_ERROR
;
1054 mala_string_free (str1
);
1055 mala_stringlist_elem_delete (list
, node1
);
1057 mala_stringlist_elem_delete (list
, node
);
1059 self
->state
= MALA_EALLOC
;
1060 return MALA_EXPANSION_ERROR
;
1062 return MALA_NO_EXPANSION
;
1067 mala_engine_assign_contraction (MalaEngine self
,
1068 MalaStringList list
,
1069 MalaStringListNode_ref pptr
)
1071 MalaStringListNode assign
;
1072 MalaStringListNode value
;
1075 mala_stringlist_fwd (&assign
);
1078 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1079 && !mala_stringlist_is_tail (list
, *pptr
)
1080 && !mala_stringlist_is_tail (list
, assign
)
1081 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1084 MalaStringListNode node
;
1086 mala_stringlist_fwd (&value
);
1088 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1090 mala_string_cstr ((*pptr
)->string
),
1091 mala_string_cstr (value
->string
));
1094 node
= mala_stringlist_after_new (list
,
1100 mala_string_free (str
);
1101 mala_stringlist_elem_delete (list
, *pptr
);
1102 mala_stringlist_elem_delete (list
, assign
);
1103 mala_stringlist_elem_delete (list
, value
);
1108 mala_string_free (str
);
1109 self
->state
= MALA_EALLOC
;
1110 return MALA_EXPANSION_ERROR
;
1112 return MALA_NO_EXPANSION
;
1119 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1122 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1123 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1130 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1132 MalaActionDesc desc
;
1133 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1137 /*only enabled when the topmost action is a subtitution to --TRUE*/
1138 if (desc
->actions
.lh_first
)
1139 return desc
->actions
.lh_first
->data
== self
->common_string
[MALA_STRING_TRUE
];
1158 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1162 if (self
->state
> MALA_EFAULT
)
1165 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1169 mala_actiondict_destroy_action (self
->actions
, act
);
1171 return MALA_SUCCESS
;
1174 self
->state
= MALA_ENOACTION
;
1181 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1183 MalaStringListNode base
= llist_get_prev (pptr
);
1184 while (mala_engine_eval (self
, llist_get_next (base
)) < MALA_EVAL
)
1185 if (llist_get_next (base
) == &self
->program
)
1186 return MALA_ENOACTION
;
1194 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1196 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1202 mala_engine_argc (MalaEngine self
)
1204 return llist_count (&self
->arguments
) + 1;
1208 mala_engine_argv (MalaEngine self
, int n
)
1210 MalaStringListNode p
;
1211 p
= llist_get_next (&self
->arguments
);
1214 return self
->argv_0
;
1218 if (p
== &self
->arguments
)
1220 p
= llist_get_next (p
);
1222 return (const char *)(p
)->data
;
1228 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1229 MalaParserFunc parser
, MalaDataDestructor destructor
)
1233 act
= mala_action_new (name
, data
, parser
, destructor
);
1237 self
->state
= mala_actiondict_push (self
->actions
, act
);
1244 mala_action_destroy (act
);
1250 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1254 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1256 return MALA_NO_EXPANSION
;
1258 if (act
->parser
!= mala_substitute_parser
)
1259 return MALA_EPARSER
;
1261 return mala_string_check ((t_uchar
*) act
->data
);
1266 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1268 return mala_actiondict_lookupaction (self
->actions
, name
);
1272 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1274 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1286 // c-file-style: "gnu"
1288 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100