Skip to content

Commit 170d75f

Browse files
committed
* Initial macro implementation
1 parent 33edf4c commit 170d75f

File tree

11 files changed

+383
-154
lines changed

11 files changed

+383
-154
lines changed

.gdbinit

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#cd ./autark-cache/tests
2-
#file ./test9
3-
file ./autark-cache/autark
1+
cd ./autark-cache/tests
2+
file ./test10
3+
#file ./autark-cache/autark
44
#set environment CC=clang
55
#set environment IWNET_RUN_TESTS=1
66
#set args /home/adam/Projects/softmotions/iwnet

dist/autark.c

Lines changed: 161 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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+
466469
static 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, ...);
11721174
int 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

65266611
int 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+
83188430
static 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

85518663
static 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

86828795
void 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

86868799
static 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-
87418830
void 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

88968987
void 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

Comments
 (0)