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 }