29 *
30 * Handle expansion of make macros
31 */
32
33 /*
34 * Included files
35 */
36 #include <mksh/dosys.h> /* sh_command2string() */
37 #include <mksh/i18n.h> /* get_char_semantics_value() */
38 #include <mksh/macro.h>
39 #include <mksh/misc.h> /* retmem() */
40 #include <mksh/read.h> /* get_next_block_fn() */
41 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
42
43 #include <widec.h>
44
45 /*
46 * File table of contents
47 */
48 static void add_macro_to_global_list(Name macro_to_add);
49 #ifdef NSE
50 static void expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd);
51 #else
52 static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
53 #endif
54
55 static void init_arch_macros(void);
56 static void init_mach_macros(void);
57 static Boolean init_arch_done = false;
58 static Boolean init_mach_done = false;
59
60
61 long env_alloc_num = 0;
62 long env_alloc_bytes = 0;
63
64 /*
65 * getvar(name)
66 *
67 * Return expanded value of macro.
68 *
69 * Return value:
70 * The expanded value of the macro
71 *
72 * Parameters:
73 * name The name of the macro we want the value for
612 if (name == make) {
613 make_word_mentioned = true;
614 }
615 if (name == query) {
616 query_mentioned = true;
617 }
618 if ((name == host_arch) || (name == target_arch)) {
619 if (!init_arch_done) {
620 init_arch_done = true;
621 init_arch_macros();
622 }
623 }
624 if ((name == host_mach) || (name == target_mach)) {
625 if (!init_mach_done) {
626 init_mach_done = true;
627 init_mach_macros();
628 }
629 }
630 /* Get the macro value. */
631 macro = get_prop(name->prop, macro_prop);
632 #ifdef NSE
633 if (nse_watch_vars && nse && macro != NULL) {
634 if (macro->body.macro.imported) {
635 nse_shell_var_used= name;
636 }
637 if (macro->body.macro.value != NULL){
638 if (nse_backquotes(macro->body.macro.value->string)) {
639 nse_backquote_seen= name;
640 }
641 }
642 }
643 #endif
644 if ((macro != NULL) && macro->body.macro.is_conditional) {
645 conditional_macro_used = true;
646 /*
647 * Add this conditional macro to the beginning of the
648 * global list.
649 */
650 add_macro_to_global_list(name);
651 if (makefile_type == reading_makefile) {
652 warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"),
653 name->string_mb, file_being_read, line_number);
654 }
655 }
656 /* Macro name read and parsed. Expand the value. */
657 if ((macro == NULL) || (macro->body.macro.value == NULL)) {
658 /* If the value is empty, we just get out of here. */
659 goto exit;
660 }
661 if (replacement == sh_replace) {
662 /* If we should do a :sh transform, we expand the command
663 * and process it.
904 *
905 * Parameters:
906 *
907 * Global variables used:
908 * host_arch Property for magic macro HOST_ARCH
909 * target_arch Property for magic macro TARGET_ARCH
910 *
911 * Return value:
912 * The function does not return a value, but can
913 * call fatal() in case of error.
914 */
915 static void
916 init_arch_macros(void)
917 {
918 String_rec result_string;
919 wchar_t wc_buf[STRING_BUFFER_LENGTH];
920 char mb_buf[STRING_BUFFER_LENGTH];
921 FILE *pipe;
922 Name value;
923 int set_host, set_target;
924 #ifdef NSE
925 Property macro;
926 #endif
927 const char *mach_command = NOCATGETS("/bin/mach");
928
929 set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
930 set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
931
932 if (set_host || set_target) {
933 INIT_STRING_FROM_STACK(result_string, wc_buf);
934 append_char((int) hyphen_char, &result_string);
935
936 if ((pipe = popen(mach_command, "r")) == NULL) {
937 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command);
938 }
939 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
940 MBSTOWCS(wcs_buffer, mb_buf);
941 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
942 }
943 if (pclose(pipe) != 0) {
944 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command);
945 }
946
947 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
948
949 #ifdef NSE
950 macro = setvar_daemon(host_arch, value, false, no_daemon, true, 0);
951 macro->body.macro.imported= true;
952 macro = setvar_daemon(target_arch, value, false, no_daemon, true, 0);
953 macro->body.macro.imported= true;
954 #else
955 if (set_host) {
956 (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
957 }
958 if (set_target) {
959 (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
960 }
961 #endif
962 }
963 }
964
965 /*
966 * init_mach_macros(void)
967 *
968 * Set the magic macros TARGET_MACH, HOST_MACH,
969 *
970 * Parameters:
971 *
972 * Global variables used:
973 * host_mach Property for magic macro HOST_MACH
974 * target_mach Property for magic macro TARGET_MACH
975 *
976 * Return value:
977 * The function does not return a value, but can
978 * call fatal() in case of error.
979 */
980 static void
981 init_mach_macros(void)
1015 (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
1016 }
1017 }
1018 }
1019
1020 /*
1021 * expand_value_with_daemon(name, macro, destination, cmd)
1022 *
1023 * Checks for daemons and then maybe calls expand_value().
1024 *
1025 * Parameters:
1026 * name Name of the macro (Added by the NSE)
1027 * macro The property block with the value to expand
1028 * destination Where the result should be deposited
1029 * cmd If we are evaluating a command line we
1030 * turn \ quoting off
1031 *
1032 * Global variables used:
1033 */
1034 static void
1035 #ifdef NSE
1036 expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd)
1037 #else
1038 expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
1039 #endif
1040 {
1041 register Chain chain;
1042
1043 #ifdef NSE
1044 if (reading_dependencies) {
1045 /*
1046 * Processing the dependencies themselves
1047 */
1048 depvar_dep_macro_used(name);
1049 } else {
1050 /*
1051 * Processing the rules for the targets
1052 * the nse_watch_vars flags chokes off most
1053 * checks. it is true only when processing
1054 * the output from a recursive make run
1055 * which is all we are interested in here.
1056 */
1057 if (nse_watch_vars) {
1058 depvar_rule_macro_used(name);
1059 }
1060 }
1061 #endif
1062
1063 switch (macro->body.macro.daemon) {
1064 case no_daemon:
1065 if (!svr4 && !posix) {
1066 expand_value(macro->body.macro.value, destination, cmd);
1067 } else {
1068 if (dollarless_flag && tilde_rule) {
1069 expand_value(dollarless_value, destination, cmd);
1070 dollarless_flag = false;
1071 tilde_rule = false;
1072 } else {
1073 expand_value(macro->body.macro.value, destination, cmd);
1074 }
1075 }
1076 return;
1077 case chain_daemon:
1078 /* If this is a $? value we call the daemon to translate the */
1079 /* list of names to a string */
1080 for (chain = (Chain) macro->body.macro.value;
1081 chain != NULL;
1119 * makefile_type Used to check if we should enforce read only
1120 * path_name The Name "PATH", compared against
1121 * virtual_root The Name "VIRTUAL_ROOT", compared against
1122 * vpath_defined Set if the macro VPATH is set
1123 * vpath_name The Name "VPATH", compared against
1124 * envvar A list of environment vars with $ in value
1125 */
1126 Property
1127 setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
1128 {
1129 register Property macro = maybe_append_prop(name, macro_prop);
1130 register Property macro_apx = get_prop(name->prop, macro_append_prop);
1131 int length = 0;
1132 String_rec destination;
1133 wchar_t buffer[STRING_BUFFER_LENGTH];
1134 register Chain chain;
1135 Name val;
1136 wchar_t *val_string = (wchar_t*)NULL;
1137 Wstring wcb;
1138
1139 #ifdef NSE
1140 macro->body.macro.imported = false;
1141 #endif
1142
1143 if ((makefile_type != reading_nothing) &&
1144 macro->body.macro.read_only) {
1145 return macro;
1146 }
1147 /* Strip spaces from the end of the value */
1148 if (daemon == no_daemon) {
1149 if(value != NULL) {
1150 wcb.init(value);
1151 length = wcb.length();
1152 val_string = wcb.get_string();
1153 }
1154 if ((length > 0) && iswspace(val_string[length-1])) {
1155 INIT_STRING_FROM_STACK(destination, buffer);
1156 buffer[0] = 0;
1157 append_string(val_string, &destination, length);
1158 if (strip_trailing_spaces) {
1159 while ((length > 0) &&
1160 iswspace(destination.buffer.start[length-1])) {
1161 destination.buffer.start[--length] = 0;
|
29 *
30 * Handle expansion of make macros
31 */
32
33 /*
34 * Included files
35 */
36 #include <mksh/dosys.h> /* sh_command2string() */
37 #include <mksh/i18n.h> /* get_char_semantics_value() */
38 #include <mksh/macro.h>
39 #include <mksh/misc.h> /* retmem() */
40 #include <mksh/read.h> /* get_next_block_fn() */
41 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
42
43 #include <widec.h>
44
45 /*
46 * File table of contents
47 */
48 static void add_macro_to_global_list(Name macro_to_add);
49 static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
50
51 static void init_arch_macros(void);
52 static void init_mach_macros(void);
53 static Boolean init_arch_done = false;
54 static Boolean init_mach_done = false;
55
56
57 long env_alloc_num = 0;
58 long env_alloc_bytes = 0;
59
60 /*
61 * getvar(name)
62 *
63 * Return expanded value of macro.
64 *
65 * Return value:
66 * The expanded value of the macro
67 *
68 * Parameters:
69 * name The name of the macro we want the value for
608 if (name == make) {
609 make_word_mentioned = true;
610 }
611 if (name == query) {
612 query_mentioned = true;
613 }
614 if ((name == host_arch) || (name == target_arch)) {
615 if (!init_arch_done) {
616 init_arch_done = true;
617 init_arch_macros();
618 }
619 }
620 if ((name == host_mach) || (name == target_mach)) {
621 if (!init_mach_done) {
622 init_mach_done = true;
623 init_mach_macros();
624 }
625 }
626 /* Get the macro value. */
627 macro = get_prop(name->prop, macro_prop);
628 if ((macro != NULL) && macro->body.macro.is_conditional) {
629 conditional_macro_used = true;
630 /*
631 * Add this conditional macro to the beginning of the
632 * global list.
633 */
634 add_macro_to_global_list(name);
635 if (makefile_type == reading_makefile) {
636 warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"),
637 name->string_mb, file_being_read, line_number);
638 }
639 }
640 /* Macro name read and parsed. Expand the value. */
641 if ((macro == NULL) || (macro->body.macro.value == NULL)) {
642 /* If the value is empty, we just get out of here. */
643 goto exit;
644 }
645 if (replacement == sh_replace) {
646 /* If we should do a :sh transform, we expand the command
647 * and process it.
888 *
889 * Parameters:
890 *
891 * Global variables used:
892 * host_arch Property for magic macro HOST_ARCH
893 * target_arch Property for magic macro TARGET_ARCH
894 *
895 * Return value:
896 * The function does not return a value, but can
897 * call fatal() in case of error.
898 */
899 static void
900 init_arch_macros(void)
901 {
902 String_rec result_string;
903 wchar_t wc_buf[STRING_BUFFER_LENGTH];
904 char mb_buf[STRING_BUFFER_LENGTH];
905 FILE *pipe;
906 Name value;
907 int set_host, set_target;
908 const char *mach_command = NOCATGETS("/bin/mach");
909
910 set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
911 set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
912
913 if (set_host || set_target) {
914 INIT_STRING_FROM_STACK(result_string, wc_buf);
915 append_char((int) hyphen_char, &result_string);
916
917 if ((pipe = popen(mach_command, "r")) == NULL) {
918 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command);
919 }
920 while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
921 MBSTOWCS(wcs_buffer, mb_buf);
922 append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
923 }
924 if (pclose(pipe) != 0) {
925 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command);
926 }
927
928 value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
929
930 if (set_host) {
931 (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
932 }
933 if (set_target) {
934 (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
935 }
936 }
937 }
938
939 /*
940 * init_mach_macros(void)
941 *
942 * Set the magic macros TARGET_MACH, HOST_MACH,
943 *
944 * Parameters:
945 *
946 * Global variables used:
947 * host_mach Property for magic macro HOST_MACH
948 * target_mach Property for magic macro TARGET_MACH
949 *
950 * Return value:
951 * The function does not return a value, but can
952 * call fatal() in case of error.
953 */
954 static void
955 init_mach_macros(void)
989 (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
990 }
991 }
992 }
993
994 /*
995 * expand_value_with_daemon(name, macro, destination, cmd)
996 *
997 * Checks for daemons and then maybe calls expand_value().
998 *
999 * Parameters:
1000 * name Name of the macro (Added by the NSE)
1001 * macro The property block with the value to expand
1002 * destination Where the result should be deposited
1003 * cmd If we are evaluating a command line we
1004 * turn \ quoting off
1005 *
1006 * Global variables used:
1007 */
1008 static void
1009 expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
1010 {
1011 register Chain chain;
1012
1013
1014 switch (macro->body.macro.daemon) {
1015 case no_daemon:
1016 if (!svr4 && !posix) {
1017 expand_value(macro->body.macro.value, destination, cmd);
1018 } else {
1019 if (dollarless_flag && tilde_rule) {
1020 expand_value(dollarless_value, destination, cmd);
1021 dollarless_flag = false;
1022 tilde_rule = false;
1023 } else {
1024 expand_value(macro->body.macro.value, destination, cmd);
1025 }
1026 }
1027 return;
1028 case chain_daemon:
1029 /* If this is a $? value we call the daemon to translate the */
1030 /* list of names to a string */
1031 for (chain = (Chain) macro->body.macro.value;
1032 chain != NULL;
1070 * makefile_type Used to check if we should enforce read only
1071 * path_name The Name "PATH", compared against
1072 * virtual_root The Name "VIRTUAL_ROOT", compared against
1073 * vpath_defined Set if the macro VPATH is set
1074 * vpath_name The Name "VPATH", compared against
1075 * envvar A list of environment vars with $ in value
1076 */
1077 Property
1078 setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
1079 {
1080 register Property macro = maybe_append_prop(name, macro_prop);
1081 register Property macro_apx = get_prop(name->prop, macro_append_prop);
1082 int length = 0;
1083 String_rec destination;
1084 wchar_t buffer[STRING_BUFFER_LENGTH];
1085 register Chain chain;
1086 Name val;
1087 wchar_t *val_string = (wchar_t*)NULL;
1088 Wstring wcb;
1089
1090
1091 if ((makefile_type != reading_nothing) &&
1092 macro->body.macro.read_only) {
1093 return macro;
1094 }
1095 /* Strip spaces from the end of the value */
1096 if (daemon == no_daemon) {
1097 if(value != NULL) {
1098 wcb.init(value);
1099 length = wcb.length();
1100 val_string = wcb.get_string();
1101 }
1102 if ((length > 0) && iswspace(val_string[length-1])) {
1103 INIT_STRING_FROM_STACK(destination, buffer);
1104 buffer[0] = 0;
1105 append_string(val_string, &destination, length);
1106 if (strip_trailing_spaces) {
1107 while ((length > 0) &&
1108 iswspace(destination.buffer.start[length-1])) {
1109 destination.buffer.start[--length] = 0;
|