22#define CONFIG_H
33
44#define META_VERSION "0.9.0"
5- #define META_REVISION "46c0c49 "
5+ #define META_REVISION "33edf4c "
66
77#endif
88#define _AMALGAMATE_
@@ -463,6 +463,9 @@ int map_iter_next(struct map_iter*);
463463#include <sys/types.h>
464464#endif
465465
466+ #define Q_XSTR (s ) Q_STR(s)
467+ #define Q_STR (s ) #s
468+
466469static inline bool utils_char_is_space (char c ) {
467470 return c == 32 || (c >= 9 && c <= 13 );
468471}
@@ -1007,14 +1010,13 @@ void autark_build_prepare(const char *script_path);
10071010#define NODE_FLG_BOUND 0x01U
10081011#define NODE_FLG_INIT 0x02U
10091012#define NODE_FLG_SETUP 0x04U
1010- #define NODE_FLG_UPDATED 0x08U // Node product updated as result of build
1013+ // Vacant: 0x08U
10111014#define NODE_FLG_BUILT 0x10U // Node built
10121015#define NODE_FLG_POST_BUILT 0x20U // Node post-built
10131016#define NODE_FLG_IN_CACHE 0x40U
10141017#define NODE_FLG_IN_SRC 0x80U
10151018#define NODE_FLG_NO_CWD 0x100U
10161019#define NODE_FLG_NEGATE 0x200U
1017- #define NODE_FLG_CALLED 0x400U
10181020
10191021#define NODE_FLG_IN_ANY (NODE_FLG_IN_SRC | NODE_FLG_IN_CACHE | NODE_FLG_NO_CWD)
10201022
@@ -1172,6 +1174,10 @@ void node_warn(struct node *n, const char *fmt, ...);
11721174int node_error (int rc , struct node * n , const char * fmt , ...);
11731175
11741176
1177+ struct node * node_clone_and_register (struct node * );
1178+
1179+ int node_bind (struct node * );
1180+
11751181#endif
11761182#ifndef _AMALGAMATE_
11771183#include "xstr.h"
@@ -6464,66 +6470,148 @@ int node_find_setup(struct node *n) {
64646470}
64656471#ifndef _AMALGAMATE_
64666472#include "script.h"
6467- #include "alloc.h"
6473+ #endif
6474+
6475+ static void _macro_remove (struct node * n ) {
6476+ struct node * prev = node_find_prev_sibling (n );
6477+ if (prev ) {
6478+ prev -> next = n -> next ;
6479+ } else {
6480+ n -> parent -> child = n -> next ;
6481+ }
6482+ }
6483+
6484+ static void _macro_init (struct node * n ) {
6485+ struct unit * unit = unit_peek ();
6486+ const char * key = node_value (n -> child );
6487+ if (!key ) {
6488+ node_warn (n , "No name specified for 'macro' directive" );
6489+ return ;
6490+ }
6491+ _macro_remove (n );
6492+ unit_env_set_node (unit , key , n );
6493+ }
6494+
6495+ int node_macro_setup (struct node * n ) {
6496+ n -> flags |= NODE_FLG_NO_CWD ;
6497+ n -> init = _macro_init ;
6498+ return 0 ;
6499+ }
6500+ #ifndef _AMALGAMATE_
6501+ #include "script.h"
64686502#include "utils.h"
6503+ #include "alloc.h"
6504+ #include "ulist.h"
64696505#endif
64706506
64716507#define MACRO_MAX_ARGS_NUM 64
64726508
6473- struct _macro {
6474- struct node * args [MACRO_MAX_ARGS_NUM ];
6509+ struct _call {
6510+ const char * key ; ///< Macro name
6511+ struct node * n ; ///< Call Parent node
6512+ struct node * mn ; ///< Macro node
6513+ struct node * prev ; ///< Call Prev node
6514+ struct node * cloned ; ///< Macro cloned node
6515+ struct ulist nodes ; ///< Nodes stack. struct node*
6516+ struct node * args [MACRO_MAX_ARGS_NUM ];
64756517};
64766518
6477- static int _macro_args_visitor (struct node * n , int lvl , void * ctx ) {
6478- if (lvl < 0 ) {
6519+ static int _call_macro_visit (struct node * n , int lvl , void * d ) {
6520+ struct _call * call = d ;
6521+
6522+ if (call -> mn == n /*skip macro itself */ || call -> mn -> child == n /* skip macro name */ ) {
64796523 return 0 ;
64806524 }
6481- struct _macro * m = n -> impl ;
6482- if (!(n -> value [0 ] == '&' && n -> value [1 ] == '\0' && n -> child )) {
6525+
6526+ if (lvl < 0 ) {
6527+ ulist_pop (& call -> nodes );
64836528 return 0 ;
64846529 }
6485- int rc = 0 ;
6486- int idx = utils_strtol (n -> child -> value , 10 , & rc );
6487- if (rc || idx < 1 || idx > MACRO_MAX_ARGS_NUM ) {
6488- node_fatal (0 , n , "Invalid macro argument index" );
6489- return 0 ;
6530+
6531+ // Macro arg
6532+ if (n -> value [0 ] == '&' && n -> value [0 ] == '\0' && n -> child && !n -> child -> next ) {
6533+ int rc = 0 ;
6534+ int idx = utils_strtol (n -> child -> value , 10 , & rc );
6535+ if (rc || idx < 1 || idx >= MACRO_MAX_ARGS_NUM ) {
6536+ node_fatal (rc , n , "Invalid macro arg index: %d" , idx );
6537+ return 0 ;
6538+ }
6539+ idx -- ;
6540+ n = call -> args [idx ];
6541+ if (!n ) {
6542+ node_fatal (rc , call -> n , "Call argument: %d for macro: %s is not set" , (idx + 1 ), call -> key );
6543+ return 0 ;
6544+ }
64906545 }
6491- idx -- ;
6492- m -> args [idx ] = n ;
6493- return 0 ;
6494- }
64956546
6496- static void _macro_args_init (struct node * n ) {
6497- akcheck (node_visit (n , 1 , 0 , _macro_args_visitor ));
6547+ struct node * parent = * (struct node * * ) ulist_peek (& call -> nodes );
6548+ struct node * nn = node_clone_and_register (n );
6549+ nn -> parent = parent ;
6550+
6551+ // Add node to the parent
6552+ if (!parent -> child ) {
6553+ parent -> child = nn ;
6554+ } else {
6555+ struct node * c = parent -> child ;
6556+ while (c && c -> next ) {
6557+ c = c -> next ;
6558+ }
6559+ c -> next = nn ;
6560+ }
6561+
6562+ node_bind (nn );
6563+ ulist_push (& call -> nodes , & nn );
6564+ return 0 ;
64986565}
64996566
6500- static void _macro_init (struct node * n ) {
6567+ static void _call_init (struct node * n ) {
65016568 struct unit * unit = unit_peek ();
65026569 const char * key = node_value (n -> child );
65036570 if (!key ) {
6504- node_warn (n , "No name specified for 'macro ' directive" );
6571+ node_warn (n , "No name specified for 'call ' directive" );
65056572 return ;
65066573 }
6507- struct _macro * m = xcalloc (1 , sizeof (* m ));
6508- _macro_args_init (n );
6509- unit_env_set_node (unit , key , n );
6510- }
6574+ struct node * mn = unit_env_get_node (unit , key );
6575+ if (!mn ) {
6576+ node_fatal (0 , n , "Unknown script macro: %s" , key );
6577+ return ;
6578+ }
6579+ struct _call * call = xcalloc (1 , sizeof (* call ));
6580+ call -> key = key ;
6581+ call -> mn = mn ;
6582+ call -> n = n ;
6583+ call -> prev = node_find_prev_sibling (n );
6584+ ulist_init (& call -> nodes , 32 , sizeof (struct node * ));
6585+ n -> impl = call ;
6586+
6587+ int idx = 0 ;
6588+ for (struct node * pn = n -> child -> next ; pn ; pn = pn -> next ) {
6589+ if (idx >= MACRO_MAX_ARGS_NUM ) {
6590+ node_fatal (0 , n , "Exceeded the maximum number of macro args: " Q_STR (MACRO_MAX_ARGS_NUM ));
6591+ return ;
6592+ }
6593+ call -> args [idx ++ ] = pn ;
6594+ }
65116595
6512- static void _macro_dispose (struct node * n ) {
6513- struct _macro * m = n -> impl ;
6514- free (m );
6596+ ulist_push (& call -> nodes , & n -> parent );
6597+ int rc = node_visit (mn , 1 , call , _call_macro_visit );
6598+ if (rc ) {
6599+ node_fatal (rc , n , 0 );
6600+ }
65156601}
65166602
6517- int node_macro_setup (struct node * n ) {
6518- n -> flags |= NODE_FLG_NO_CWD ;
6519- n -> init = _macro_init ;
6520- return 0 ;
6603+ static void _call_dispose (struct node * n ) {
6604+ struct _call * call = n -> impl ;
6605+ if (call ) {
6606+ ulist_destroy_keep (& call -> nodes );
6607+ free (call );
6608+ }
65216609}
6522- #ifndef _AMALGAMATE_
6523- #include "script.h"
6524- #endif
65256610
65266611int node_call_setup (struct node * n ) {
6612+ n -> flags |= NODE_FLG_NO_CWD ;
6613+ n -> init = _call_init ;
6614+ n -> dispose = _call_dispose ;
65276615 return 0 ;
65286616}
65296617#ifndef _AMALGAMATE_
@@ -8315,6 +8403,30 @@ static struct xnode* _node_text_push(struct _yycontext *yy, const char *text) {
83158403 return _push_and_register (yy , _node_text (yy , text ));
83168404}
83178405
8406+ int node_bind (struct node * n ) {
8407+ return _node_bind (n );
8408+ }
8409+
8410+ struct node * node_clone_and_register (struct node * n_ ) {
8411+ struct sctx * ctx = n_ -> ctx ;
8412+ struct xnode * n = (struct xnode * ) n_ ;
8413+ struct xnode * x = pool_calloc (g_env .pool , sizeof (* x ));
8414+ * x = * n ;
8415+ x -> base .flags = 0 ;
8416+ x -> base .child = 0 ;
8417+ x -> base .next = 0 ;
8418+ x -> base .parent = 0 ;
8419+ x -> base .impl = 0 ;
8420+ x -> base .value_get = 0 ;
8421+ x -> base .init = 0 ;
8422+ x -> base .setup = 0 ;
8423+ x -> base .build = 0 ;
8424+ x -> base .post_build = 0 ;
8425+ x -> base .dispose = 0 ;
8426+ _node_register (ctx , x );
8427+ return (struct node * ) x ;
8428+ }
8429+
83188430static char * _text_escaped (char * wp , const char * rp ) {
83198431 // Replace: \} \{ \n \r \t
83208432 int esc = 0 ;
@@ -8550,16 +8662,17 @@ static void _script_destroy(struct sctx *s) {
85508662
85518663static int _node_bind (struct node * n ) {
85528664 int rc = 0 ;
8553- // Tree has been built since its safe to compute node name
8554- if (n -> type != NODE_TYPE_SCRIPT ) {
8555- n -> name = pool_printf (g_env .pool , "%s:%-3u %5s" , _node_file (n ), n -> lnum , n -> value );
8556- } else {
8557- n -> name = pool_printf (g_env .pool , "%s %5s" , _node_file (n ), "" );
8558- }
8559- n -> vfile = pool_printf (g_env .pool , ".%u" , n -> index );
8560-
85618665 if (!(n -> flags & NODE_FLG_BOUND )) {
85628666 n -> flags |= NODE_FLG_BOUND ;
8667+
8668+ // Tree has been built since its safe to compute node name
8669+ if (n -> type != NODE_TYPE_SCRIPT ) {
8670+ n -> name = pool_printf (g_env .pool , "%s:%-3u %5s" , _node_file (n ), n -> lnum , n -> value );
8671+ } else {
8672+ n -> name = pool_printf (g_env .pool , "%s %5s" , _node_file (n ), "" );
8673+ }
8674+ n -> vfile = pool_printf (g_env .pool , ".%u" , n -> index );
8675+
85638676 switch (n -> type ) {
85648677 case NODE_TYPE_SCRIPT :
85658678 rc = node_script_setup (n );
@@ -8680,7 +8793,7 @@ const char* node_value(struct node *n) {
86808793}
86818794
86828795void node_reset (struct node * n ) {
8683- n -> flags &= ~(NODE_FLG_UPDATED | NODE_FLG_BUILT | NODE_FLG_SETUP | NODE_FLG_INIT );
8796+ n -> flags &= ~(NODE_FLG_BUILT | NODE_FLG_SETUP | NODE_FLG_INIT );
86848797}
86858798
86868799static void _init_subnodes (struct node * n ) {
@@ -8714,30 +8827,6 @@ static void _post_build_subnodes(struct node *n) {
87148827 }
87158828}
87168829
8717- static void _macro_call_init (struct node * n ) {
8718- }
8719-
8720- static void _macros_init (struct sctx * s ) {
8721- for (int i = 0 ; i < s -> nodes .num ; ++ i ) {
8722- struct node * n = NODE_AT (& s -> nodes , i );
8723- if (n -> type == NODE_TYPE_MACRO ) {
8724- n -> flags |= NODE_FLG_SETUP ;
8725- _node_context_push (n );
8726- n -> init (n );
8727- _node_context_pop (n );
8728- }
8729- }
8730- for (int i = 0 ; i < s -> nodes .num ; ++ i ) {
8731- struct node * n = NODE_AT (& s -> nodes , i );
8732- if (n -> type == NODE_TYPE_CALL && !(n -> flags & NODE_FLG_CALLED )) {
8733- n -> flags |= NODE_FLG_CALLED ;
8734- _node_context_push (n );
8735- _macro_call_init (n );
8736- _node_context_pop (n );
8737- }
8738- }
8739- }
8740-
87418830void node_init (struct node * n ) {
87428831 if (!node_is_init (n )) {
87438832 n -> flags |= NODE_FLG_INIT ;
@@ -8746,6 +8835,8 @@ void node_init(struct node *n) {
87468835 case NODE_TYPE_INCLUDE :
87478836 case NODE_TYPE_FOREACH :
87488837 case NODE_TYPE_IN_SOURCES :
8838+ case NODE_TYPE_MACRO :
8839+ case NODE_TYPE_CALL :
87498840 _node_context_push (n );
87508841 n -> init (n );
87518842 _init_subnodes (n );
@@ -8895,7 +8986,6 @@ int script_include(struct node *parent, const char *file, struct node **out) {
88958986
88968987void script_build (struct sctx * s ) {
88978988 akassert (s -> root );
8898- _macros_init (s );
88998989 node_init (s -> root );
89008990 node_setup (s -> root );
89018991 node_build (s -> root );
0 commit comments