Deleted Added
full compact
var.c (105895) var.c (106106)
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.

--- 25 unchanged lines hidden (view full) ---

34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)var.c 8.3 (Berkeley) 3/19/94
39 */
40
41#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.

--- 25 unchanged lines hidden (view full) ---

34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)var.c 8.3 (Berkeley) 3/19/94
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/usr.bin/make/var.c 105895 2002-10-24 20:37:58Z jmallett $");
42__FBSDID("$FreeBSD: head/usr.bin/make/var.c 106106 2002-10-28 23:33:57Z jmallett $");
43
44/*-
45 * var.c --
46 * Variable-handling functions
47 *
48 * Interface:
49 * Var_Set Set the value of a variable in the given
50 * context. The variable is created if it doesn't

--- 33 unchanged lines hidden (view full) ---

84 */
85
86#include <ctype.h>
87#include <sys/types.h>
88#include <regex.h>
89#include <stdlib.h>
90#include "make.h"
91#include "buf.h"
43
44/*-
45 * var.c --
46 * Variable-handling functions
47 *
48 * Interface:
49 * Var_Set Set the value of a variable in the given
50 * context. The variable is created if it doesn't

--- 33 unchanged lines hidden (view full) ---

84 */
85
86#include <ctype.h>
87#include <sys/types.h>
88#include <regex.h>
89#include <stdlib.h>
90#include "make.h"
91#include "buf.h"
92#include "var.h"
92
93/*
94 * This is a harmless return value for Var_Parse that can be used by Var_Subst
95 * to determine if there was an error in parsing -- easier than returning
96 * a flag, as things outside this module don't give a hoot.
97 */
98char var_Error[] = "";
99

--- 24 unchanged lines hidden (view full) ---

124GNode *VAR_CMD; /* variables defined on the command-line */
125
126static Lst allVars; /* List of all variables */
127
128#define FIND_CMD 0x1 /* look in VAR_CMD when searching */
129#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
130#define FIND_ENV 0x4 /* look in the environment also */
131
93
94/*
95 * This is a harmless return value for Var_Parse that can be used by Var_Subst
96 * to determine if there was an error in parsing -- easier than returning
97 * a flag, as things outside this module don't give a hoot.
98 */
99char var_Error[] = "";
100

--- 24 unchanged lines hidden (view full) ---

125GNode *VAR_CMD; /* variables defined on the command-line */
126
127static Lst allVars; /* List of all variables */
128
129#define FIND_CMD 0x1 /* look in VAR_CMD when searching */
130#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
131#define FIND_ENV 0x4 /* look in the environment also */
132
132typedef struct Var {
133 char *name; /* the variable's name */
134 Buffer val; /* its value */
135 int flags; /* miscellaneous status flags */
136#define VAR_IN_USE 1 /* Variable's value currently being used.
137 * Used to avoid recursion */
138#define VAR_FROM_ENV 2 /* Variable comes from the environment */
139#define VAR_JUNK 4 /* Variable is a junk variable that
140 * should be destroyed when done with
141 * it. Used by Var_Parse for undefined,
142 * modified variables */
143} Var;
144
145/* Var*Pattern flags */
146#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
147#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
148#define VAR_SUB_MATCHED 0x04 /* There was a match */
149#define VAR_MATCH_START 0x08 /* Match at start of word */
150#define VAR_MATCH_END 0x10 /* Match at end of word */
151#define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */
152
153typedef struct {
154 char *lhs; /* String to match */
155 int leftLen; /* Length of string */
156 char *rhs; /* Replacement string (w/ &'s removed) */
157 int rightLen; /* Length of replacement */
158 int flags;
159} VarPattern;
160
161typedef struct {
162 regex_t re;
163 int nsub;
164 regmatch_t *matches;
165 char *replace;
166 int flags;
167} VarREPattern;
168
169static int VarCmp(void *, void *);
170static void VarPossiblyExpand(char **, GNode *);
171static Var *VarFind(char *, GNode *, int);
172static void VarAdd(char *, char *, GNode *);
173static void VarDelete(void *);
133static int VarCmp(void *, void *);
134static void VarPossiblyExpand(char **, GNode *);
135static Var *VarFind(char *, GNode *, int);
136static void VarAdd(char *, char *, GNode *);
137static void VarDelete(void *);
174static Boolean VarHead(char *, Boolean, Buffer, void *);
175static Boolean VarTail(char *, Boolean, Buffer, void *);
176static Boolean VarSuffix(char *, Boolean, Buffer, void *);
177static Boolean VarRoot(char *, Boolean, Buffer, void *);
178static Boolean VarMatch(char *, Boolean, Buffer, void *);
179#ifdef SYSVVARSUB
180static Boolean VarSYSVMatch(char *, Boolean, Buffer, void *);
181#endif
182static Boolean VarNoMatch(char *, Boolean, Buffer, void *);
183static void VarREError(int, regex_t *, const char *);
184static Boolean VarRESubstitute(char *, Boolean, Buffer, void *);
185static Boolean VarSubstitute(char *, Boolean, Buffer, void *);
186static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
187 VarPattern *);
138static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
139 VarPattern *);
188static char *VarQuote(char *);
189static char *VarModify(char *, Boolean (*)(char *, Boolean, Buffer, void *),
140static char *VarQuote(const char *);
141static char *VarModify(char *,
142 Boolean (*)(const char *, Boolean, Buffer, void *),
190 void *);
191static int VarPrintVar(void *, void *);
192
193/*-
194 *-----------------------------------------------------------------------
195 * VarCmp --
196 * See if the given variable matches the named one. Called from
197 * Lst_Find when searching for a variable of a given name.

--- 413 unchanged lines hidden (view full) ---

611 return p;
612 } else {
613 return ((char *) NULL);
614 }
615}
616
617/*-
618 *-----------------------------------------------------------------------
143 void *);
144static int VarPrintVar(void *, void *);
145
146/*-
147 *-----------------------------------------------------------------------
148 * VarCmp --
149 * See if the given variable matches the named one. Called from
150 * Lst_Find when searching for a variable of a given name.

--- 413 unchanged lines hidden (view full) ---

564 return p;
565 } else {
566 return ((char *) NULL);
567 }
568}
569
570/*-
571 *-----------------------------------------------------------------------
619 * VarHead --
620 * Remove the tail of the given word and place the result in the given
621 * buffer.
622 *
623 * Results:
624 * TRUE if characters were added to the buffer (a space needs to be
625 * added to the buffer before the next word).
626 *
627 * Side Effects:
628 * The trimmed word is added to the buffer.
629 *
630 *-----------------------------------------------------------------------
631 */
632static Boolean
633VarHead (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
634{
635 char *slash;
636
637 slash = strrchr (word, '/');
638 if (slash != (char *)NULL) {
639 if (addSpace) {
640 Buf_AddByte (buf, (Byte)' ');
641 }
642 *slash = '\0';
643 Buf_AddBytes (buf, strlen (word), (Byte *)word);
644 *slash = '/';
645 return (TRUE);
646 } else {
647 /*
648 * If no directory part, give . (q.v. the POSIX standard)
649 */
650 if (addSpace) {
651 Buf_AddBytes(buf, 2, (Byte *)" .");
652 } else {
653 Buf_AddByte(buf, (Byte)'.');
654 }
655 }
656 return (TRUE);
657}
658
659/*-
660 *-----------------------------------------------------------------------
661 * VarTail --
662 * Remove the head of the given word and place the result in the given
663 * buffer.
664 *
665 * Results:
666 * TRUE if characters were added to the buffer (a space needs to be
667 * added to the buffer before the next word).
668 *
669 * Side Effects:
670 * The trimmed word is added to the buffer.
671 *
672 *-----------------------------------------------------------------------
673 */
674static Boolean
675VarTail (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
676{
677 char *slash;
678
679 if (addSpace) {
680 Buf_AddByte (buf, (Byte)' ');
681 }
682
683 slash = strrchr (word, '/');
684 if (slash != (char *)NULL) {
685 *slash++ = '\0';
686 Buf_AddBytes (buf, strlen(slash), (Byte *)slash);
687 slash[-1] = '/';
688 } else {
689 Buf_AddBytes (buf, strlen(word), (Byte *)word);
690 }
691 return (TRUE);
692}
693
694/*-
695 *-----------------------------------------------------------------------
696 * VarSuffix --
697 * Place the suffix of the given word in the given buffer.
698 *
699 * Results:
700 * TRUE if characters were added to the buffer (a space needs to be
701 * added to the buffer before the next word).
702 *
703 * Side Effects:
704 * The suffix from the word is placed in the buffer.
705 *
706 *-----------------------------------------------------------------------
707 */
708static Boolean
709VarSuffix (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
710{
711 char *dot;
712
713 dot = strrchr (word, '.');
714 if (dot != (char *)NULL) {
715 if (addSpace) {
716 Buf_AddByte (buf, (Byte)' ');
717 }
718 *dot++ = '\0';
719 Buf_AddBytes (buf, strlen (dot), (Byte *)dot);
720 dot[-1] = '.';
721 addSpace = TRUE;
722 }
723 return (addSpace);
724}
725
726/*-
727 *-----------------------------------------------------------------------
728 * VarRoot --
729 * Remove the suffix of the given word and place the result in the
730 * buffer.
731 *
732 * Results:
733 * TRUE if characters were added to the buffer (a space needs to be
734 * added to the buffer before the next word).
735 *
736 * Side Effects:
737 * The trimmed word is added to the buffer.
738 *
739 *-----------------------------------------------------------------------
740 */
741static Boolean
742VarRoot (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
743{
744 char *dot;
745
746 if (addSpace) {
747 Buf_AddByte (buf, (Byte)' ');
748 }
749
750 dot = strrchr (word, '.');
751 if (dot != (char *)NULL) {
752 *dot = '\0';
753 Buf_AddBytes (buf, strlen (word), (Byte *)word);
754 *dot = '.';
755 } else {
756 Buf_AddBytes (buf, strlen(word), (Byte *)word);
757 }
758 return (TRUE);
759}
760
761/*-
762 *-----------------------------------------------------------------------
763 * VarMatch --
764 * Place the word in the buffer if it matches the given pattern.
765 * Callback function for VarModify to implement the :M modifier.
766 * A space will be added if requested. A pattern is supplied
767 * which the word must match.
768 *
769 * Results:
770 * TRUE if a space should be placed in the buffer before the next
771 * word.
772 *
773 * Side Effects:
774 * The word may be copied to the buffer.
775 *
776 *-----------------------------------------------------------------------
777 */
778static Boolean
779VarMatch (char *word, Boolean addSpace, Buffer buf, void *pattern)
780{
781 if (Str_Match(word, (char *) pattern)) {
782 if (addSpace) {
783 Buf_AddByte(buf, (Byte)' ');
784 }
785 addSpace = TRUE;
786 Buf_AddBytes(buf, strlen(word), (Byte *)word);
787 }
788 return(addSpace);
789}
790
791#ifdef SYSVVARSUB
792/*-
793 *-----------------------------------------------------------------------
794 * VarSYSVMatch --
795 * Place the word in the buffer if it matches the given pattern.
796 * Callback function for VarModify to implement the System V %
797 * modifiers. A space is added if requested.
798 *
799 * Results:
800 * TRUE if a space should be placed in the buffer before the next
801 * word.
802 *
803 * Side Effects:
804 * The word may be copied to the buffer.
805 *
806 *-----------------------------------------------------------------------
807 */
808static Boolean
809VarSYSVMatch (char *word, Boolean addSpace, Buffer buf, void *patp)
810{
811 int len;
812 char *ptr;
813 VarPattern *pat = (VarPattern *) patp;
814
815 if (addSpace)
816 Buf_AddByte(buf, (Byte)' ');
817
818 addSpace = TRUE;
819
820 if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL)
821 Str_SYSVSubst(buf, pat->rhs, ptr, len);
822 else
823 Buf_AddBytes(buf, strlen(word), (Byte *) word);
824
825 return(addSpace);
826}
827#endif
828
829
830/*-
831 *-----------------------------------------------------------------------
832 * VarNoMatch --
833 * Place the word in the buffer if it doesn't match the given pattern.
834 * Callback function for VarModify to implement the :N modifier. A
835 * space is added if requested.
836 *
837 * Results:
838 * TRUE if a space should be placed in the buffer before the next
839 * word.
840 *
841 * Side Effects:
842 * The word may be copied to the buffer.
843 *
844 *-----------------------------------------------------------------------
845 */
846static Boolean
847VarNoMatch (char *word, Boolean addSpace, Buffer buf, void *pattern)
848{
849 if (!Str_Match(word, (char *) pattern)) {
850 if (addSpace) {
851 Buf_AddByte(buf, (Byte)' ');
852 }
853 addSpace = TRUE;
854 Buf_AddBytes(buf, strlen(word), (Byte *)word);
855 }
856 return(addSpace);
857}
858
859
860/*-
861 *-----------------------------------------------------------------------
862 * VarSubstitute --
863 * Perform a string-substitution on the given word, placing the
864 * result in the passed buffer. A space is added if requested.
865 *
866 * Results:
867 * TRUE if a space is needed before more characters are added.
868 *
869 * Side Effects:
870 * None.
871 *
872 *-----------------------------------------------------------------------
873 */
874static Boolean
875VarSubstitute (char *word, Boolean addSpace, Buffer buf, void *patternp)
876{
877 int wordLen; /* Length of word */
878 char *cp; /* General pointer */
879 VarPattern *pattern = (VarPattern *) patternp;
880
881 wordLen = strlen(word);
882 if (1) { /* substitute in each word of the variable */
883 /*
884 * Break substitution down into simple anchored cases
885 * and if none of them fits, perform the general substitution case.
886 */
887 if ((pattern->flags & VAR_MATCH_START) &&
888 (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
889 /*
890 * Anchored at start and beginning of word matches pattern
891 */
892 if ((pattern->flags & VAR_MATCH_END) &&
893 (wordLen == pattern->leftLen)) {
894 /*
895 * Also anchored at end and matches to the end (word
896 * is same length as pattern) add space and rhs only
897 * if rhs is non-null.
898 */
899 if (pattern->rightLen != 0) {
900 if (addSpace) {
901 Buf_AddByte(buf, (Byte)' ');
902 }
903 addSpace = TRUE;
904 Buf_AddBytes(buf, pattern->rightLen,
905 (Byte *)pattern->rhs);
906 }
907 } else if (pattern->flags & VAR_MATCH_END) {
908 /*
909 * Doesn't match to end -- copy word wholesale
910 */
911 goto nosub;
912 } else {
913 /*
914 * Matches at start but need to copy in trailing characters
915 */
916 if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
917 if (addSpace) {
918 Buf_AddByte(buf, (Byte)' ');
919 }
920 addSpace = TRUE;
921 }
922 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
923 Buf_AddBytes(buf, wordLen - pattern->leftLen,
924 (Byte *)(word + pattern->leftLen));
925 }
926 } else if (pattern->flags & VAR_MATCH_START) {
927 /*
928 * Had to match at start of word and didn't -- copy whole word.
929 */
930 goto nosub;
931 } else if (pattern->flags & VAR_MATCH_END) {
932 /*
933 * Anchored at end, Find only place match could occur (leftLen
934 * characters from the end of the word) and see if it does. Note
935 * that because the $ will be left at the end of the lhs, we have
936 * to use strncmp.
937 */
938 cp = word + (wordLen - pattern->leftLen);
939 if ((cp >= word) &&
940 (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
941 /*
942 * Match found. If we will place characters in the buffer,
943 * add a space before hand as indicated by addSpace, then
944 * stuff in the initial, unmatched part of the word followed
945 * by the right-hand-side.
946 */
947 if (((cp - word) + pattern->rightLen) != 0) {
948 if (addSpace) {
949 Buf_AddByte(buf, (Byte)' ');
950 }
951 addSpace = TRUE;
952 }
953 Buf_AddBytes(buf, cp - word, (Byte *)word);
954 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
955 } else {
956 /*
957 * Had to match at end and didn't. Copy entire word.
958 */
959 goto nosub;
960 }
961 } else {
962 /*
963 * Pattern is unanchored: search for the pattern in the word using
964 * String_FindSubstring, copying unmatched portions and the
965 * right-hand-side for each match found, handling non-global
966 * substitutions correctly, etc. When the loop is done, any
967 * remaining part of the word (word and wordLen are adjusted
968 * accordingly through the loop) is copied straight into the
969 * buffer.
970 * addSpace is set FALSE as soon as a space is added to the
971 * buffer.
972 */
973 Boolean done;
974 int origSize;
975
976 done = FALSE;
977 origSize = Buf_Size(buf);
978 while (!done) {
979 cp = Str_FindSubstring(word, pattern->lhs);
980 if (cp != (char *)NULL) {
981 if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
982 Buf_AddByte(buf, (Byte)' ');
983 addSpace = FALSE;
984 }
985 Buf_AddBytes(buf, cp-word, (Byte *)word);
986 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
987 wordLen -= (cp - word) + pattern->leftLen;
988 word = cp + pattern->leftLen;
989 if (wordLen == 0 || (pattern->flags & VAR_SUB_GLOBAL) == 0){
990 done = TRUE;
991 }
992 } else {
993 done = TRUE;
994 }
995 }
996 if (wordLen != 0) {
997 if (addSpace) {
998 Buf_AddByte(buf, (Byte)' ');
999 }
1000 Buf_AddBytes(buf, wordLen, (Byte *)word);
1001 }
1002 /*
1003 * If added characters to the buffer, need to add a space
1004 * before we add any more. If we didn't add any, just return
1005 * the previous value of addSpace.
1006 */
1007 return ((Buf_Size(buf) != origSize) || addSpace);
1008 }
1009 /*
1010 * Common code for anchored substitutions:
1011 * addSpace was set TRUE if characters were added to the buffer.
1012 */
1013 return (addSpace);
1014 }
1015 nosub:
1016 if (addSpace) {
1017 Buf_AddByte(buf, (Byte)' ');
1018 }
1019 Buf_AddBytes(buf, wordLen, (Byte *)word);
1020 return(TRUE);
1021}
1022
1023/*-
1024 *-----------------------------------------------------------------------
1025 * VarREError --
1026 * Print the error caused by a regcomp or regexec call.
1027 *
1028 * Results:
1029 * None.
1030 *
1031 * Side Effects:
1032 * An error gets printed.
1033 *
1034 *-----------------------------------------------------------------------
1035 */
1036static void
1037VarREError(int err, regex_t *pat, const char *str)
1038{
1039 char *errbuf;
1040 int errlen;
1041
1042 errlen = regerror(err, pat, 0, 0);
1043 errbuf = emalloc(errlen);
1044 regerror(err, pat, errbuf, errlen);
1045 Error("%s: %s", str, errbuf);
1046 free(errbuf);
1047}
1048
1049
1050/*-
1051 *-----------------------------------------------------------------------
1052 * VarRESubstitute --
1053 * Perform a regex substitution on the given word, placing the
1054 * result in the passed buffer. A space is added if requested.
1055 *
1056 * Results:
1057 * TRUE if a space is needed before more characters are added.
1058 *
1059 * Side Effects:
1060 * None.
1061 *
1062 *-----------------------------------------------------------------------
1063 */
1064static Boolean
1065VarRESubstitute(char *word, Boolean addSpace, Buffer buf, void *patternp)
1066{
1067 VarREPattern *pat;
1068 int xrv;
1069 char *wp;
1070 char *rp;
1071 int added;
1072 int flags = 0;
1073
1074#define MAYBE_ADD_SPACE() \
1075 if (addSpace && !added) \
1076 Buf_AddByte(buf, ' '); \
1077 added = 1
1078
1079 added = 0;
1080 wp = word;
1081 pat = patternp;
1082
1083 if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
1084 (VAR_SUB_ONE|VAR_SUB_MATCHED))
1085 xrv = REG_NOMATCH;
1086 else {
1087 tryagain:
1088 xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
1089 }
1090
1091 switch (xrv) {
1092 case 0:
1093 pat->flags |= VAR_SUB_MATCHED;
1094 if (pat->matches[0].rm_so > 0) {
1095 MAYBE_ADD_SPACE();
1096 Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
1097 }
1098
1099 for (rp = pat->replace; *rp; rp++) {
1100 if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
1101 MAYBE_ADD_SPACE();
1102 Buf_AddByte(buf,rp[1]);
1103 rp++;
1104 }
1105 else if ((*rp == '&') ||
1106 ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
1107 int n;
1108 char *subbuf;
1109 int sublen;
1110 char errstr[3];
1111
1112 if (*rp == '&') {
1113 n = 0;
1114 errstr[0] = '&';
1115 errstr[1] = '\0';
1116 } else {
1117 n = rp[1] - '0';
1118 errstr[0] = '\\';
1119 errstr[1] = rp[1];
1120 errstr[2] = '\0';
1121 rp++;
1122 }
1123
1124 if (n > pat->nsub) {
1125 Error("No subexpression %s", &errstr[0]);
1126 subbuf = "";
1127 sublen = 0;
1128 } else if ((pat->matches[n].rm_so == -1) &&
1129 (pat->matches[n].rm_eo == -1)) {
1130 Error("No match for subexpression %s", &errstr[0]);
1131 subbuf = "";
1132 sublen = 0;
1133 } else {
1134 subbuf = wp + pat->matches[n].rm_so;
1135 sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
1136 }
1137
1138 if (sublen > 0) {
1139 MAYBE_ADD_SPACE();
1140 Buf_AddBytes(buf, sublen, subbuf);
1141 }
1142 } else {
1143 MAYBE_ADD_SPACE();
1144 Buf_AddByte(buf, *rp);
1145 }
1146 }
1147 wp += pat->matches[0].rm_eo;
1148 if (pat->flags & VAR_SUB_GLOBAL) {
1149 flags |= REG_NOTBOL;
1150 if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
1151 MAYBE_ADD_SPACE();
1152 Buf_AddByte(buf, *wp);
1153 wp++;
1154
1155 }
1156 if (*wp)
1157 goto tryagain;
1158 }
1159 if (*wp) {
1160 MAYBE_ADD_SPACE();
1161 Buf_AddBytes(buf, strlen(wp), wp);
1162 }
1163 break;
1164 default:
1165 VarREError(xrv, &pat->re, "Unexpected regex error");
1166 /* fall through */
1167 case REG_NOMATCH:
1168 if (*wp) {
1169 MAYBE_ADD_SPACE();
1170 Buf_AddBytes(buf,strlen(wp),wp);
1171 }
1172 break;
1173 }
1174 return(addSpace||added);
1175}
1176
1177
1178/*-
1179 *-----------------------------------------------------------------------
1180 * VarModify --
1181 * Modify each of the words of the passed string using the given
1182 * function. Used to implement all modifiers.
1183 *
1184 * Results:
1185 * A string of all the words modified appropriately.
1186 *
1187 * Side Effects:
1188 * None.
1189 *
1190 *-----------------------------------------------------------------------
1191 */
1192static char *
572 * VarModify --
573 * Modify each of the words of the passed string using the given
574 * function. Used to implement all modifiers.
575 *
576 * Results:
577 * A string of all the words modified appropriately.
578 *
579 * Side Effects:
580 * None.
581 *
582 *-----------------------------------------------------------------------
583 */
584static char *
1193VarModify (char *str, Boolean (*modProc)(char *, Boolean, Buffer, void *),
585VarModify (char *str, Boolean (*modProc)(const char *, Boolean, Buffer, void *),
1194 void *datum)
1195{
1196 Buffer buf; /* Buffer for the new string */
1197 Boolean addSpace; /* TRUE if need to add a space to the
1198 * buffer before adding the trimmed
1199 * word */
1200 char **av; /* word list [first word does not count] */
1201 int ac, i;

--- 144 unchanged lines hidden (view full) ---

1346 * The quoted string
1347 *
1348 * Side Effects:
1349 * None.
1350 *
1351 *-----------------------------------------------------------------------
1352 */
1353static char *
586 void *datum)
587{
588 Buffer buf; /* Buffer for the new string */
589 Boolean addSpace; /* TRUE if need to add a space to the
590 * buffer before adding the trimmed
591 * word */
592 char **av; /* word list [first word does not count] */
593 int ac, i;

--- 144 unchanged lines hidden (view full) ---

738 * The quoted string
739 *
740 * Side Effects:
741 * None.
742 *
743 *-----------------------------------------------------------------------
744 */
745static char *
1354VarQuote(char *str)
746VarQuote(const char *str)
1355{
1356
1357 Buffer buf;
1358 /* This should cover most shells :-( */
1359 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
747{
748
749 Buffer buf;
750 /* This should cover most shells :-( */
751 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
752 char *ret;
1360
1361 buf = Buf_Init (MAKE_BSIZE);
1362 for (; *str; str++) {
1363 if (strchr(meta, *str) != NULL)
1364 Buf_AddByte(buf, (Byte)'\\');
1365 Buf_AddByte(buf, (Byte)*str);
1366 }
1367 Buf_AddByte(buf, (Byte) '\0');
753
754 buf = Buf_Init (MAKE_BSIZE);
755 for (; *str; str++) {
756 if (strchr(meta, *str) != NULL)
757 Buf_AddByte(buf, (Byte)'\\');
758 Buf_AddByte(buf, (Byte)*str);
759 }
760 Buf_AddByte(buf, (Byte) '\0');
1368 str = (char *)Buf_GetAll (buf, (int *)NULL);
761 ret = Buf_GetAll (buf, NULL);
1369 Buf_Destroy (buf, FALSE);
762 Buf_Destroy (buf, FALSE);
1370 return str;
763 return ret;
1371}
1372
1373/*-
1374 *-----------------------------------------------------------------------
764}
765
766/*-
767 *-----------------------------------------------------------------------
768 * VarREError --
769 * Print the error caused by a regcomp or regexec call.
770 *
771 * Results:
772 * None.
773 *
774 * Side Effects:
775 * An error gets printed.
776 *
777 *-----------------------------------------------------------------------
778 */
779void
780VarREError(int err, regex_t *pat, const char *str)
781{
782 char *errbuf;
783 int errlen;
784
785 errlen = regerror(err, pat, 0, 0);
786 errbuf = emalloc(errlen);
787 regerror(err, pat, errbuf, errlen);
788 Error("%s: %s", str, errbuf);
789 free(errbuf);
790}
791
792
793/*-
794 *-----------------------------------------------------------------------
1375 * Var_Parse --
1376 * Given the start of a variable invocation, extract the variable
1377 * name and find its value, then modify it according to the
1378 * specification.
1379 *
1380 * Results:
1381 * The (possibly-modified) value of the variable or var_Error if the
1382 * specification is invalid. The length of the specification is

--- 1100 unchanged lines hidden ---
795 * Var_Parse --
796 * Given the start of a variable invocation, extract the variable
797 * name and find its value, then modify it according to the
798 * specification.
799 *
800 * Results:
801 * The (possibly-modified) value of the variable or var_Error if the
802 * specification is invalid. The length of the specification is

--- 1100 unchanged lines hidden ---