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
;
94 if (mala_engine_state_get (self
) > MALA_EFAULT
)
95 return mala_engine_state_get (self
);
97 mala_stringlist_init (&pre
);
99 for (i
= 0; i
!= argc
&& *argv
; ++i
,++argv
)
101 if (!mala_stringlist_tail_new_cstr (&pre
, *argv
, &self
->words
))
105 list
= mala_stringlist_new ();
109 /*TODO preprocess in own function*/
110 while (!mala_stringlist_is_empty (&pre
))
114 itr
= mala_stringlist_head (&pre
);
116 putaway
= mala_engine_ppexpand (self
, &pre
, &itr
);
118 if (self
->state
> MALA_EFAULT
)
123 mala_stringlist_node_remove (&pre
, itr
);
124 mala_stringlist_tail_insert (list
, itr
);
125 if (putaway
&& mala_stringlist_is_empty (&pre
))
127 itr
= mala_stringlist_head (&pre
);
131 if (mala_stringlist_is_empty (list
))
133 /* empty substituted by --NULL, TODO use empty string instead? */
134 mala_stringlist_free (list
);
135 return mala_engine_add_action_cstr (self
, name
,
136 mala_string_copy (self
->common_string
[MALA_STRING_NULL
]),
137 mala_substitute_parser
,
138 (MalaDataFactory
)mala_string_factory
,
142 if (mala_stringlist_is_tail (list
, mala_stringlist_head (list
)))
147 subst
= mala_string_copy (mala_stringlist_head (list
) -> string
);
148 mala_stringlist_free (list
);
150 return mala_engine_add_action_cstr (self
, name
, subst
,
151 mala_substitute_parser
,
152 (MalaDataFactory
)mala_string_factory
,
158 return mala_engine_add_action_cstr (self
, name
, list
,
160 (MalaDataFactory
) mala_stringlist_factory
,
165 mala_stringlist_free (list
);
166 mala_stringlist_erase (&pre
);
167 return self
->state
= MALA_ESYNTAX
;
171 mala_stringlist_erase (&pre
);
172 return self
->state
= MALA_EALLOC
;
176 mala_engine_pushback_word (MalaEngine self
, const char * word
)
178 if (mala_engine_state_get (self
) > MALA_EFAULT
)
179 return mala_engine_state_get (self
);
181 if (!mala_stringlist_tail_new_cstr (&self
->program
, word
, &self
->words
))
182 return self
->state
= MALA_EALLOC
;
188 mala_engine_add_action_cstr (MalaEngine self
, const char * cname
, void * data
,
189 MalaParserFunc parser
, MalaDataFactory factory
,
195 if (mala_engine_state_get (self
) > MALA_EFAULT
)
196 return mala_engine_state_get (self
);
198 name
= mala_string_new (cname
, &self
->words
);
202 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
206 if (mala_action_attach (action
) != MALA_SUCCESS
)
209 mala_string_free (name
);
213 mala_action_free (action
);
215 mala_string_free (name
);
217 return self
->state
= MALA_EALLOC
;
221 mala_engine_add_action (MalaEngine self
, MalaString name
, void * data
,
222 MalaParserFunc parser
, MalaDataFactory factory
,
227 if (mala_engine_state_get (self
) > MALA_EFAULT
)
228 return mala_engine_state_get (self
);
230 action
= mala_action_new (name
, data
, parser
, factory
, parent
);
234 if (mala_action_attach (action
) != MALA_SUCCESS
)
240 mala_action_free (action
);
242 return self
->state
= MALA_EALLOC
;
247 mala_engine_new_initfunc (int (*initfunc
)(MalaEngine
))
251 self
= mala_engine_new ();
255 self
->state
= initfunc (self
);
260 mala_engine_free (MalaEngine self
)
267 mala_stringlist_erase (&self
->program
);
268 mala_stringlist_erase (&self
->arguments
);
270 mala_stringbucket_erase (&self
->words
);
272 for (i
= 0; i
< MALA_STRING_MAX
; ++i
)
273 mala_string_free (self
->common_string
[i
]);
279 mala_engine_actions_register (MalaEngine self
, mala_actioninit
* actioninit
)
283 if (mala_engine_state_get (self
) > MALA_EFAULT
)
284 return mala_engine_state_get (self
);
286 while (actioninit
->command
)
288 action
= mala_action_new_actioninit (actioninit
, &self
->words
);
292 if (mala_action_attach (action
) != MALA_SUCCESS
)
301 return self
->state
= MALA_EINIT
;
305 /*TODO make some inlines { */
308 mala_engine_getprogram (MalaEngine self
)
310 if (mala_engine_state_get (self
) > MALA_EFAULT
)
313 return &self
->program
;
317 mala_engine_state_get (MalaEngine self
)
319 return self
? self
->state
: MALA_EINVALID
;
323 mala_engine_clearstate (MalaEngine self
)
326 self
->state
= MALA_SUCCESS
;
330 mala_engine_negated (MalaEngine self
)
332 return self
? self
->negated
: -1;
336 mala_engine_clear_negated (MalaEngine self
)
338 if (mala_engine_state_get (self
) > MALA_EFAULT
)
342 /* } TODO make some inlines */
346 mala_engine_dumpprogram (MalaEngine self
, FILE* stream
, const char * prefix
, const char * suffix
)
348 MalaStringListNode node
;
353 for (node
= mala_stringlist_head (&self
->program
);
354 node
!= (void *)&self
->program
;
355 mala_stringlistnode_fwd (&node
))
357 fprintf (stream
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
362 mala_engine_dumpargs (MalaEngine self
, FILE* stream
, const char * prefix
, const char * suffix
)
364 MalaStringListNode node
;
369 for (node
= mala_stringlist_head (&self
->arguments
);
370 node
!= (void *)&self
->arguments
;
371 mala_stringlistnode_fwd (&node
))
373 fprintf (stream
, "%s%s%s", prefix
, mala_string_cstr (node
->string
), suffix
);
379 mala_engine_run (MalaEngine self
)
381 MalaStringListNode pptr
;
383 if (mala_engine_state_get (self
) > MALA_EFAULT
)
386 while (self
->state
< MALA_EFAULT
&&
387 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
389 if (self
->state
== MALA_LITERAL
)
391 mala_stringlist_elem_remove (&self
->program
, pptr
);
392 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
393 self
->state
= MALA_SUCCESS
;
396 mala_engine_eval (self
, &pptr
);
402 mala_engine_step (MalaEngine self
)
404 MalaStringListNode pptr
;
406 if (mala_engine_state_get (self
) > MALA_EFAULT
)
409 if (self
->state
< MALA_EFAULT
&&
410 (pptr
= mala_stringlist_head (&self
->program
)) != (void *)&self
->program
)
412 if (self
->state
== MALA_LITERAL
)
414 mala_stringlist_elem_remove (&self
->program
, pptr
);
415 mala_stringlist_tail_insert (&self
->arguments
, pptr
);
416 self
->state
= MALA_SUCCESS
;
419 mala_engine_eval (self
, &pptr
);
425 mala_engine_eval (MalaEngine self
, MalaStringListNode_ref pptr
)
430 desc
= (MalaActionDesc
) mala_string_user_get ((*pptr
)->string
);
434 act
= mala_actiondesc_top (desc
);
437 self
->state
= mala_action_execute (act
, pptr
, self
);
441 if (!(*pptr
= mala_stringlist_before_new (&self
->program
,
443 self
->common_string
[MALA_STRING_DEFAULT_PARSER
])))
444 return self
->state
= MALA_EALLOC
;
447 if (self
->state
== MALA_EXCEPTION
)
448 self
->state
= MALA_ENOACTION
;
454 Evaluate the nth argument until one of the following happens
455 - for at most 'times' (-1 for full evaluation)
456 - until we reach the state of MALA_LITERAL (no further expansions are possible)
457 - an error/exception is flagged
458 - the type associated with the data of the current word equals to 'type'
461 mala_engine_arg_eval (MalaEngine self
,
462 MalaStringListNode_ref pptr
,
465 MalaDataFactory type
)
468 MalaStringListNode next
;
470 if (mala_engine_state_get (self
) > MALA_EFAULT
)
474 nth
&& !mala_stringlist_is_tail (&self
->program
, next
);
475 mala_stringlistnode_fwd (&next
), --nth
);
480 self
->state
= MALA_SUCCESS
;
481 act
= mala_actiondesc_top ((MalaActionDesc
) mala_string_user_get (next
->string
));
482 while (self
->state
< MALA_LITERAL
484 && ((act
&& type
) ? (act
->factory
!= type
) : 1))
486 mala_engine_eval (self
, &next
);
487 if (mala_stringlist_is_end (&self
->program
, next
))
494 mala_engine_exception (self
, pptr
, mala_stringlist_tail (&self
->program
),
495 self
->common_string
[MALA_STRING_ERROR_MISSING_ARGUMENT
]);
500 mala_engine_arg_eval_fmt (MalaEngine self
,
501 MalaStringListNode_ref pptr
,
508 MalaStringListNode node
;
511 node
= mala_engine_arg_eval (self
, pptr
, nth
, -1, NULL
);
513 if (self
->state
!= MALA_EXCEPTION
)
515 r
= mala_string_scan (mala_stringlistnode_string (node
), fmt
, dest
);
517 r
= pred (dest
, constraint
);
519 return mala_engine_exception (self
, pptr
, node
,
520 self
->common_string
[MALA_STRING_ERROR_WRONG_TYPE
]);
527 mala_engine_arg_eval_string (MalaEngine self
,
528 MalaStringListNode_ref pptr
,
535 string
= mala_stringlistnode_string (mala_engine_arg_eval (self
, pptr
, nth
, -1, NULL
));
537 if (self
->state
>= MALA_EXCEPTION
|| ! (pred
? pred (string
, constraint
) : 1))
544 mala_engine_exception (MalaEngine self
,
545 MalaStringListNode_ref pptr
,
546 MalaStringListNode here
,
549 MalaStringListNode tmp
;
551 if (mala_engine_state_get (self
) > MALA_EFAULT
)
552 return mala_engine_state_get (self
);
554 tmp
= mala_stringlist_before_new (&self
->program
, *pptr
, except
);
556 return self
->state
= MALA_EALLOC
;
558 if (!mala_stringlist_after_new (&self
->program
, here
,
559 self
->common_string
[MALA_STRING_HERE
]))
560 return self
->state
= MALA_EALLOC
;
564 /*TODO self-state needs to be preserved somehow?*/
565 return self
->state
= MALA_EXCEPTION
;
570 mala_engine_ppexpand (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
574 if (self
->state
> MALA_EFAULT
)
575 return MALA_EXPANSION_ERROR
;
577 #define mala_run_expansion(name) \
578 if (MALA_NO_EXPANSION != (ret = mala_engine_##name (self, list, pptr))) return ret
580 mala_run_expansion (literal_expansion
);
581 mala_run_expansion (numsplit_expansion
);
582 mala_run_expansion (exclam_expansion
);
583 mala_run_expansion (no_expansion
);
584 mala_run_expansion (assign_expansion
);
585 mala_run_expansion (char_expansion
);
586 mala_run_expansion (underscore_expansion
);
587 mala_run_expansion (bracket_expansion
);
588 mala_run_expansion (assign_contraction
);
589 mala_run_expansion (envvar_expansion
);
590 mala_run_expansion (setenv_expansion
);
591 mala_run_expansion (backquote_expansion
);
592 #undef mala_run_expansion
598 mala_engine_literal_expansion (MalaEngine self
,
600 MalaStringListNode_ref pptr
)
602 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
603 && mala_string_check_prefix ((*pptr
)->string
, "`")
604 && !mala_string_check_prefix ((*pptr
)->string
, "``"))
607 MalaStringListNode newnode1
;
608 MalaStringListNode newnode2
;
610 newnode1
= mala_stringlist_after_new (list
,
612 self
->common_string
[MALA_STRING_LITERAL
]);
614 goto ealloc_newnode1
;
616 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
617 newnode2
= mala_stringlist_after_new (list
, newnode1
, nstr
);
619 goto ealloc_newnode2
;
621 mala_stringlist_elem_delete (list
, *pptr
);
627 mala_stringlist_elem_delete (list
, newnode1
);
629 self
->state
= MALA_EALLOC
;
630 return MALA_EXPANSION_ERROR
;
632 return MALA_NO_EXPANSION
;
637 mala_engine_backquote_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
639 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_LITERAL_EXPANSION
)
640 && mala_string_check_prefix ((*pptr
)->string
, "``"))
643 MalaStringListNode newnode
;
645 nstr
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
646 newnode
= mala_stringlist_after_new (list
, *pptr
, nstr
);
650 mala_stringlist_elem_delete (list
, *pptr
);
656 self
->state
= MALA_EALLOC
;
657 return MALA_EXPANSION_ERROR
;
659 return MALA_NO_EXPANSION
;
663 mala_engine_numsplit_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
665 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NUMSPLIT_EXPANSION
)
666 && mala_string_length ((*pptr
)->string
) > 2
667 && mala_string_at ((*pptr
)->string
, 0) == '-'
668 && isalpha (mala_string_at ((*pptr
)->string
, 1))
673 for (i
= 2; i
< mala_string_length ((*pptr
)->string
); ++i
)
675 if (isdigit (mala_string_at ((*pptr
)->string
, i
)))
680 MalaStringListNode na
;
681 MalaStringListNode nb
;
683 a
= mala_string_new_substr ((*pptr
)->string
, 0, i
);
684 b
= mala_string_new_substr ((*pptr
)->string
, i
, SIZE_MAX
);
688 na
= mala_stringlist_after_new (list
, *pptr
, a
);
692 nb
= mala_stringlist_after_new (list
, na
, b
);
696 mala_stringlist_elem_delete (list
, *pptr
);
699 mala_string_free (a
);
700 mala_string_free (b
);
705 mala_stringlist_elem_delete (list
, na
);
708 mala_string_free (a
);
709 mala_string_free (b
);
710 self
->state
= MALA_EALLOC
;
711 return MALA_EXPANSION_ERROR
;
715 return MALA_NO_EXPANSION
;
720 mala_engine_exclam_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
722 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_EXCLAM_EXPANSION
)
723 && mala_string_length ((*pptr
)->string
) == 1
724 && mala_string_same ((*pptr
)->string
, self
->common_string
[MALA_STRING_EXCLAMATIONMARK
]))
726 MalaStringListNode newnode
;
728 newnode
= mala_stringlist_after_new (list
,
730 self
->common_string
[MALA_STRING_NOT
]);
732 return self
->state
= MALA_EALLOC
;
734 mala_stringlist_elem_delete (list
, *pptr
);
738 return MALA_NO_EXPANSION
;
743 mala_engine_no_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
745 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_NO_EXPANSION
)
746 && mala_string_check_prefix_nocase ((*pptr
)->string
, "--NO-")
747 && mala_string_length ((*pptr
)->string
) >= sizeof ("--NO-"))
751 MalaStringListNode n1
;
752 MalaStringListNode n2
;
754 a
= mala_string_new_substr ((*pptr
)->string
, sizeof ("--NO-")-1, SIZE_MAX
);
755 aa
= mala_string_new_prefix ("--", a
);
759 n1
= mala_stringlist_after_new (list
,
760 *pptr
, self
->common_string
[MALA_STRING_NOT
]);
764 n2
= mala_stringlist_after_new (list
, n1
, aa
);
768 mala_string_free (a
);
769 mala_string_free (aa
);
770 mala_stringlist_elem_delete (list
, *pptr
);
775 mala_stringlist_elem_delete (list
, n1
);
777 mala_string_free (a
);
778 mala_string_free (aa
);
780 self
->state
= MALA_EALLOC
;
781 return MALA_EXPANSION_ERROR
;
783 return MALA_NO_EXPANSION
;
788 mala_engine_assign_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
792 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_EXPANSION
)
793 && mala_string_check_prefix ((*pptr
)->string
, "--")
794 && ((eq
= mala_string_char_find ((*pptr
)->string
, '=')) != SIZE_MAX
)
795 && mala_string_length ((*pptr
)->string
) > eq
+ 1)
800 MalaStringListNode na
;
801 MalaStringListNode nb
;
803 a
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
804 b
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
808 na
= mala_stringlist_after_new (list
, *pptr
, a
);
812 nb
= mala_stringlist_after_new (list
, na
, b
);
816 mala_stringlist_elem_delete (list
, *pptr
);
819 mala_string_free (a
);
820 mala_string_free (b
);
826 mala_stringlist_elem_delete (list
, na
);
829 mala_string_free (a
);
830 mala_string_free (b
);
831 self
->state
= MALA_EALLOC
;
832 return MALA_EXPANSION_ERROR
;
834 return MALA_NO_EXPANSION
;
839 mala_engine_envvar_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
841 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ENVVAR_EXPANSION
)
842 && (mala_string_char_find ((*pptr
)->string
, '$') != SIZE_MAX
))
844 MalaStringListNode newnode
;
846 newnode
= mala_stringlist_before_new (list
,
848 self
->common_string
[MALA_STRING_ENVSUBST
]);
856 self
->state
= MALA_EALLOC
;
857 return MALA_EXPANSION_ERROR
;
860 return MALA_NO_EXPANSION
;
865 mala_engine_char_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
867 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_CHAR_EXPANSION
)
868 && mala_string_length ((*pptr
)->string
) > 2
869 && ( mala_string_at ((*pptr
)->string
, 0) == '-'
870 || mala_string_at ((*pptr
)->string
, 0) == '+')
871 && isalpha (mala_string_at ((*pptr
)->string
, 1)))
873 char prefix
[2] = "-";
874 char current
[2] = " ";
879 MalaStringListNode node
= NULL
;
880 MalaStringListNode pred
= *pptr
;
883 for (i
= mala_string_cstr ((*pptr
)->string
); *i
; ++i
)
885 if (*i
== '-' || *i
== '+')
887 else if (isalpha (*i
))
891 str
= mala_string_new_cat2 (prefix
, current
,
892 mala_string_bucket_get ((*pptr
)->string
));
896 node
= mala_stringlist_after_new (list
,
902 mala_string_free (str
);
909 mala_stringlistnode_fwd (&pred
);
910 mala_stringlist_elem_delete (list
, *pptr
);
915 mala_string_free (str
);
916 /* cleanup from pred downto pptr */
917 while (pred
!= *pptr
)
919 MalaStringListNode tmp
= mala_stringlistnode_prev (pred
);
920 mala_stringlist_elem_delete (list
, pred
);
923 self
->state
= MALA_EALLOC
;
924 return MALA_EXPANSION_ERROR
;
926 return MALA_NO_EXPANSION
;
931 mala_engine_underscore_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
933 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_UNDERSCORE_EXPANSION
)
934 && mala_string_check_prefix ((*pptr
)->string
, "--")
935 && strchr (mala_string_cstr ((*pptr
)->string
), '_'))
938 MalaStringListNode node
;
942 cstr
= strdup (mala_string_cstr ((*pptr
)->string
));
946 for (i
= cstr
+ 2; *i
; ++i
)
952 str
= mala_string_new (cstr
, &self
->words
);
956 node
= mala_stringlist_after_new (list
,
963 mala_string_free (str
);
965 mala_stringlist_elem_delete (list
, *pptr
);
970 mala_string_free (str
);
974 self
->state
= MALA_EALLOC
;
975 return MALA_EXPANSION_ERROR
;
977 return MALA_NO_EXPANSION
;
982 mala_engine_setenv_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
986 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_SETENV_EXPANSION
)
987 && mala_string_length ((*pptr
)->string
) > 1
988 && (eq
= mala_string_char_find ((*pptr
)->string
, '='))
991 && !mala_string_check_prefix ((*pptr
)->string
, "-"))
995 MalaStringListNode n1
;
996 MalaStringListNode n2
;
997 MalaStringListNode n3
;
999 key
= mala_string_new_substr ((*pptr
)->string
, 0, eq
);
1003 value
= mala_string_new_substr ((*pptr
)->string
, eq
+ 1, SIZE_MAX
);
1007 n1
= mala_stringlist_after_new (list
,
1008 *pptr
, self
->common_string
[MALA_STRING_SETENV
]);
1012 n2
= mala_stringlist_after_new (list
, n1
, key
);
1016 n3
= mala_stringlist_after_new (list
, n2
, value
);
1020 mala_string_free (key
);
1021 mala_string_free (value
);
1022 mala_stringlist_elem_delete (list
, *pptr
);
1027 mala_stringlist_elem_delete (list
, n2
);
1029 mala_stringlist_elem_delete (list
, n1
);
1031 mala_string_free (value
);
1033 mala_string_free (key
);
1035 self
->state
= MALA_EALLOC
;
1036 return MALA_EXPANSION_ERROR
;
1038 return MALA_NO_EXPANSION
;
1043 mala_engine_bracket_expansion (MalaEngine self
, MalaStringList list
, MalaStringListNode_ref pptr
)
1045 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_BRACKET_EXPANSION
)
1046 && mala_string_at ((*pptr
)->string
, 0) == '[')
1048 MalaStringListNode nitr
;
1049 MalaStringListNode node
;
1051 MalaString str1
= NULL
;
1052 MalaStringListNode node1
;
1054 MalaString str2
= NULL
;
1055 MalaStringListNode node2
;
1057 node
= mala_stringlist_after_new (list
, *pptr
, self
->common_string
[MALA_STRING_SECTION
]);
1061 if (mala_string_length((*pptr
)->string
) > 1)
1063 str1
= mala_string_new_substr ((*pptr
)->string
, 1, SIZE_MAX
);
1064 node1
= mala_stringlist_after_new (list
, node
, str1
);
1071 mala_stringlistnode_fwd (&node1
);
1074 for (nitr
= node1
; (void*)nitr
!= (void*)list
; mala_stringlistnode_fwd (&nitr
))
1076 if (mala_string_at (nitr
->string
, mala_string_length(nitr
->string
) - 1) == ']')
1080 if ((void*)nitr
!= (void*)list
)
1082 if (mala_string_length(nitr
->string
) > 1)
1084 str2
= mala_string_new_substr (nitr
->string
, 0,
1085 mala_string_length(nitr
->string
) - 1);
1086 node2
= mala_stringlist_after_new (list
, nitr
, str2
);
1095 mala_string_free (str1
);
1096 mala_string_free (str2
);
1097 mala_stringlist_elem_delete (list
, *pptr
);
1098 mala_stringlist_elem_delete (list
, nitr
);
1104 mala_string_free (str1
);
1105 mala_stringlist_elem_delete (list
, node1
);
1106 mala_stringlist_elem_delete (list
, node
);
1107 self
->state
= MALA_ESYNTAX
;
1108 return MALA_EXPANSION_ERROR
;
1111 mala_string_free (str1
);
1112 mala_stringlist_elem_delete (list
, node1
);
1114 mala_stringlist_elem_delete (list
, node
);
1116 self
->state
= MALA_EALLOC
;
1117 return MALA_EXPANSION_ERROR
;
1119 return MALA_NO_EXPANSION
;
1124 mala_engine_assign_contraction (MalaEngine self
,
1125 MalaStringList list
,
1126 MalaStringListNode_ref pptr
)
1128 MalaStringListNode assign
;
1129 MalaStringListNode value
;
1132 mala_stringlistnode_fwd (&assign
);
1135 if (mala_engine_check_expansionflag (self
, MALA_STRING_FLAG_ASSIGN_CONTRACTION
)
1136 && !mala_stringlist_is_tail (list
, *pptr
)
1137 && !mala_stringlist_is_tail (list
, assign
)
1138 && mala_string_same (assign
->string
, self
->common_string
[MALA_STRING_ASSIGN
]))
1141 MalaStringListNode node
;
1143 mala_stringlistnode_fwd (&value
);
1145 str
= mala_string_new_print (mala_string_bucket_get ((*pptr
)->string
),
1147 mala_string_cstr ((*pptr
)->string
),
1148 mala_string_cstr (value
->string
));
1151 node
= mala_stringlist_after_new (list
,
1157 mala_string_free (str
);
1158 mala_stringlist_elem_delete (list
, *pptr
);
1159 mala_stringlist_elem_delete (list
, assign
);
1160 mala_stringlist_elem_delete (list
, value
);
1165 mala_string_free (str
);
1166 self
->state
= MALA_EALLOC
;
1167 return MALA_EXPANSION_ERROR
;
1169 return MALA_NO_EXPANSION
;
1176 mala_engine_string_istrue (MalaEngine self
, MalaString str
)
1179 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_FALSE
])
1180 || !mala_string_compare (str
, self
->common_string
[MALA_STRING_ZERO
]))
1187 mala_engine_check_expansionflag (MalaEngine self
, int flag
)
1189 MalaActionDesc desc
;
1190 desc
= (MalaActionDesc
) mala_string_user_get (self
->common_string
[flag
]);
1192 /*only enabled when the topmost action is a subtitution to --TRUE*/
1193 return mala_actiondesc_data_top (desc
) == self
->common_string
[MALA_STRING_TRUE
];
1210 mala_engine_erase_action (MalaEngine self
, const t_uchar
* key
)
1214 if (self
->state
> MALA_EFAULT
)
1217 act
= mala_actiondict_lookupaction (self
->actions
, key
);
1221 mala_actiondict_destroy_action (self
->actions
, act
);
1223 return MALA_SUCCESS
;
1226 self
->state
= MALA_ENOACTION
;
1233 mala_engine_deepeval (MalaEngine self
, MalaStringListNode_ref pptr
)
1235 MalaStringListNode base
= llist_get_prev (pptr
);
1236 while (mala_engine_eval (self
, llist_get_nextt (base
)) < MALA_EVAL
)
1237 if (llist_get_next (base
) == &self
->program
)
1238 return MALA_ENOACTION
;
1246 mala_engine_pusfront_program (MalaEngine self
, int argc
, char ** argv
)
1248 self
->state
= mala_strlist_pushfront_cstrings (&self
->program
, argc
, argv
);
1254 mala_engine_argc (MalaEngine self
)
1256 return llist_count (&self
->arguments
) + 1;
1260 mala_engine_argv (MalaEngine self
, int n
)
1262 MalaStringListNode p
;
1263 p
= llist_get_next (&self
->arguments
);
1266 return self
->argv_0
;
1270 if (p
== &self
->arguments
)
1272 p
= llist_get_next (p
);
1274 return (const char *)(p
)->data
;
1280 mala_engine_action_new (MalaEngine self
, t_uchar
** name
, void** data
,
1281 MalaParserFunc parser
, MalaDataDestructor destructor
)
1285 act
= mala_action_new (name
, data
, parser
, destructor
);
1289 self
->state
= mala_actiondict_push (self
->actions
, act
);
1296 mala_action_destroy (act
);
1302 mala_engine_check_expansionflag (MalaEngine self
, const t_uchar
* name
)
1306 act
= mala_actiondict_lookupaction (self
->actions
, name
);
1308 return MALA_NO_EXPANSION
;
1310 if (act
->parser
!= mala_substitute_parser
)
1311 return MALA_EPARSER
;
1313 return mala_string_check ((t_uchar
*) act
->data
);
1318 mala_engine_getaction (MalaEngine self
, const t_uchar
* name
)
1320 return mala_actiondict_lookupaction (self
->actions
, name
);
1324 mala_engine_getprevaction (MalaEngine self
, const t_uchar
* name
)
1326 return mala_actiondict_lookupprevaction (self
->actions
, name
);
1338 // c-file-style: "gnu"
1340 // arch-tag: ece5489f-f703-4033-8cbc-efc1b0562100