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_ppexpand_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_ppexpand (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_stringlistnode_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_stringlistnode_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_step (MalaEngine self
)
402 MalaStringListNode pptr
;
404 if (self
->state
< MALA_EFAULT
&&
405 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
407 if (self
->state
== MALA_LITERAL
)
409 mala_stringlist_elem_remove (&self
->program
, pptr
);
410 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
411 self
->state
= MALA_SUCCESS
;
414 mala_engine_eval (self
, &pptr
);
420 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
425 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
429 act
= mala_actiondesc_top (desc
);
432 self
->state
= mala_action_execute (act
, pptr
, self
);
436 if (!(*pptr
= mala_stringlist_before_new (&self
->program
,
438 self
->common_string
[MALA_STRING_DEFAULT_PARSER
])))
439 return self
->state
= MALA_EALLOC
;
442 if (self
->state
== MALA_EXCEPTION
)
443 self
->state
= MALA_ENOACTION
;
449 Evaluate the nth argument until one of the following happens
450 - for at most 'times'
451 - until we reach the state of MALA_LITERAL (no further expansions are possible)
452 - an error/exception is flagged
453 - the type associated with the data of the current word equals to 'type'
456 mala_engine_arg_eval (MalaEngine self
,
457 MalaStringListNode_ref pptr
,
460 MalaDataFactory type
)
463 MalaStringListNode next
;
465 if (!self
|| self
->state
> MALA_EFAULT
)
469 nth
&& !mala_stringlist_is_tail (&self
->program
, next
);
470 mala_stringlistnode_fwd (&next
), --nth
);
475 self
->state
= MALA_SUCCESS
;
476 act
= mala_actiondesc_top ((MalaActionDesc
) mala_string_user_get (next
->string
));
477 while (self
->state
< MALA_EXCEPTION
479 && ((act
&& type
) ? (act
->factory
!= type
) : 1))
481 mala_engine_eval (self
, &next
);
482 if (mala_stringlist_is_end (&self
->program
, next
))
489 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
490 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
496 mala_engine_exception (MalaEngine self
,
497 MalaStringListNode_ref pptr
,
498 MalaStringListNode here
,
501 MalaStringListNode tmp
;
503 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
505 return self
->state
= MALA_EALLOC
;
507 if (!mala_stringlist_after_new (&self
->program
, here
,
508 self
->common_string
[MALA_STRING_HERE
]))
509 return self
->state
= MALA_EALLOC
;
513 /*TODO self-state needs to be preserved somehow?*/
514 return self
->state
= MALA_EXCEPTION
;
519 mala_engine_ppexpand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
523 if (self
->state
> MALA_EFAULT
)
524 return MALA_EXPANSION_ERROR
;
526 #define mala_run_expansion(name) \
527 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
529 mala_run_expansion (literal_expansion
);
530 mala_run_expansion (numsplit_expansion
);
531 mala_run_expansion (exclam_expansion
);
532 mala_run_expansion (no_expansion
);
533 mala_run_expansion (assign_expansion
);
534 mala_run_expansion (char_expansion
);
535 mala_run_expansion (underscore_expansion
);
536 mala_run_expansion (bracket_expansion
);
537 mala_run_expansion (assign_contraction
);
538 mala_run_expansion (envvar_expansion
);
539 mala_run_expansion (setenv_expansion
);
540 mala_run_expansion (backquote_expansion
);
541 #undef mala_run_expansion
547 mala_engine_literal_expansion (MalaEngine self
,
549 MalaStringListNode_ref pptr
)
551 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
552 && mala_string_check_prefix ((*pptr
)->string
, "`")
553 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
556 MalaStringListNode newnode1
;
557 MalaStringListNode newnode2
;
559 newnode1
= mala_stringlist_after_new (list
,
561 self
->common_string
[MALA_STRING_LITERAL
]);
563 goto ealloc_newnode1
;
565 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
566 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
568 goto ealloc_newnode2
;
570 mala_stringlist_elem_delete (list
, *pptr
);
576 mala_stringlist_elem_delete (list
, newnode1
);
578 self
->state
= MALA_EALLOC
;
579 return MALA_EXPANSION_ERROR
;
581 return MALA_NO_EXPANSION
;
586 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
588 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
589 && mala_string_check_prefix ((*pptr
)->string
, "``"))
592 MalaStringListNode newnode
;
594 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
595 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
599 mala_stringlist_elem_delete (list
, *pptr
);
605 self
->state
= MALA_EALLOC
;
606 return MALA_EXPANSION_ERROR
;
608 return MALA_NO_EXPANSION
;
612 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
614 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
615 && mala_string_length ((*pptr
)->string
) > 2
616 && mala_string_at ((*pptr
)->string
, 0) == '-'
617 && isalpha (mala_string_at ((*pptr
)->string
, 1))
622 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
624 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
629 MalaStringListNode na
;
630 MalaStringListNode nb
;
632 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
633 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
637 na
= mala_stringlist_after_new (list
, *pptr
, a
);
641 nb
= mala_stringlist_after_new (list
, na
, b
);
645 mala_stringlist_elem_delete (list
, *pptr
);
648 mala_string_free (a
);
649 mala_string_free (b
);
654 mala_stringlist_elem_delete (list
, na
);
657 mala_string_free (a
);
658 mala_string_free (b
);
659 self
->state
= MALA_EALLOC
;
660 return MALA_EXPANSION_ERROR
;
664 return MALA_NO_EXPANSION
;
669 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
671 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
672 && mala_string_length ((*pptr
)->string
) == 1
673 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
675 MalaStringListNode newnode
;
677 newnode
= mala_stringlist_after_new (list
,
679 self
->common_string
[MALA_STRING_NOT
]);
681 return self
->state
= MALA_EALLOC
;
683 mala_stringlist_elem_delete (list
, *pptr
);
687 return MALA_NO_EXPANSION
;
692 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
694 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
695 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
696 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
700 MalaStringListNode n1
;
701 MalaStringListNode n2
;
703 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
704 aa
= mala_string_new_prefix ("--", a
);
708 n1
= mala_stringlist_after_new (list
,
709 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
713 n2
= mala_stringlist_after_new (list
, n1
, aa
);
717 mala_string_free (a
);
718 mala_string_free (aa
);
719 mala_stringlist_elem_delete (list
, *pptr
);
724 mala_stringlist_elem_delete (list
, n1
);
726 mala_string_free (a
);
727 mala_string_free (aa
);
729 self
->state
= MALA_EALLOC
;
730 return MALA_EXPANSION_ERROR
;
732 return MALA_NO_EXPANSION
;
737 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
741 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
742 && mala_string_check_prefix ((*pptr
)->string
, "--")
743 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
744 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
749 MalaStringListNode na
;
750 MalaStringListNode nb
;
752 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
753 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
757 na
= mala_stringlist_after_new (list
, *pptr
, a
);
761 nb
= mala_stringlist_after_new (list
, na
, b
);
765 mala_stringlist_elem_delete (list
, *pptr
);
768 mala_string_free (a
);
769 mala_string_free (b
);
775 mala_stringlist_elem_delete (list
, na
);
778 mala_string_free (a
);
779 mala_string_free (b
);
780 self
->state
= MALA_EALLOC
;
781 return MALA_EXPANSION_ERROR
;
783 return MALA_NO_EXPANSION
;
788 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
790 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
791 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
793 MalaStringListNode newnode
;
795 newnode
= mala_stringlist_before_new (list
,
797 self
->common_string
[MALA_STRING_ENVSUBST
]);
805 self
->state
= MALA_EALLOC
;
806 return MALA_EXPANSION_ERROR
;
809 return MALA_NO_EXPANSION
;
814 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
816 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
817 && mala_string_length ((*pptr
)->string
) > 2
818 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
819 || mala_string_at ((*pptr
)->string
, 0) == '+')
820 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
822 char prefix
[2] = "-";
823 char current
[2] = " ";
828 MalaStringListNode node
= NULL
;
829 MalaStringListNode pred
= *pptr
;
832 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
834 if (*i
== '-' || *i
== '+')
836 else if (isalpha (*i
))
840 str
= mala_string_new_cat2 (prefix
, current
,
841 mala_string_bucket_get ((*pptr
)->string
));
845 node
= mala_stringlist_after_new (list
,
851 mala_string_free (str
);
858 mala_stringlistnode_fwd (&pred
);
859 mala_stringlist_elem_delete (list
, *pptr
);
864 mala_string_free (str
);
865 /* cleanup from pred downto pptr */
866 while (pred
!= *pptr
)
868 MalaStringListNode tmp
= mala_stringlistnode_prev (pred
);
869 mala_stringlist_elem_delete (list
, pred
);
872 self
->state
= MALA_EALLOC
;
873 return MALA_EXPANSION_ERROR
;
875 return MALA_NO_EXPANSION
;
880 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
882 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
883 && mala_string_check_prefix ((*pptr
)->string
, "--")
884 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
887 MalaStringListNode node
;
891 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
895 for (i
= cstr
+ 2; *i
; ++i
)
901 str
= mala_string_new (cstr
, &self
->words
);
905 node
= mala_stringlist_after_new (list
,
912 mala_string_free (str
);
914 mala_stringlist_elem_delete (list
, *pptr
);
919 mala_string_free (str
);
923 self
->state
= MALA_EALLOC
;
924 return MALA_EXPANSION_ERROR
;
926 return MALA_NO_EXPANSION
;
931 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
935 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
936 && mala_string_length ((*pptr
)->string
) > 1
937 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
940 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
944 MalaStringListNode n1
;
945 MalaStringListNode n2
;
946 MalaStringListNode n3
;
948 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
952 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
956 n1
= mala_stringlist_after_new (list
,
957 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
961 n2
= mala_stringlist_after_new (list
, n1
, key
);
965 n3
= mala_stringlist_after_new (list
, n2
, value
);
969 mala_string_free (key
);
970 mala_string_free (value
);
971 mala_stringlist_elem_delete (list
, *pptr
);
976 mala_stringlist_elem_delete (list
, n2
);
978 mala_stringlist_elem_delete (list
, n1
);
980 mala_string_free (value
);
982 mala_string_free (key
);
984 self
->state
= MALA_EALLOC
;
985 return MALA_EXPANSION_ERROR
;
987 return MALA_NO_EXPANSION
;
992 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
994 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
995 && mala_string_at ((*pptr
)->string
, 0) == '[')
997 MalaStringListNode nitr
;
998 MalaStringListNode node
;
1000 MalaString str1
= NULL
;
1001 MalaStringListNode node1
;
1003 MalaString str2
= NULL
;
1004 MalaStringListNode node2
;
1006 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
1010 if (mala_string_length((*pptr
)->string
) > 1)
1012 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
1013 node1
= mala_stringlist_after_new (list
, node
, str1
);
1020 mala_stringlistnode_fwd (&node1
);
1023 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlistnode_fwd (&nitr
))
1025 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1029 if ((void*)nitr
!= (void*)list
)
1031 if (mala_string_length(nitr
->string
) > 1)
1033 str2
= mala_string_new_substr (nitr
->string
, 0,
1034 mala_string_length(nitr
->string
) - 1);
1035 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1044 mala_string_free (str1
);
1045 mala_string_free (str2
);
1046 mala_stringlist_elem_delete (list
, *pptr
);
1047 mala_stringlist_elem_delete (list
, nitr
);
1053 mala_string_free (str1
);
1054 mala_stringlist_elem_delete (list
, node1
);
1055 mala_stringlist_elem_delete (list
, node
);
1056 self
->state
= MALA_ESYNTAX
;
1057 return MALA_EXPANSION_ERROR
;
1060 mala_string_free (str1
);
1061 mala_stringlist_elem_delete (list
, node1
);
1063 mala_stringlist_elem_delete (list
, node
);
1065 self
->state
= MALA_EALLOC
;
1066 return MALA_EXPANSION_ERROR
;
1068 return MALA_NO_EXPANSION
;
1073 mala_engine_assign_contraction (MalaEngine self
,
1074 MalaStringList list
,
1075 MalaStringListNode_ref pptr
)
1077 MalaStringListNode assign
;
1078 MalaStringListNode value
;
1081 mala_stringlistnode_fwd (&assign
);
1084 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1085 && !mala_stringlist_is_tail (list
, *pptr
)
1086 && !mala_stringlist_is_tail (list
, assign
)
1087 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1090 MalaStringListNode node
;
1092 mala_stringlistnode_fwd (&value
);
1094 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1096 mala_string_cstr ((*pptr
)->string
),
1097 mala_string_cstr (value
->string
));
1100 node
= mala_stringlist_after_new (list
,
1106 mala_string_free (str
);
1107 mala_stringlist_elem_delete (list
, *pptr
);
1108 mala_stringlist_elem_delete (list
, assign
);
1109 mala_stringlist_elem_delete (list
, value
);
1114 mala_string_free (str
);
1115 self
->state
= MALA_EALLOC
;
1116 return MALA_EXPANSION_ERROR
;
1118 return MALA_NO_EXPANSION
;
1125 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1128 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1129 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1136 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1138 MalaActionDesc desc
;
1139 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1141 /*only enabled when the topmost action is a subtitution to --TRUE*/
1142 return mala_actiondesc_data_top (desc
) == self
->common_string
[MALA_STRING_TRUE
];
1159 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1163 if (self
->state
> MALA_EFAULT
)
1166 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1170 mala_actiondict_destroy_action (self
->actions
, act
);
1172 return MALA_SUCCESS
;
1175 self
->state
= MALA_ENOACTION
;
1182 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1184 MalaStringListNode base
= llist_get_prev (pptr
);
1185 while (mala_engine_eval (self
, llist_get_nextt (base
)) < MALA_EVAL
)
1186 if (llist_get_next (base
) == &self
->program
)
1187 return MALA_ENOACTION
;
1195 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1197 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1203 mala_engine_argc (MalaEngine self
)
1205 return llist_count (&self
->arguments
) + 1;
1209 mala_engine_argv (MalaEngine self
, int n
)
1211 MalaStringListNode p
;
1212 p
= llist_get_next (&self
->arguments
);
1215 return self
->argv_0
;
1219 if (p
== &self
->arguments
)
1221 p
= llist_get_next (p
);
1223 return (const char *)(p
)->data
;
1229 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1230 MalaParserFunc parser
, MalaDataDestructor destructor
)
1234 act
= mala_action_new (name
, data
, parser
, destructor
);
1238 self
->state
= mala_actiondict_push (self
->actions
, act
);
1245 mala_action_destroy (act
);
1251 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1255 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1257 return MALA_NO_EXPANSION
;
1259 if (act
->parser
!= mala_substitute_parser
)
1260 return MALA_EPARSER
;
1262 return mala_string_check ((t_uchar
*) act
->data
);
1267 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1269 return mala_actiondict_lookupaction (self
->actions
, name
);
1273 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1275 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1287 // c-file-style: "gnu"
1289 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100