kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

macro.c (2987B)


      1 /*
      2  * Macro control for make. Ported from pdpmake macro.c. Part of the
      3  * src/api/make.c amalgamation.
      4  */
      5 #include "make.h"
      6 
      7 static struct macro* mk_getmp(MakeCtx* mc, const char* name) {
      8   struct macro* mp;
      9 
     10   for (mp = mc->macrohead[mk_getbucket(name)]; mp; mp = mp->m_next)
     11     if (strcmp(name, mp->m_name) == 0)
     12       return mp;
     13   return NULL;
     14 }
     15 
     16 static int mk_is_valid_macro(MakeCtx* mc, const char* name) {
     17   const char* s;
     18   for (s = name; *s; ++s) {
     19     // In POSIX mode only a limited set of characters are guaranteed
     20     // to be allowed in macro names.
     21 #if ENABLE_FEATURE_MAKE_EXTENSIONS
     22     if (mc->posix)
     23 #endif
     24     {
     25       // Find the appropriate character set
     26       if (((
     27 #if ENABLE_FEATURE_MAKE_EXTENSIONS
     28               (mc->pragma & P_MACRO_NAME) ||
     29 #endif
     30 #if ENABLE_FEATURE_MAKE_POSIX_2024
     31               !POSIX_2017
     32 #else
     33               FALSE
     34 #endif
     35               )
     36                ? !isfname(*s)
     37                : !ispname(*s)))
     38         return FALSE;
     39     }
     40     // As an extension allow anything that can get through the
     41     // input parser, apart from the following.
     42     if (*s == '=')
     43       return FALSE;
     44 #if ENABLE_FEATURE_MAKE_POSIX_2024
     45     if (isblank(*s) || iscntrl(*s))
     46       return FALSE;
     47 #endif
     48   }
     49   return TRUE;
     50 }
     51 
     52 #if ENABLE_FEATURE_MAKE_EXTENSIONS
     53 static int mk_potentially_valid_macro(MakeCtx* mc, const char* name) {
     54   int ret = FALSE;
     55 
     56   if (!(mc->pragma & P_MACRO_NAME)) {
     57     mc->pragma |= P_MACRO_NAME;
     58     ret = mk_is_valid_macro(mc, name);
     59     mc->pragma &= ~P_MACRO_NAME;
     60   }
     61   return ret;
     62 }
     63 #endif
     64 
     65 static void mk_setmacro(MakeCtx* mc, const char* name, const char* val,
     66                         int level) {
     67   struct macro* mp;
     68   bool valid = level & M_VALID;
     69   bool from_env = level & M_ENVIRON;
     70 #if ENABLE_FEATURE_MAKE_EXTENSIONS || ENABLE_FEATURE_MAKE_POSIX_2024
     71   bool immediate = level & M_IMMEDIATE;
     72 #endif
     73 
     74   level &= ~(M_IMMEDIATE | M_VALID | M_ENVIRON);
     75   mp = mk_getmp(mc, name);
     76   if (mp) {
     77     // Don't replace existing macro from a lower level
     78     if (level > mp->m_level)
     79       return;
     80 
     81     // Replace existing macro
     82   } else {
     83     // If not defined, allocate space for new
     84     unsigned int bucket;
     85 
     86     if (!valid && !mk_is_valid_macro(mc, name)) {
     87       // Silently drop invalid names from the environment
     88       if (from_env)
     89         return;
     90 #if ENABLE_FEATURE_MAKE_EXTENSIONS
     91       mk_error(mc, "invalid macro name '%s'%s", name,
     92                mk_potentially_valid_macro(mc, name)
     93                    ? ": allow with pragma macro_name"
     94                    : "");
     95 #else
     96       mk_error(mc, "invalid macro name '%s'", name);
     97 #endif
     98     }
     99 
    100     bucket = mk_getbucket(name);
    101     mp = mk_alloc(mc, sizeof(struct macro));
    102     mp->m_next = mc->macrohead[bucket];
    103     mc->macrohead[bucket] = mp;
    104     mp->m_flag = FALSE;
    105     mp->m_name = mk_strdup(mc, name);
    106   }
    107 #if ENABLE_FEATURE_MAKE_EXTENSIONS || ENABLE_FEATURE_MAKE_POSIX_2024
    108   mp->m_immediate = immediate;
    109 #endif
    110   mp->m_level = level;
    111   mp->m_val = mk_strdup(mc, val ? val : "");
    112 }