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 Evaluate the nth argument until one of the following happens
430 - for at most 'times'
431 - until we reach the state of MALA_LITERAL (no further expansions are possible)
432 - an error/exception is flagged
433 - the type associated with the data of the current word equals to 'type'
436 mala_engine_arg_eval (MalaEngine self
,
437 MalaStringListNode_ref pptr
,
440 MalaDataFactory type
)
443 MalaStringListNode next
;
445 if (!self
|| self
->state
> MALA_EFAULT
)
449 nth
&& !mala_stringlist_is_tail (&self
->program
, next
);
450 mala_stringlist_fwd (&next
), --nth
);
455 self
->state
= MALA_SUCCESS
;
456 act
= mala_actiondesc_top ((MalaActionDesc
) mala_string_user_get (next
->string
));
457 while (self
->state
< MALA_EXCEPTION
459 && ((act
&& type
) ? (act
->factory
!= type
) : 1))
461 mala_engine_eval (self
, &next
);
462 if (mala_stringlist_is_end (&self
->program
, next
))
469 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
470 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
476 mala_engine_exception (MalaEngine self
,
477 MalaStringListNode_ref pptr
,
478 MalaStringListNode here
,
481 MalaStringListNode tmp
;
483 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
485 return self
->state
= MALA_EALLOC
;
487 if (!mala_stringlist_after_new (&self
->program
, here
,
488 self
->common_string
[MALA_STRING_HERE
]))
489 return self
->state
= MALA_EALLOC
;
493 /*TODO self-state needs to be preserved somehow?*/
494 return self
->state
= MALA_EXCEPTION
;
499 mala_engine_expand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
503 if (self
->state
> MALA_EFAULT
)
504 return MALA_EXPANSION_ERROR
;
506 #define mala_run_expansion(name) \
507 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
509 mala_run_expansion (literal_expansion
);
510 mala_run_expansion (numsplit_expansion
);
511 mala_run_expansion (exclam_expansion
);
512 mala_run_expansion (no_expansion
);
513 mala_run_expansion (assign_expansion
);
514 mala_run_expansion (char_expansion
);
515 mala_run_expansion (underscore_expansion
);
516 mala_run_expansion (bracket_expansion
);
517 mala_run_expansion (assign_contraction
);
518 mala_run_expansion (envvar_expansion
);
519 mala_run_expansion (setenv_expansion
);
520 mala_run_expansion (backquote_expansion
);
521 #undef mala_run_expansion
527 mala_engine_literal_expansion (MalaEngine self
,
529 MalaStringListNode_ref pptr
)
531 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
532 && mala_string_check_prefix ((*pptr
)->string
, "`")
533 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
536 MalaStringListNode newnode1
;
537 MalaStringListNode newnode2
;
539 newnode1
= mala_stringlist_after_new (list
,
541 self
->common_string
[MALA_STRING_LITERAL
]);
543 goto ealloc_newnode1
;
545 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
546 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
548 goto ealloc_newnode2
;
550 mala_stringlist_elem_delete (list
, *pptr
);
556 mala_stringlist_elem_delete (list
, newnode1
);
558 self
->state
= MALA_EALLOC
;
559 return MALA_EXPANSION_ERROR
;
561 return MALA_NO_EXPANSION
;
566 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
568 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
569 && mala_string_check_prefix ((*pptr
)->string
, "``"))
572 MalaStringListNode newnode
;
574 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
575 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
579 mala_stringlist_elem_delete (list
, *pptr
);
585 self
->state
= MALA_EALLOC
;
586 return MALA_EXPANSION_ERROR
;
588 return MALA_NO_EXPANSION
;
592 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
594 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
595 && mala_string_length ((*pptr
)->string
) > 2
596 && mala_string_at ((*pptr
)->string
, 0) == '-'
597 && isalpha (mala_string_at ((*pptr
)->string
, 1))
602 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
604 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
609 MalaStringListNode na
;
610 MalaStringListNode nb
;
612 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
613 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
617 na
= mala_stringlist_after_new (list
, *pptr
, a
);
621 nb
= mala_stringlist_after_new (list
, na
, b
);
625 mala_stringlist_elem_delete (list
, *pptr
);
628 mala_string_free (a
);
629 mala_string_free (b
);
634 mala_stringlist_elem_delete (list
, na
);
637 mala_string_free (a
);
638 mala_string_free (b
);
639 self
->state
= MALA_EALLOC
;
640 return MALA_EXPANSION_ERROR
;
644 return MALA_NO_EXPANSION
;
649 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
651 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
652 && mala_string_length ((*pptr
)->string
) == 1
653 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
655 MalaStringListNode newnode
;
657 newnode
= mala_stringlist_after_new (list
,
659 self
->common_string
[MALA_STRING_NOT
]);
661 return self
->state
= MALA_EALLOC
;
663 mala_stringlist_elem_delete (list
, *pptr
);
667 return MALA_NO_EXPANSION
;
672 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
674 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
675 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
676 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
680 MalaStringListNode n1
;
681 MalaStringListNode n2
;
683 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
684 aa
= mala_string_new_prefix ("--", a
);
688 n1
= mala_stringlist_after_new (list
,
689 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
693 n2
= mala_stringlist_after_new (list
, n1
, aa
);
697 mala_string_free (a
);
698 mala_string_free (aa
);
699 mala_stringlist_elem_delete (list
, *pptr
);
704 mala_stringlist_elem_delete (list
, n1
);
706 mala_string_free (a
);
707 mala_string_free (aa
);
709 self
->state
= MALA_EALLOC
;
710 return MALA_EXPANSION_ERROR
;
712 return MALA_NO_EXPANSION
;
717 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
721 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
722 && mala_string_check_prefix ((*pptr
)->string
, "--")
723 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
724 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
729 MalaStringListNode na
;
730 MalaStringListNode nb
;
732 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
733 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
737 na
= mala_stringlist_after_new (list
, *pptr
, a
);
741 nb
= mala_stringlist_after_new (list
, na
, b
);
745 mala_stringlist_elem_delete (list
, *pptr
);
748 mala_string_free (a
);
749 mala_string_free (b
);
755 mala_stringlist_elem_delete (list
, na
);
758 mala_string_free (a
);
759 mala_string_free (b
);
760 self
->state
= MALA_EALLOC
;
761 return MALA_EXPANSION_ERROR
;
763 return MALA_NO_EXPANSION
;
768 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
770 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
771 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
773 MalaStringListNode newnode
;
775 newnode
= mala_stringlist_before_new (list
,
777 self
->common_string
[MALA_STRING_ENVSUBST
]);
785 self
->state
= MALA_EALLOC
;
786 return MALA_EXPANSION_ERROR
;
789 return MALA_NO_EXPANSION
;
794 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
796 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
797 && mala_string_length ((*pptr
)->string
) > 2
798 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
799 || mala_string_at ((*pptr
)->string
, 0) == '+')
800 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
802 char prefix
[2] = "-";
803 char current
[2] = " ";
808 MalaStringListNode node
= NULL
;
809 MalaStringListNode pred
= *pptr
;
812 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
814 if (*i
== '-' || *i
== '+')
816 else if (isalpha (*i
))
820 str
= mala_string_new_cat2 (prefix
, current
,
821 mala_string_bucket_get ((*pptr
)->string
));
825 node
= mala_stringlist_after_new (list
,
831 mala_string_free (str
);
838 mala_stringlist_fwd (&pred
);
839 mala_stringlist_elem_delete (list
, *pptr
);
844 mala_string_free (str
);
845 /* cleanup from pred downto pptr */
846 while (pred
!= *pptr
)
848 // TODO use stringlist func
849 MalaStringListNode tmp
= pred
->node
.cqe_prev
;
850 mala_stringlist_elem_delete (list
, pred
);
853 self
->state
= MALA_EALLOC
;
854 return MALA_EXPANSION_ERROR
;
856 return MALA_NO_EXPANSION
;
861 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
863 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
864 && mala_string_check_prefix ((*pptr
)->string
, "--")
865 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
868 MalaStringListNode node
;
872 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
876 for (i
= cstr
+ 2; *i
; ++i
)
882 str
= mala_string_new (cstr
, &self
->words
);
886 node
= mala_stringlist_after_new (list
,
893 mala_string_free (str
);
895 mala_stringlist_elem_delete (list
, *pptr
);
900 mala_string_free (str
);
904 self
->state
= MALA_EALLOC
;
905 return MALA_EXPANSION_ERROR
;
907 return MALA_NO_EXPANSION
;
912 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
916 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
917 && mala_string_length ((*pptr
)->string
) > 1
918 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
921 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
925 MalaStringListNode n1
;
926 MalaStringListNode n2
;
927 MalaStringListNode n3
;
929 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
933 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
937 n1
= mala_stringlist_after_new (list
,
938 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
942 n2
= mala_stringlist_after_new (list
, n1
, key
);
946 n3
= mala_stringlist_after_new (list
, n2
, value
);
950 mala_string_free (key
);
951 mala_string_free (value
);
952 mala_stringlist_elem_delete (list
, *pptr
);
957 mala_stringlist_elem_delete (list
, n2
);
959 mala_stringlist_elem_delete (list
, n1
);
961 mala_string_free (value
);
963 mala_string_free (key
);
965 self
->state
= MALA_EALLOC
;
966 return MALA_EXPANSION_ERROR
;
968 return MALA_NO_EXPANSION
;
973 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
975 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
976 && mala_string_at ((*pptr
)->string
, 0) == '[')
978 MalaStringListNode nitr
;
979 MalaStringListNode node
;
981 MalaString str1
= NULL
;
982 MalaStringListNode node1
;
984 MalaString str2
= NULL
;
985 MalaStringListNode node2
;
987 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
991 if (mala_string_length((*pptr
)->string
) > 1)
993 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
994 node1
= mala_stringlist_after_new (list
, node
, str1
);
1001 mala_stringlist_fwd (&node1
);
1004 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlist_fwd (&nitr
))
1006 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1010 if ((void*)nitr
!= (void*)list
)
1012 if (mala_string_length(nitr
->string
) > 1)
1014 str2
= mala_string_new_substr (nitr
->string
, 0,
1015 mala_string_length(nitr
->string
) - 1);
1016 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1025 mala_string_free (str1
);
1026 mala_string_free (str2
);
1027 mala_stringlist_elem_delete (list
, *pptr
);
1028 mala_stringlist_elem_delete (list
, nitr
);
1034 mala_string_free (str1
);
1035 mala_stringlist_elem_delete (list
, node1
);
1036 mala_stringlist_elem_delete (list
, node
);
1037 self
->state
= MALA_ESYNTAX
;
1038 return MALA_EXPANSION_ERROR
;
1041 mala_string_free (str1
);
1042 mala_stringlist_elem_delete (list
, node1
);
1044 mala_stringlist_elem_delete (list
, node
);
1046 self
->state
= MALA_EALLOC
;
1047 return MALA_EXPANSION_ERROR
;
1049 return MALA_NO_EXPANSION
;
1054 mala_engine_assign_contraction (MalaEngine self
,
1055 MalaStringList list
,
1056 MalaStringListNode_ref pptr
)
1058 MalaStringListNode assign
;
1059 MalaStringListNode value
;
1062 mala_stringlist_fwd (&assign
);
1065 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1066 && !mala_stringlist_is_tail (list
, *pptr
)
1067 && !mala_stringlist_is_tail (list
, assign
)
1068 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1071 MalaStringListNode node
;
1073 mala_stringlist_fwd (&value
);
1075 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1077 mala_string_cstr ((*pptr
)->string
),
1078 mala_string_cstr (value
->string
));
1081 node
= mala_stringlist_after_new (list
,
1087 mala_string_free (str
);
1088 mala_stringlist_elem_delete (list
, *pptr
);
1089 mala_stringlist_elem_delete (list
, assign
);
1090 mala_stringlist_elem_delete (list
, value
);
1095 mala_string_free (str
);
1096 self
->state
= MALA_EALLOC
;
1097 return MALA_EXPANSION_ERROR
;
1099 return MALA_NO_EXPANSION
;
1106 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1109 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1110 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1117 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1119 MalaActionDesc desc
;
1120 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1124 /*only enabled when the topmost action is a subtitution to --TRUE*/
1125 if (desc
->actions
.lh_first
)
1126 return desc
->actions
.lh_first
->data
== self
->common_string
[MALA_STRING_TRUE
];
1145 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1149 if (self
->state
> MALA_EFAULT
)
1152 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1156 mala_actiondict_destroy_action (self
->actions
, act
);
1158 return MALA_SUCCESS
;
1161 self
->state
= MALA_ENOACTION
;
1168 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1170 MalaStringListNode base
= llist_get_prev (pptr
);
1171 while (mala_engine_eval (self
, llist_get_next (base
)) < MALA_EVAL
)
1172 if (llist_get_next (base
) == &self
->program
)
1173 return MALA_ENOACTION
;
1181 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1183 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1189 mala_engine_argc (MalaEngine self
)
1191 return llist_count (&self
->arguments
) + 1;
1195 mala_engine_argv (MalaEngine self
, int n
)
1197 MalaStringListNode p
;
1198 p
= llist_get_next (&self
->arguments
);
1201 return self
->argv_0
;
1205 if (p
== &self
->arguments
)
1207 p
= llist_get_next (p
);
1209 return (const char *)(p
)->data
;
1215 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1216 MalaParserFunc parser
, MalaDataDestructor destructor
)
1220 act
= mala_action_new (name
, data
, parser
, destructor
);
1224 self
->state
= mala_actiondict_push (self
->actions
, act
);
1231 mala_action_destroy (act
);
1237 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1241 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1243 return MALA_NO_EXPANSION
;
1245 if (act
->parser
!= mala_substitute_parser
)
1246 return MALA_EPARSER
;
1248 return mala_string_check ((t_uchar
*) act
->data
);
1253 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1255 return mala_actiondict_lookupaction (self
->actions
, name
);
1259 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1261 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1273 // c-file-style: "gnu"
1275 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100