Added $(error xxx) support
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Mar 2025 23:11:15 +0000 (23:11 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Mar 2025 23:11:15 +0000 (23:11 +0000)
include/xmake/read.h
include/xmake/variable.h
lib.c
read.c
variable.c
xmake.c

index 20a1c06beda49c5146ff5348f4cf214dc1c6bac9..532f243b8b7c435d68aea8f004ce5eaf2a7ca5d5 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef     _READ_H
 #define     _READ_H
 
+void read_memory_makefile (const char *filename, unsigned long line_no, char *memory);
 int read_makefile (const char *filename);
 
 struct nameseq {
index 4c876bc6fdb7ba2b3e130025753364a03856a26b..95573cb56a3673a49facf44fcffc02652f13ef5b 100644 (file)
@@ -33,9 +33,9 @@ struct variable *variable_add (char *name, char *value, enum variable_origin ori
 struct variable *variable_change (char *name, char *value, enum variable_origin origin);
 struct variable *variable_find (char *name);
 
-char *variable_expand_line (char *line);
+void parse_var_line (const char *filename, unsigned long line_no, char *line, enum variable_origin origin);
+char *variable_expand_line (const char *filename, unsigned long line_no, char *line);
 
-void parse_var_line (char *line, enum variable_origin origin);
 void variables_init (void);
 
 #endif      /* _VARIABLE_H */
diff --git a/lib.c b/lib.c
index e154e324892f94da9153f54ea6fb5607860b6be4..32e53d97402e14f2a5bf7750e151e0dd16b101ea 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -139,7 +139,7 @@ static int non_option (const char *arg) {
     
         char *temp = xstrdup (arg);
         
-        parse_var_line (temp, VAR_ORIGIN_COMMAND_LINE);
+        parse_var_line ("<command-line>", 1, temp, VAR_ORIGIN_COMMAND_LINE);
         free (temp);
     
     } else {
diff --git a/read.c b/read.c
index 46d3778c285b3844ca7bbfad3820c70757991363..673a51fc007d1cf3a1b7dcb910fab747f99587bc 100644 (file)
--- a/read.c
+++ b/read.c
@@ -494,8 +494,8 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
                 fprintf (stderr, "%s: %s: %lu: extraneous text after '%s' directive\n", program_name, lbuf->filename, line_no, ifneq ? "ifneq" : "ifeq");
             }
             
-            p = variable_expand_line (xstrdup (arg1));
-            q = variable_expand_line (xstrdup (arg2));
+            p = variable_expand_line (lbuf->filename, line_no, xstrdup (arg1));
+            q = variable_expand_line (lbuf->filename, line_no, xstrdup (arg2));
             
             if (after_else) {
                 cur_if_stack->prev_ignoring |= !cur_if_stack->ignoring;
@@ -552,7 +552,7 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
             
             }
             
-            p = line = variable_expand_line (xstrdup (skip_whitespace (p)));
+            p = line = variable_expand_line (lbuf->filename, line_no, xstrdup (skip_whitespace (p)));
             
             for (; isspace ((int) *p);) {
                 p++;
@@ -686,7 +686,7 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
             }
             
             *q = '\0';
-            p = line = variable_expand_line (xstrdup (p));
+            p = line = variable_expand_line (lbuf->filename, line_no, xstrdup (p));
             
             while (1) {
             
@@ -707,7 +707,7 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
                 saved_ch = *q;
                 *q = '\0';
                 
-                if ((ret = include_makefile (lbuf->filename, lbuf->line_no, p, bsd))) {
+                if ((ret = include_makefile (lbuf->filename, line_no, p, bsd))) {
                     return ret;
                 }
                 
@@ -722,11 +722,16 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
         
         }
         
-        if (strchr (p, '=')) {
+        if (*p == '$') {
+        
+            variable_expand_line (lbuf->filename, line_no, p);
+            continue;
+        
+        } else if (strchr (p, '=')) {
         
             record_waiting_files ();
             
-            parse_var_line (p, VAR_ORIGIN_FILE);
+            parse_var_line (lbuf->filename, line_no, p, VAR_ORIGIN_FILE);
             continue;
         
         }
@@ -746,7 +751,7 @@ static int read_lbuf (struct linebuf *lbuf, int set_default) {
         }
         
         remove_backslash_newlines (line);
-        line = variable_expand_line (xstrdup (line));
+        line = variable_expand_line (lbuf->filename, line_no, xstrdup (line));
         
         if (!(colon = strchr (line, ':'))) {
         
@@ -876,6 +881,24 @@ int read_makefile (const char *filename) {
 
 }
 
+void read_memory_makefile (const char *filename, unsigned long line_no, char *memory) {
+
+    struct linebuf lbuf;
+    
+    lbuf.size = 256;
+    lbuf.f = 0;
+    
+    lbuf.start = xmalloc (lbuf.size);
+    lbuf.memory = memory;
+    
+    lbuf.filename = filename;
+    lbuf.line_no = line_no;
+    
+    read_lbuf (&lbuf, 1);
+    free (lbuf.start);
+
+}
+
 void *parse_nameseq (char *line, size_t size) {
 
     struct nameseq *start = 0;
index 1bfa1971bea7004ae3632758e36bf1d2f1f37986..a1c6559194fb5e521bfccbecf9a1e06a37e2b163 100644 (file)
@@ -8,12 +8,56 @@
 
 #include    <xmake/hashtab.h>
 #include    <xmake/lib.h>
+#include    <xmake/read.h>
 #include    <xmake/report.h>
 #include    <xmake/variable.h>
 #include    <xmake/xmake.h>
 
+struct builtin_function {
+
+    const char *name;
+    char *(*func) (const char *filename, unsigned long line_no, char *input);
+
+};
+
+static char *func_eval (const char *filename, unsigned long line_no, char *input) {
+
+    read_memory_makefile (filename, line_no, input);
+    return 0;
+
+}
+
+static char *func_error (const char *filename, unsigned long line_no, char *input) {
+
+    fprintf (stderr, "%s: %s: %lu: %s\n", program_name, filename, line_no, input);
+    exit (EXIT_FAILURE);
+
+}
+
+static struct builtin_function builtin_functions[] ={
+
+    {   "eval",     &func_eval      },
+    {   "error",    &func_error     },
+    
+    {   0,          0               }
+
+};
+
+static struct hashtab hashtab_builtin = { 0 };
 static struct hashtab hashtab_vars = { 0 };
 
+static struct builtin_function *find_builtin_function (const char *name) {
+
+    struct hashtab_name *key;
+    
+    if ((key = hashtab_get_key (&hashtab_builtin, name))) {
+        return hashtab_get (&hashtab_builtin, key);
+    }
+    
+    return 0;
+
+}
+
 static char *variable_suffix_replace (char *body, const char *from_s, const char *to_s) {
 
     char *new_body = xstrdup (body);
@@ -124,7 +168,7 @@ struct variable *variable_find (char *name) {
 
 }
 
-char *variable_expand_line (char *line) {
+char *variable_expand_line (const char *filename, unsigned long line_no, char *line) {
 
     size_t pos = 0;
     
@@ -138,6 +182,9 @@ char *variable_expand_line (char *line) {
             struct variable *var = 0;
             char *alloc_replacement = 0;
             
+            struct builtin_function *func;
+            char saved_ch;
+            
             if (line[pos + 1] == '$') {
             
                 p_after_variable = line + pos + 2;
@@ -173,9 +220,27 @@ char *variable_expand_line (char *line) {
                 q--;
                 
                 p_after_variable = q + 1;
-                content = variable_expand_line (xstrndup (body, q - body));
+                content = variable_expand_line (filename, line_no, xstrndup (body, q - body));
+                
+                for (q = content; *q && !isspace ((int) *q);) {
+                    q++;
+                }
+                
+                saved_ch = *q;
+                *q = '\0';
+                
+                func = find_builtin_function (content);
+                *q = saved_ch;
+                
+                if (func) {
+                
+                    for (; isspace ((int) *q);) {
+                        q++;
+                    }
+                    
+                    alloc_replacement = func->func (filename, line_no, q);
                 
-                if ((q = strchr (content, '='))) {
+                } else if ((q = strchr (content, '='))) {
                 
                     char *colon = strchr (content, ':');
                     
@@ -266,7 +331,7 @@ char *variable_expand_line (char *line) {
 
 }
 
-void parse_var_line (char *line, enum variable_origin origin) {
+void parse_var_line (const char *filename, unsigned long line_no, char *line, enum variable_origin origin) {
 
     enum {
         VAR_ASSIGN,
@@ -368,7 +433,7 @@ void parse_var_line (char *line, enum variable_origin origin) {
         ;
     }
     
-    var_name = variable_expand_line (xstrndup (line, p - line));
+    var_name = variable_expand_line (filename, line_no, xstrndup (line, p - line));
     
     if (*var_name == '\0') {
     
@@ -402,7 +467,7 @@ void parse_var_line (char *line, enum variable_origin origin) {
             
             case VAR_FLAVOR_SIMPLY_EXPANDED:
             
-                new_value = variable_expand_line (new_value);
+                new_value = variable_expand_line (filename, line_no, new_value);
                 break;
             
             case VAR_FLAVOR_IMMEDIATELY_EXPANDED: {
@@ -410,7 +475,7 @@ void parse_var_line (char *line, enum variable_origin origin) {
                 size_t dollar_count;
                 char *temp, *p2;
                 
-                new_value = variable_expand_line (new_value);
+                new_value = variable_expand_line (filename, line_no, new_value);
                 
                 for (dollar_count = 0, p = new_value; *p; p++) {
                 
@@ -477,4 +542,19 @@ void parse_var_line (char *line, enum variable_origin origin) {
 
 }
 
-void variables_init (void) {}
+void variables_init (void) {
+
+    struct builtin_function *builtin;
+    struct hashtab_name *key;
+    
+    for (builtin = builtin_functions; builtin->name; builtin++) {
+    
+        if (!(key = hashtab_alloc_name (builtin->name))) {
+            continue;
+        }
+        
+        hashtab_put (&hashtab_builtin, key, builtin);
+    
+    }
+
+}
diff --git a/xmake.c b/xmake.c
index b16032d39d65e2b1469823a01f86a1ee44f0edf5..d11ad843e436df6d5a583897f6ccc11ef32a78ae 100644 (file)
--- a/xmake.c
+++ b/xmake.c
@@ -40,11 +40,11 @@ static int rule_run_command (const char *name, char *p, char *q) {
     char *new_cmds, *s;
     
     *q = '\0';
-    new_cmds = xstrdup (p);
     
+    new_cmds = xstrdup (p);
     *q = '\n';
-    new_cmds = variable_expand_line (new_cmds);
     
+    new_cmds = variable_expand_line ("<command-line>", 1, new_cmds);
     s = new_cmds;
     
     while (isspace ((int) *s) || *s == '-' || *s == '@') {
@@ -281,7 +281,7 @@ static char *find_target (char *target) {
         return 0;
     }
     
-    vpath = variable_expand_line (xstrdup (vpath_var->value));
+    vpath = variable_expand_line ("<command-line>", 1, xstrdup (vpath_var->value));
     
     while (vpath && *vpath) {
     
@@ -562,7 +562,7 @@ int main (int argc, char **argv) {
         path = xmalloc (len + 1);
         sprintf (path, "CURDIR ?= %s", cwd);
         
-        parse_var_line (path, VAR_ORIGIN_FILE);
+        parse_var_line ("<command-line>", 1, path, VAR_ORIGIN_FILE);
         free (path);
         
         len = strlen (".CURDIR") + 4 + strlen (cwd);
@@ -570,7 +570,7 @@ int main (int argc, char **argv) {
         path = xmalloc (len + 1);
         sprintf (path, ".CURDIR ?= %s", cwd);
         
-        parse_var_line (path, VAR_ORIGIN_FILE);
+        parse_var_line ("<command-line>", 1, path, VAR_ORIGIN_FILE);
         free (path);
         
         /*variable_add (xstrdup ("CURDIR"), xstrdup (get_current_directory ()), VAR_ORIGIN_FILE);*/