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
;
35 #define MALA_STATE(s) #s
36 const char * mala_engine_states
[] = {MALA_STATES
};
41 * function definitions
50 self
= malloc (sizeof(mala_engine
));
58 self
->state
= MALA_CONTINUE
;
60 mala_stringbucket_init (&self
->words
, MALA_STRING_FWD
, (void(*)(void*)) mala_actiondesc_free
);
62 for (i
= 0; i
< MALA_STRING_MAX
; ++i
)
64 self
->common_string
[i
] = mala_string_new (mala_common_strings
[i
], &self
->words
);
65 if (!self
->common_string
[i
])
69 mala_stringlist_init (&self
->program
);
70 mala_stringlist_init (&self
->arguments
);
76 mala_string_free (self
->common_string
[i
]);
83 mala_engine_new_main (int (*initfunc
) (MalaEngine
),
84 int argc
, char **argv
,
85 mala_actioninit
* actions_init
)
87 /*TODO convinience function*/
92 mala_engine_ppexpand_define (MalaEngine self
, const char * name
, int argc
, char ** argv
)
96 MalaStringListNode itr
;
99 if (mala_engine_state_get (self
) > MALA_EFAULT
)
100 return mala_engine_state_get (self
);
102 mala_stringlist_init (&pre
);
104 for (i
= 0; i
!= argc
&& *argv
; ++i
,++argv
)
106 if (!mala_stringlist_tail_new_cstr (&pre
, *argv
, &self
->words
))
110 list
= mala_stringlist_new ();
114 /*TODO preprocess in own function*/
115 while (!mala_stringlist_is_empty (&pre
))
119 itr
= mala_stringlist_head (&pre
);
121 putaway
= mala_engine_ppexpand (self
, &pre
, &itr
);
123 if (self
->state
> MALA_EFAULT
)
128 mala_stringlist_node_remove (&pre
, itr
);
129 mala_stringlist_tail_insert (list
, itr
);
130 if (putaway
&& mala_stringlist_is_empty (&pre
))
132 itr
= mala_stringlist_head (&pre
);
136 if (mala_stringlist_is_empty (list
))
138 mala_stringlist_free (list
);
139 return mala_engine_add_action_cstr (self
, name
,
140 mala_string_copy (self
->common_string
[MALA_STRING_PASS
]),
141 mala_substitute_parser
,
142 (MalaDataFactory
)mala_string_factory
,
146 if (mala_stringlist_is_tail (list
, mala_stringlist_head (list
)))
151 subst
= mala_string_copy (mala_stringlist_head (list
) -> string
);
152 mala_stringlist_free (list
);
154 return mala_engine_add_action_cstr (self
, name
, subst
,
155 mala_substitute_parser
,
156 (MalaDataFactory
)mala_string_factory
,
162 return mala_engine_add_action_cstr (self
, name
, list
,
164 (MalaDataFactory
) mala_stringlist_factory
,
169 mala_stringlist_free (list
);
170 mala_stringlist_erase (&pre
);
171 return self
->state
= MALA_ESYNTAX
;
175 mala_stringlist_erase (&pre
);
176 return self
->state
= MALA_EALLOC
;
180 mala_engine_pushback_word (MalaEngine self
, const char * word
)
182 if (mala_engine_state_get (self
) > MALA_EFAULT
)
183 return mala_engine_state_get (self
);
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 if (mala_engine_state_get (self
) > MALA_EFAULT
)
200 return mala_engine_state_get (self
);
202 name
= mala_string_new (cname
, &self
->words
);
206 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
210 if (mala_action_attach (action
) != MALA_SUCCESS
)
213 mala_string_free (name
);
217 mala_action_free (action
);
219 mala_string_free (name
);
221 return self
->state
= MALA_EALLOC
;
225 mala_engine_add_action (MalaEngine self
, MalaString name
, void * data
,
226 MalaParserFunc parser
, MalaDataFactory factory
,
231 if (mala_engine_state_get (self
) > MALA_EFAULT
)
232 return mala_engine_state_get (self
);
234 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
238 if (mala_action_attach (action
) != MALA_SUCCESS
)
244 mala_action_free (action
);
246 return self
->state
= MALA_EALLOC
;
251 mala_engine_new_initfunc (int (*initfunc
)(MalaEngine
))
255 self
= mala_engine_new ();
259 self
->state
= initfunc (self
);
264 mala_engine_free (MalaEngine self
)
271 mala_stringlist_erase (&self
->program
);
272 mala_stringlist_erase (&self
->arguments
);
274 mala_stringbucket_erase (&self
->words
);
276 for (i
= 0; i
< MALA_STRING_MAX
; ++i
)
277 mala_string_free (self
->common_string
[i
]);
283 mala_engine_actions_register (MalaEngine self
, mala_actioninit
* actioninit
)
287 if (mala_engine_state_get (self
) > MALA_EFAULT
)
288 return mala_engine_state_get (self
);
290 while (actioninit
->command
)
292 action
= mala_action_new_actioninit (actioninit
, &self
->words
);
296 if (mala_action_attach (action
) != MALA_SUCCESS
)
305 return self
->state
= MALA_EINIT
;
309 /*TODO make some inlines { */
312 mala_engine_getprogram (MalaEngine self
)
314 if (mala_engine_state_get (self
) > MALA_EFAULT
)
317 return &self
->program
;
321 mala_engine_state_get (MalaEngine self
)
323 return self
? self
->state
: MALA_EINVALID
;
327 mala_engine_state_str (MalaEngine self
)
329 return mala_engine_states
[self
? self
->state
: MALA_EINVALID
];
333 mala_engine_clearstate (MalaEngine self
)
336 self
->state
= MALA_SUCCESS
;
340 mala_engine_negated (MalaEngine self
)
342 return self
? self
->negated
: -1;
346 mala_engine_clear_negated (MalaEngine self
)
348 if (mala_engine_state_get (self
) > MALA_EFAULT
)
352 /* } TODO make some inlines */
356 mala_engine_dumpprogram (MalaEngine self
, FILE* stream
, const char * prefix
, const char * suffix
)
358 MalaStringListNode node
;
363 for (node
= mala_stringlist_head (&self
->program
);
364 node
!= (void *)&self
->program
;
365 mala_stringlistnode_fwd (&node
))
367 fprintf (stream
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
372 mala_engine_dumpargs (MalaEngine self
, FILE* stream
, const char * prefix
, const char * suffix
)
374 MalaStringListNode node
;
379 for (node
= mala_stringlist_head (&self
->arguments
);
380 node
!= (void *)&self
->arguments
;
381 mala_stringlistnode_fwd (&node
))
383 fprintf (stream
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
389 mala_engine_run (MalaEngine self
)
391 MalaStringListNode pptr
;
393 if (mala_engine_state_get (self
) > MALA_EFAULT
)
396 while (self
->state
< MALA_EFAULT
&&
397 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
399 if (self
->state
== MALA_LITERAL
)
401 self
->state
= mala_engine_string_istrue (self
,
402 mala_stringlistnode_string (pptr
))
405 mala_stringlist_elem_remove (&self
->program
, pptr
);
406 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
409 mala_engine_eval (self
, &pptr
);
415 mala_engine_step (MalaEngine self
)
417 MalaStringListNode pptr
;
419 pptr
= mala_stringlist_head (&self
->program
);
421 mala_engine_eval (self
, &pptr
);
423 while (pptr
->string
== self
->common_string
[MALA_STRING_PASS
])
424 mala_engine_eval (self
, &pptr
);
430 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
436 if (self
->trace
&& (*pptr
)->string
!= self
->common_string
[MALA_STRING_PASS
])
438 fprintf (stderr
, "%-8s: ", mala_engine_state_str (self
));
439 mala_engine_dumpprogram (self
, stderr
, "", " ");
440 fprintf (stderr
, "\n");
443 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
447 act
= mala_actiondesc_top (desc
);
451 state
= mala_action_execute (act
, pptr
, self
);
452 if (self
->state
!= MALA_REMOVE
)
458 if (self
->state
!= MALA_REMOVE
)
460 if (!(*pptr
= mala_stringlist_before_new (&self
->program
,
462 self
->common_string
[MALA_STRING_DEFAULT_PARSER
])))
463 return self
->state
= state
= MALA_EALLOC
;
466 mala_stringlistnode_substitute_string (*pptr
, self
->common_string
[MALA_STRING_DEFAULT_PARSER
]);
469 if (self
->state
== MALA_EXCEPTION
)
470 self
->state
= state
= MALA_ENOACTION
;
476 Evaluate the nth argument until one of the following happens
477 - for at most 'times' (-1 for full evaluation)
478 - until we reach a final state MALA_SUCCESS, MALA_FAILURE or MALA_LITERAL
479 - an error/exception is flagged
480 - the type associated with the data of the current word equals to 'type'
483 mala_engine_arg_eval (MalaEngine self
,
484 MalaStringListNode_ref pptr
,
487 MalaDataFactory type
)
490 MalaStringListNode next
;
492 if (mala_engine_state_get (self
) > MALA_EFAULT
)
496 nth
&& !mala_stringlist_is_tail (&self
->program
, next
);
497 mala_stringlistnode_fwd (&next
), --nth
);
502 if (self
->state
== MALA_REMOVE
)
504 act
= mala_actiondesc_top ((MalaActionDesc
) mala_string_user_get (next
->string
));
505 mala_engine_eval (self
, &next
);
509 self
->state
= MALA_CONTINUE
;
511 act
= mala_actiondesc_top ((MalaActionDesc
) mala_string_user_get (next
->string
));
512 while (self
->state
== MALA_CONTINUE
514 && ((act
&& type
) ? (act
->factory
!= type
) : 1))
516 mala_engine_eval (self
, &next
);
517 if (mala_stringlist_is_end (&self
->program
, next
))
525 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
526 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
531 mala_engine_arg_eval_fmt (MalaEngine self
,
532 MalaStringListNode_ref pptr
,
539 MalaStringListNode node
;
542 node
= mala_engine_arg_eval (self
, pptr
, nth
, -1, NULL
);
544 if (self
->state
!= MALA_EXCEPTION
)
546 r
= mala_string_scan (mala_stringlistnode_string (node
), fmt
, dest
);
548 r
= pred (dest
, constraint
);
550 return mala_engine_exception (self
, pptr
, node
,
551 self
->common_string
[MALA_STRING_ERROR_WRONG_TYPE
]);
558 mala_engine_arg_eval_string (MalaEngine self
,
559 MalaStringListNode_ref pptr
,
566 string
= mala_stringlistnode_string (mala_engine_arg_eval (self
, pptr
, nth
, -1, NULL
));
568 if (self
->state
>= MALA_EXCEPTION
|| ! (pred
? pred (string
, constraint
) : 1))
576 mala_engine_command_done (MalaEngine eng
, MalaStringListNode_ref pptr
, int args
)
578 mala_stringlistnode_substitute_string (*pptr
, eng
->common_string
[MALA_STRING_PASS
]);
581 mala_stringlist_elem_delete (&eng
->program
, mala_stringlistnode_next (*pptr
));
587 mala_engine_exception (MalaEngine self
,
588 MalaStringListNode_ref pptr
,
589 MalaStringListNode here
,
592 MalaStringListNode tmp
;
594 if (mala_engine_state_get (self
) > MALA_EFAULT
)
595 return mala_engine_state_get (self
);
597 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
599 return self
->state
= MALA_EALLOC
;
601 if (!mala_stringlist_after_new (&self
->program
, here
,
602 self
->common_string
[MALA_STRING_HERE
]))
603 return self
->state
= MALA_EALLOC
;
607 /*TODO self-state needs to be preserved somehow?*/
608 return self
->state
= MALA_EXCEPTION
;
613 mala_engine_ppexpand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
617 if (self
->state
> MALA_EFAULT
)
618 return MALA_EXPANSION_ERROR
;
620 #define mala_run_expansion(name) \
621 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
623 mala_run_expansion (literal_expansion
);
624 mala_run_expansion (numsplit_expansion
);
625 mala_run_expansion (exclam_expansion
);
626 mala_run_expansion (no_expansion
);
627 mala_run_expansion (assign_expansion
);
628 mala_run_expansion (char_expansion
);
629 mala_run_expansion (underscore_expansion
);
630 mala_run_expansion (bracket_expansion
);
631 mala_run_expansion (assign_contraction
);
632 mala_run_expansion (envvar_expansion
);
633 mala_run_expansion (setenv_expansion
);
634 mala_run_expansion (backquote_expansion
);
635 #undef mala_run_expansion
641 mala_engine_literal_expansion (MalaEngine self
,
643 MalaStringListNode_ref pptr
)
645 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
646 && mala_string_check_prefix ((*pptr
)->string
, "`")
647 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
650 MalaStringListNode newnode1
;
651 MalaStringListNode newnode2
;
653 newnode1
= mala_stringlist_after_new (list
,
655 self
->common_string
[MALA_STRING_LITERAL
]);
657 goto ealloc_newnode1
;
659 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
660 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
662 goto ealloc_newnode2
;
664 mala_stringlist_elem_delete (list
, *pptr
);
670 mala_stringlist_elem_delete (list
, newnode1
);
672 self
->state
= MALA_EALLOC
;
673 return MALA_EXPANSION_ERROR
;
675 return MALA_NO_EXPANSION
;
680 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
682 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
683 && mala_string_check_prefix ((*pptr
)->string
, "``"))
686 MalaStringListNode newnode
;
688 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
689 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
693 mala_stringlist_elem_delete (list
, *pptr
);
699 self
->state
= MALA_EALLOC
;
700 return MALA_EXPANSION_ERROR
;
702 return MALA_NO_EXPANSION
;
706 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
708 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
709 && mala_string_length ((*pptr
)->string
) > 2
710 && mala_string_at ((*pptr
)->string
, 0) == '-'
711 && isalpha (mala_string_at ((*pptr
)->string
, 1))
716 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
718 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
723 MalaStringListNode na
;
724 MalaStringListNode nb
;
726 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
727 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
731 na
= mala_stringlist_after_new (list
, *pptr
, a
);
735 nb
= mala_stringlist_after_new (list
, na
, b
);
739 mala_stringlist_elem_delete (list
, *pptr
);
742 mala_string_free (a
);
743 mala_string_free (b
);
748 mala_stringlist_elem_delete (list
, na
);
751 mala_string_free (a
);
752 mala_string_free (b
);
753 self
->state
= MALA_EALLOC
;
754 return MALA_EXPANSION_ERROR
;
758 return MALA_NO_EXPANSION
;
763 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
765 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
766 && mala_string_length ((*pptr
)->string
) == 1
767 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
769 MalaStringListNode newnode
;
771 newnode
= mala_stringlist_after_new (list
,
773 self
->common_string
[MALA_STRING_NOT
]);
775 return self
->state
= MALA_EALLOC
;
777 mala_stringlist_elem_delete (list
, *pptr
);
781 return MALA_NO_EXPANSION
;
786 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
788 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
789 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
790 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
794 MalaStringListNode n1
;
795 MalaStringListNode n2
;
797 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
798 aa
= mala_string_new_prefix ("--", a
);
802 n1
= mala_stringlist_after_new (list
,
803 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
807 n2
= mala_stringlist_after_new (list
, n1
, aa
);
811 mala_string_free (a
);
812 mala_string_free (aa
);
813 mala_stringlist_elem_delete (list
, *pptr
);
818 mala_stringlist_elem_delete (list
, n1
);
820 mala_string_free (a
);
821 mala_string_free (aa
);
823 self
->state
= MALA_EALLOC
;
824 return MALA_EXPANSION_ERROR
;
826 return MALA_NO_EXPANSION
;
831 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
835 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
836 && mala_string_check_prefix ((*pptr
)->string
, "--")
837 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
838 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
843 MalaStringListNode na
;
844 MalaStringListNode nb
;
846 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
847 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
851 na
= mala_stringlist_after_new (list
, *pptr
, a
);
855 nb
= mala_stringlist_after_new (list
, na
, b
);
859 mala_stringlist_elem_delete (list
, *pptr
);
862 mala_string_free (a
);
863 mala_string_free (b
);
869 mala_stringlist_elem_delete (list
, na
);
872 mala_string_free (a
);
873 mala_string_free (b
);
874 self
->state
= MALA_EALLOC
;
875 return MALA_EXPANSION_ERROR
;
877 return MALA_NO_EXPANSION
;
882 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
884 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
885 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
887 MalaStringListNode newnode
;
889 newnode
= mala_stringlist_before_new (list
,
891 self
->common_string
[MALA_STRING_ENVSUBST
]);
899 self
->state
= MALA_EALLOC
;
900 return MALA_EXPANSION_ERROR
;
903 return MALA_NO_EXPANSION
;
908 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
910 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
911 && mala_string_length ((*pptr
)->string
) > 2
912 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
913 || mala_string_at ((*pptr
)->string
, 0) == '+')
914 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
916 char prefix
[2] = "-";
917 char current
[2] = " ";
922 MalaStringListNode node
= NULL
;
923 MalaStringListNode pred
= *pptr
;
926 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
928 if (*i
== '-' || *i
== '+')
930 else if (isalpha (*i
))
934 str
= mala_string_new_cat2 (prefix
, current
,
935 mala_string_bucket_get ((*pptr
)->string
));
939 node
= mala_stringlist_after_new (list
,
945 mala_string_free (str
);
952 mala_stringlistnode_fwd (&pred
);
953 mala_stringlist_elem_delete (list
, *pptr
);
958 mala_string_free (str
);
959 /* cleanup from pred downto pptr */
960 while (pred
!= *pptr
)
962 MalaStringListNode tmp
= mala_stringlistnode_prev (pred
);
963 mala_stringlist_elem_delete (list
, pred
);
966 self
->state
= MALA_EALLOC
;
967 return MALA_EXPANSION_ERROR
;
969 return MALA_NO_EXPANSION
;
974 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
976 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
977 && mala_string_check_prefix ((*pptr
)->string
, "--")
978 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
981 MalaStringListNode node
;
985 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
989 for (i
= cstr
+ 2; *i
; ++i
)
995 str
= mala_string_new (cstr
, &self
->words
);
999 node
= mala_stringlist_after_new (list
,
1006 mala_string_free (str
);
1008 mala_stringlist_elem_delete (list
, *pptr
);
1013 mala_string_free (str
);
1017 self
->state
= MALA_EALLOC
;
1018 return MALA_EXPANSION_ERROR
;
1020 return MALA_NO_EXPANSION
;
1025 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
1029 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
1030 && mala_string_length ((*pptr
)->string
) > 1
1031 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
1034 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
1038 MalaStringListNode n1
;
1039 MalaStringListNode n2
;
1040 MalaStringListNode n3
;
1042 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
1046 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
1050 n1
= mala_stringlist_after_new (list
,
1051 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
1055 n2
= mala_stringlist_after_new (list
, n1
, key
);
1059 n3
= mala_stringlist_after_new (list
, n2
, value
);
1063 mala_string_free (key
);
1064 mala_string_free (value
);
1065 mala_stringlist_elem_delete (list
, *pptr
);
1070 mala_stringlist_elem_delete (list
, n2
);
1072 mala_stringlist_elem_delete (list
, n1
);
1074 mala_string_free (value
);
1076 mala_string_free (key
);
1078 self
->state
= MALA_EALLOC
;
1079 return MALA_EXPANSION_ERROR
;
1081 return MALA_NO_EXPANSION
;
1086 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
1088 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
1089 && mala_string_at ((*pptr
)->string
, 0) == '[')
1091 MalaStringListNode nitr
;
1092 MalaStringListNode node
;
1094 MalaString str1
= NULL
;
1095 MalaStringListNode node1
;
1097 MalaString str2
= NULL
;
1098 MalaStringListNode node2
;
1100 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
1104 if (mala_string_length((*pptr
)->string
) > 1)
1106 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
1107 node1
= mala_stringlist_after_new (list
, node
, str1
);
1114 mala_stringlistnode_fwd (&node1
);
1117 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlistnode_fwd (&nitr
))
1119 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1123 if ((void*)nitr
!= (void*)list
)
1125 if (mala_string_length(nitr
->string
) > 1)
1127 str2
= mala_string_new_substr (nitr
->string
, 0,
1128 mala_string_length(nitr
->string
) - 1);
1129 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1138 mala_string_free (str1
);
1139 mala_string_free (str2
);
1140 mala_stringlist_elem_delete (list
, *pptr
);
1141 mala_stringlist_elem_delete (list
, nitr
);
1147 mala_string_free (str1
);
1148 mala_stringlist_elem_delete (list
, node1
);
1149 mala_stringlist_elem_delete (list
, node
);
1150 self
->state
= MALA_ESYNTAX
;
1151 return MALA_EXPANSION_ERROR
;
1154 mala_string_free (str1
);
1155 mala_stringlist_elem_delete (list
, node1
);
1157 mala_stringlist_elem_delete (list
, node
);
1159 self
->state
= MALA_EALLOC
;
1160 return MALA_EXPANSION_ERROR
;
1162 return MALA_NO_EXPANSION
;
1167 mala_engine_assign_contraction (MalaEngine self
,
1168 MalaStringList list
,
1169 MalaStringListNode_ref pptr
)
1171 MalaStringListNode assign
;
1172 MalaStringListNode value
;
1175 mala_stringlistnode_fwd (&assign
);
1178 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1179 && !mala_stringlist_is_tail (list
, *pptr
)
1180 && !mala_stringlist_is_tail (list
, assign
)
1181 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1184 MalaStringListNode node
;
1186 mala_stringlistnode_fwd (&value
);
1188 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1190 mala_string_cstr ((*pptr
)->string
),
1191 mala_string_cstr (value
->string
));
1194 node
= mala_stringlist_after_new (list
,
1200 mala_string_free (str
);
1201 mala_stringlist_elem_delete (list
, *pptr
);
1202 mala_stringlist_elem_delete (list
, assign
);
1203 mala_stringlist_elem_delete (list
, value
);
1208 mala_string_free (str
);
1209 self
->state
= MALA_EALLOC
;
1210 return MALA_EXPANSION_ERROR
;
1212 return MALA_NO_EXPANSION
;
1219 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1221 /*TODO check for other zero representations 0.0 0e0 etc.*/
1223 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_EMPTY
])
1224 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1225 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1232 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1234 MalaActionDesc desc
;
1235 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1237 /*only enabled when the topmost action is a subtitution to --TRUE*/
1238 return mala_actiondesc_data_top (desc
) == self
->common_string
[MALA_STRING_TRUE
];
1255 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1259 if (self
->state
> MALA_EFAULT
)
1262 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1266 mala_actiondict_destroy_action (self
->actions
, act
);
1268 return MALA_SUCCESS
;
1271 self
->state
= MALA_ENOACTION
;
1278 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1280 MalaStringListNode base
= llist_get_prev (pptr
);
1281 while (mala_engine_eval (self
, llist_get_nextt (base
)) < MALA_EVAL
)
1282 if (llist_get_next (base
) == &self
->program
)
1283 return MALA_ENOACTION
;
1291 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1293 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1299 mala_engine_argc (MalaEngine self
)
1301 return llist_count (&self
->arguments
) + 1;
1305 mala_engine_argv (MalaEngine self
, int n
)
1307 MalaStringListNode p
;
1308 p
= llist_get_next (&self
->arguments
);
1311 return self
->argv_0
;
1315 if (p
== &self
->arguments
)
1317 p
= llist_get_next (p
);
1319 return (const char *)(p
)->data
;
1325 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1326 MalaParserFunc parser
, MalaDataDestructor destructor
)
1330 act
= mala_action_new (name
, data
, parser
, destructor
);
1334 self
->state
= mala_actiondict_push (self
->actions
, act
);
1341 mala_action_destroy (act
);
1347 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1351 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1353 return MALA_NO_EXPANSION
;
1355 if (act
->parser
!= mala_substitute_parser
)
1356 return MALA_EPARSER
;
1358 return mala_string_check ((t_uchar
*) act
->data
);
1363 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1365 return mala_actiondict_lookupaction (self
->actions
, name
);
1369 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1371 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1383 // c-file-style: "gnu"
1385 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100