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 --- |