From 9573f5794fc297ab426f9a1c376c78c1a176d910 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Wed, 17 Sep 2025 12:45:25 +0100 Subject: [PATCH] Added %.x support --- rule.c | 40 ++++++++++++++++++++++++++++++++- variable.c | 11 ++++++--- xmake.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/rule.c b/rule.c index 58470f3..0959631 100644 --- a/rule.c +++ b/rule.c @@ -1,6 +1,7 @@ /****************************************************************************** * @file rule.c *****************************************************************************/ +#include #include #include "command.h" @@ -16,8 +17,45 @@ struct rule *rule_find (const char *name) { struct hashtab_name *key; + char *hash_tagged_name = 0; + char *dot = 0, *ptr = 0; + if (!(key = hashtab_get_key (&hashtab_rules, name))) { - return 0; + + hash_tagged_name = xstrdup (name); + + /* Find the begining of the filename. */ + if (!(ptr = strrchr (hash_tagged_name, '/'))) { + ptr = strrchr (hash_tagged_name, '\\'); + } + + if (!ptr) { + ptr = hash_tagged_name; + } else { + ptr++; + } + + /* Replace filename by '%'. */ + if (*ptr) { + + dot = strrchr (ptr, '.'); + *ptr++ = '%'; + + if (dot) { + memmove (ptr, dot, strlen (dot) + 1); + } else { + *ptr = '\0'; + } + + } + + key = hashtab_get_key (&hashtab_rules, hash_tagged_name); + free (hash_tagged_name); + + if (!key) { + return 0; + } + } return hashtab_get (&hashtab_rules, key); diff --git a/variable.c b/variable.c index b6f645f..cb44327 100644 --- a/variable.c +++ b/variable.c @@ -576,7 +576,7 @@ static char *variable_suffix_replace (char *body, const char *from_s, const char size_t rem = strlen (to_s) - strlen (from_s); - new_body = xrealloc (new_body, strlen (new_body) + rem); + new_body = xrealloc (new_body, strlen (new_body) + rem + 1); memmove (p + rem, p, strlen (p) + 1); memcpy (p, to_s, strlen (to_s)); @@ -670,7 +670,7 @@ char *variable_expand_line (const char *filename, unsigned long line_no, char *l while (line[pos]) { - if (line[pos] == '$') { + if (line[pos] == '$' || (line[pos] == '%' && variable_find ("%"))) { char *new, *replacement = ""; char *p_after_variable; @@ -681,7 +681,12 @@ char *variable_expand_line (const char *filename, unsigned long line_no, char *l struct builtin_function *func; char saved_ch; - if (line[pos + 1] == '$') { + if (line[pos] == '%') { + + var = variable_find ("%"); + p_after_variable = line + pos + 1; + + } else if (line[pos + 1] == '$') { p_after_variable = line + pos + 2; pos += 1; diff --git a/xmake.c b/xmake.c index e25b188..f7ae429 100644 --- a/xmake.c +++ b/xmake.c @@ -7,6 +7,8 @@ #if defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__) # define __USE_POSIX +#elif defined (_WIN32) +# define strcasecmp _stricmp #endif #include @@ -706,18 +708,57 @@ static int rule_use (struct rule *r, char *name) { struct dep *dep; - char *p, *star_name, *lesser_name; + char *hash_name = 0, *filename = 0, *dot = 0, *n2 = 0; int ret; + char *p, *star_name, *lesser_name; + CString str; cstr_new (&str); for (dep = r->deps; dep; dep = dep->next) { - cstr_cat (&str, dep->name, strlen (dep->name)); + if ((p = strchr (dep->name, '%'))) { + + /* Replace the rule's '%' by the filename without extension. */ + n2 = xmalloc (strlen (dep->name) + strlen (name) + 1); + strncat (n2, dep->name, p - dep->name); + + if (!(filename = strrchr (name, '/'))) { + filename = strrchr (name, '\\'); + } + + if (!filename) { + filename = name; + } else { + filename++; + } + + if ((dot = strrchr (filename, '.'))) { + strncat (n2, filename, dot - filename); + } else { + strcat (n2, filename); + } + + strcat (n2, p + 1); + + ret = rule_search_and_build (n2); + cstr_cat (&str, n2, strlen (n2)); + + free (n2); + + if (ret) { + return ret; + } + + } else { + + cstr_cat (&str, dep->name, strlen (dep->name)); + + if ((ret = rule_search_and_build (dep->name))) { + return ret; + } - if ((ret = rule_search_and_build (dep->name))) { - return ret; } if (dep->next) { @@ -749,8 +790,25 @@ static int rule_use (struct rule *r, char *name) { *p = '\0'; } + if (!(filename = strrchr (name, '/'))) { + filename = strrchr (name, '\\'); + } + + if (!filename) { + filename = name; + } else { + filename++; + } + + hash_name = xstrdup (filename); + + if ((dot = strrchr (hash_name, '.'))) { + *dot = '\0'; + } + variable_change ("@", xstrdup (name), VAR_ORIGIN_AUTOMATIC); variable_change ("<", lesser_name, VAR_ORIGIN_AUTOMATIC); + variable_change ("%", hash_name, VAR_ORIGIN_AUTOMATIC); variable_change ("*", star_name, VAR_ORIGIN_AUTOMATIC); variable_change ("^", xstrdup (str.data), VAR_ORIGIN_AUTOMATIC); -- 2.34.1