Sat Aug 31 18:14:28 2013 UTC ()
- When the source line is logged (option -s), an empty line above
  helps to see which source line belongs to which warning.
- PKGSRCTOP is a known variable. It is used only in the top-level
  Makefile.
- Arbitrary tool names may be added to TOOLS_NOOP.
- In the top-level Makefile, the alphabetic order of the SUBDIRs
  may have a single exception.


(rillig)
diff -r1.236 -r1.237 pkgsrc/pkgtools/pkglint/files/makevars.map
diff -r1.857 -r1.858 pkgsrc/pkgtools/pkglint/files/pkglint.pl
diff -r1.1 -r1.2 pkgsrc/pkgtools/pkglint/files/PkgLint/Line.pm

cvs diff -r1.236 -r1.237 pkgsrc/pkgtools/pkglint/files/Attic/makevars.map (switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/makevars.map 2013/08/15 20:30:43 1.236
+++ pkgsrc/pkgtools/pkglint/files/Attic/makevars.map 2013/08/31 18:14:28 1.237
@@ -1,745 +1,746 @@ @@ -1,745 +1,746 @@
1# $NetBSD: makevars.map,v 1.236 2013/08/15 20:30:43 rillig Exp $ 1# $NetBSD: makevars.map,v 1.237 2013/08/31 18:14:28 rillig Exp $
2# 2#
3 3
4# This file contains the guessed type of some variables, according to 4# This file contains the guessed type of some variables, according to
5# their current use in pkgsrc. 5# their current use in pkgsrc.
6# 6#
7# The type YesNo is used for variables that are checked using 7# The type YesNo is used for variables that are checked using
8# .if defined(VAR) && !empty(VAR:M[Yy][Ee][Ss]) 8# .if defined(VAR) && !empty(VAR:M[Yy][Ee][Ss])
9# 9#
10# The type Yes is used for variables that are checked using 10# The type Yes is used for variables that are checked using
11# .if defined(VAR) 11# .if defined(VAR)
12# 12#
13# Type type List is used for lists of things. There are two types of lists, 13# Type type List is used for lists of things. There are two types of lists,
14# InternalList and List, which are described in the pkgsrc guide, chapter 14# InternalList and List, which are described in the pkgsrc guide, chapter
15# "Makefiles". 15# "Makefiles".
16 16
17# 17#
18# Some commonly used ACLs. For further documentation, see the chapter 18# Some commonly used ACLs. For further documentation, see the chapter
19# ``The pkglint type system'' in the pkglint developer documentation. 19# ``The pkglint type system'' in the pkglint developer documentation.
20# 20#
21 21
22# A package-defined variable may be set in Makefile, Makefile.common or 22# A package-defined variable may be set in Makefile, Makefile.common or
23# options.mk, since these are commonly used in pkgsrc. Due to the 23# options.mk, since these are commonly used in pkgsrc. Due to the
24# special nature of buildlink3.mk and builtin.mk files, these files may 24# special nature of buildlink3.mk and builtin.mk files, these files may
25# not define those variables. All other .mk files may, allowing for 25# not define those variables. All other .mk files may, allowing for
26# application.mk or similar helper files. 26# application.mk or similar helper files.
27acl package = [m:su, c:dsu, b:, builtin.mk:, *.mk:dsu] 27acl package = [m:su, c:dsu, b:, builtin.mk:, *.mk:dsu]
28 28
29# A package_list may be appended to in all "normal" Makefile fragments. 29# A package_list may be appended to in all "normal" Makefile fragments.
30# This excludes buildlink3.mk and builtin.mk, since they are very 30# This excludes buildlink3.mk and builtin.mk, since they are very
31# special-purpose. Because at the beginning, all lists are empty, in the 31# special-purpose. Because at the beginning, all lists are empty, in the
32# primary Makefile a direct assignment may be used instead of appending. 32# primary Makefile a direct assignment may be used instead of appending.
33# Since Makefile.common files are usually used by packages that know 33# Since Makefile.common files are usually used by packages that know
34# what they are doing, they may set variables directly, too. This rule 34# what they are doing, they may set variables directly, too. This rule
35# can be removed to show a lot of possible problems in pkgsrc. 35# can be removed to show a lot of possible problems in pkgsrc.
36acl package_list = [m:asu, c:asu, b:, builtin.mk:, *.mk:au] 36acl package_list = [m:asu, c:asu, b:, builtin.mk:, *.mk:au]
37acl bl_list = [b:a, builtin.mk:a] 37acl bl_list = [b:a, builtin.mk:a]
38 38
39# A user-defined or system-defined variable must not be set by any 39# A user-defined or system-defined variable must not be set by any
40# package file. It also must not be used in buildlink3.mk and 40# package file. It also must not be used in buildlink3.mk and
41# builtin.mk files or at load-time, since the system/user preferences 41# builtin.mk files or at load-time, since the system/user preferences
42# may not have been loaded when these files are included. 42# may not have been loaded when these files are included.
43acl user = [b:, builtin.mk:, *:u] 43acl user = [b:, builtin.mk:, *:u]
44acl system = [b:, builtin.mk:u, *:u] 44acl system = [b:, builtin.mk:u, *:u]
45acl cmdline = [b:, builtin.mk:, *:pu] 45acl cmdline = [b:, builtin.mk:, *:pu]
46 46
47# The following variables are taken from mk/defaults/mk.conf, 1.118 47# The following variables are taken from mk/defaults/mk.conf, 1.118
48 48
49ALLOW_VULNERABLE_PACKAGES Yes [$user] 49ALLOW_VULNERABLE_PACKAGES Yes [$user]
50MANINSTALL List of { maninstall catinstall } [$user] 50MANINSTALL List of { maninstall catinstall } [$user]
51MANZ Yes [$user] 51MANZ Yes [$user]
52GZIP List of ShellWord [$user] 52GZIP List of ShellWord [$user]
53MKCRYPTO YesNo [$user] 53MKCRYPTO YesNo [$user]
54OBJHOSTNAME Yes [$user] 54OBJHOSTNAME Yes [$user]
55OBJMACHINE Yes [$user] 55OBJMACHINE Yes [$user]
56PKG_SUFX Filename [$user] 56PKG_SUFX Filename [$user]
57PKGSRC_LOCKTYPE { none sleep once } [$user] 57PKGSRC_LOCKTYPE { none sleep once } [$user]
58PKGSRC_SLEEPSECS Integer [$user] 58PKGSRC_SLEEPSECS Integer [$user]
59USETBL Yes [$user] 59USETBL Yes [$user]
60ABI { 32 64 } [$user] 60ABI { 32 64 } [$user]
61PKG_DEVELOPER Yes [$user] 61PKG_DEVELOPER Yes [$user]
62USE_ABI_DEPENDS YesNo [$user] 62USE_ABI_DEPENDS YesNo [$user]
63PKG_REGISTER_SHELLS { YES NO } [$user] 63PKG_REGISTER_SHELLS { YES NO } [$user]
64PKGSRC_COMPILER List of { \ 64PKGSRC_COMPILER List of { \
65 ccache ccc clang distcc f2c gcc hp icc \ 65 ccache ccc clang distcc f2c gcc hp icc \
66 ido gcc mipspro mipspro-ucode pcc \ 66 ido gcc mipspro mipspro-ucode pcc \
67 sunpro xlc \ 67 sunpro xlc \
68 } [$user] 68 } [$user]
69PKGSRC_MESSAGE_RECIPIENTS List of Mail_Address [$user] 69PKGSRC_MESSAGE_RECIPIENTS List of Mail_Address [$user]
70PKGSRC_SHOW_BUILD_DEFS YesNo [$user] 70PKGSRC_SHOW_BUILD_DEFS YesNo [$user]
71PKGSRC_SHOW_PATCH_ERRORMSG YesNo [$user] 71PKGSRC_SHOW_PATCH_ERRORMSG YesNo [$user]
72PKGSRC_RUN_TEST YesNo [$user] 72PKGSRC_RUN_TEST YesNo [$user]
73PREFER_PKGSRC List of Identifier [$user] 73PREFER_PKGSRC List of Identifier [$user]
74PREFER_NATIVE List of Identifier [$user] 74PREFER_NATIVE List of Identifier [$user]
75PREFER_NATIVE_PTHREADS YesNo [$user] 75PREFER_NATIVE_PTHREADS YesNo [$user]
76LOCALBASE Pathname [$user] 76LOCALBASE Pathname [$user]
77CROSSBASE Pathname [$user] 77CROSSBASE Pathname [$user]
78VARBASE Pathname [$user] 78VARBASE Pathname [$user]
79X11_TYPE { modular native } [$user] 79X11_TYPE { modular native } [$user]
80X11BASE Pathname [$user] 80X11BASE Pathname [$user]
81MOTIFBASE Pathname [$user] 81MOTIFBASE Pathname [$user]
82PKGINFODIR Pathname [$user] 82PKGINFODIR Pathname [$user]
83PKGMANDIR Pathname [$user] 83PKGMANDIR Pathname [$user]
84USE_XPKGWEDGE YesNo [$user] 84USE_XPKGWEDGE YesNo [$user]
85BSDSRCDIR Pathname [$user] 85BSDSRCDIR Pathname [$user]
86BSDXSRCDIR Pathname [$user] 86BSDXSRCDIR Pathname [$user]
87DISTDIR Pathname [$user] 87DISTDIR Pathname [$user]
88DIST_PATH Pathlist [$user] 88DIST_PATH Pathlist [$user]
89DEFAULT_VIEW Unchecked [$user] 89DEFAULT_VIEW Unchecked [$user]
90FETCH_CMD ShellCommand [$user] 90FETCH_CMD ShellCommand [$user]
91FETCH_USING { curl custom fetch ftp manual wget } [$user] 91FETCH_USING { curl custom fetch ftp manual wget } [$user]
92FETCH_RESUME_ARGS List of ShellWord [$user] 92FETCH_RESUME_ARGS List of ShellWord [$user]
93FETCH_OUTPUT_ARGS List of ShellWord [$user] 93FETCH_OUTPUT_ARGS List of ShellWord [$user]
94LIBTOOLIZE_PLIST YesNo [$user] 94LIBTOOLIZE_PLIST YesNo [$user]
95PKG_INSTALLATION_PREFS List of { overwrite pkgviews } [$user] 95PKG_INSTALLATION_PREFS List of { overwrite pkgviews } [$user]
96PKG_RESUME_TRANSFERS YesNo [$user] 96PKG_RESUME_TRANSFERS YesNo [$user]
97PKG_SYSCONFBASE Pathname [$user] 97PKG_SYSCONFBASE Pathname [$user]
98RCD_SCRIPTS_DIR Pathname [$user] 98RCD_SCRIPTS_DIR Pathname [$user]
99PACKAGES Pathname [$user] 99PACKAGES Pathname [$user]
100PKGVULNDIR Pathname [$user] 100PKGVULNDIR Pathname [$user]
101PASSIVE_FETCH Yes [$user] 101PASSIVE_FETCH Yes [$user]
102PATCH_FUZZ_FACTOR { -F0 -F1 -F2 -F3 } [$user] 102PATCH_FUZZ_FACTOR { -F0 -F1 -F2 -F3 } [$user]
103ACCEPTABLE_LICENSES List of Identifier [$user] 103ACCEPTABLE_LICENSES List of Identifier [$user]
104SPECIFIC_PKGS Yes [$user] 104SPECIFIC_PKGS Yes [$user]
105SITE_SPECIFIC_PKGS List of PkgPath [$user] 105SITE_SPECIFIC_PKGS List of PkgPath [$user]
106HOST_SPECIFIC_PKGS List of PkgPath [$user] 106HOST_SPECIFIC_PKGS List of PkgPath [$user]
107GROUP_SPECIFIC_PKGS List of PkgPath [$user] 107GROUP_SPECIFIC_PKGS List of PkgPath [$user]
108USER_SPECIFIC_PKGS List of PkgPath [$user] 108USER_SPECIFIC_PKGS List of PkgPath [$user]
109FAILOVER_FETCH Yes [$user] 109FAILOVER_FETCH Yes [$user]
110MASTER_SORT List of Unchecked [$user] 110MASTER_SORT List of Unchecked [$user]
111MASTER_SORT_REGEX List of Unchecked [$user] 111MASTER_SORT_REGEX List of Unchecked [$user]
112PATCH_DEBUG Yes [$user] 112PATCH_DEBUG Yes [$user]
113PKG_FC ShellCommand [$user] 113PKG_FC ShellCommand [$user]
114IMAKE ShellCommand [$user] 114IMAKE ShellCommand [$user]
115IMAKEOPTS List of ShellWord [$user] 115IMAKEOPTS List of ShellWord [$user]
116PRE_ROOT_CMD ShellCommand [$user] 116PRE_ROOT_CMD ShellCommand [$user]
117USE_GAMESGROUP YesNo [$package] 117USE_GAMESGROUP YesNo [$package]
118SU_CMD ShellCommand [$user] 118SU_CMD ShellCommand [$user]
119SU_CMD_PATH_APPEND Pathlist [$user] 119SU_CMD_PATH_APPEND Pathlist [$user]
120FATAL_OBJECT_FMT_SKEW YesNo [$user] 120FATAL_OBJECT_FMT_SKEW YesNo [$user]
121WARN_NO_OBJECT_FMT YesNo [$user] 121WARN_NO_OBJECT_FMT YesNo [$user]
122SMART_MESSAGES Yes [$user] 122SMART_MESSAGES Yes [$user]
123BINPKG_SITES List of URL [$user] 123BINPKG_SITES List of URL [$user]
124BIN_INSTALL_FLAG List of ShellWord [$user] 124BIN_INSTALL_FLAG List of ShellWord [$user]
125LOCALPATCHES Pathname [$user] 125LOCALPATCHES Pathname [$user]
126 126
127# some other variables, sorted alphabetically 127# some other variables, sorted alphabetically
128 128
129.CURDIR Pathname [$system] 129.CURDIR Pathname [$system]
130.TARGET Pathname [$system] 130.TARGET Pathname [$system]
131ALL_ENV List of ShellWord 131ALL_ENV List of ShellWord
132ALTERNATIVES_FILE Filename 132ALTERNATIVES_FILE Filename
133ALTERNATIVES_SRC List of Pathname 133ALTERNATIVES_SRC List of Pathname
134APACHE_MODULE Yes [$package] 134APACHE_MODULE Yes [$package]
135AR ShellCommand [$system] 135AR ShellCommand [$system]
136AS ShellCommand [$system] 136AS ShellCommand [$system]
137AUTOCONF_REQD List of Version [$package_list] 137AUTOCONF_REQD List of Version [$package_list]
138AUTOMAKE_OVERRIDE List of Pathmask 138AUTOMAKE_OVERRIDE List of Pathmask
139AUTOMAKE_REQD List of Version [$package_list] 139AUTOMAKE_REQD List of Version [$package_list]
140AUTO_MKDIRS YesNo [$package] 140AUTO_MKDIRS YesNo [$package]
141BATCH Yes [$user] 141BATCH Yes [$user]
142BDB185_DEFAULT Unchecked [] 142BDB185_DEFAULT Unchecked []
143BDBBASE Pathname [$system] 143BDBBASE Pathname [$system]
144BDB_ACCEPTED List of { db1 db2 db3 db4 db5 } [$package] 144BDB_ACCEPTED List of { db1 db2 db3 db4 db5 } [$package]
145BDB_DEFAULT { db1 db2 db3 db4 db5 } [] 145BDB_DEFAULT { db1 db2 db3 db4 db5 } []
146BDB_LIBS List of LdFlag [$system] 146BDB_LIBS List of LdFlag [$system]
147BDB_TYPE { db1 db2 db3 db4 db5 } [$system] 147BDB_TYPE { db1 db2 db3 db4 db5 } [$system]
148BINGRP UserGroupName [$system] 148BINGRP UserGroupName [$system]
149BINMODE FileMode [$system] 149BINMODE FileMode [$system]
150BINOWN UserGroupName [$system] 150BINOWN UserGroupName [$system]
151BOOTSTRAP_DEPENDS InternalList of DependencyWithPath [c:a,m:a,o:a,*.mk:a] 151BOOTSTRAP_DEPENDS InternalList of DependencyWithPath [c:a,m:a,o:a,*.mk:a]
152BROKEN Message [] 152BROKEN Message []
153BROKEN_GETTEXT_DETECTION YesNo [$package] 153BROKEN_GETTEXT_DETECTION YesNo [$package]
154BSD_MAKE_ENV List of ShellWord [$system] 154BSD_MAKE_ENV List of ShellWord [$system]
155BUILDLINK_ABI_DEPENDS.* InternalList of Dependency [*:a] 155BUILDLINK_ABI_DEPENDS.* InternalList of Dependency [*:a]
156BUILDLINK_API_DEPENDS.* InternalList of Dependency [*:a] 156BUILDLINK_API_DEPENDS.* InternalList of Dependency [*:a]
157BUILDLINK_CONTENTS_FILTER List of ShellWord [] 157BUILDLINK_CONTENTS_FILTER List of ShellWord []
158# ^^ ShellCommand 158# ^^ ShellCommand
159BUILDLINK_CFLAGS List of CFlag [$system] 159BUILDLINK_CFLAGS List of CFlag [$system]
160BUILDLINK_CFLAGS.* List of CFlag [$bl_list] 160BUILDLINK_CFLAGS.* List of CFlag [$bl_list]
161BUILDLINK_CPPFLAGS List of CFlag [$system] 161BUILDLINK_CPPFLAGS List of CFlag [$system]
162BUILDLINK_CPPFLAGS.* List of CFlag [$bl_list] 162BUILDLINK_CPPFLAGS.* List of CFlag [$bl_list]
163BUILDLINK_CONTENTS_FILTER.* ShellCommand [b:s] 163BUILDLINK_CONTENTS_FILTER.* ShellCommand [b:s]
164BUILDLINK_DEPENDS InternalList of Identifier [b:a] 164BUILDLINK_DEPENDS InternalList of Identifier [b:a]
165BUILDLINK_DEPMETHOD.* List of BuildlinkDepmethod [b:ad,m:as,c:a,*.mk:a] 165BUILDLINK_DEPMETHOD.* List of BuildlinkDepmethod [b:ad,m:as,c:a,*.mk:a]
166# ^^ FIXME: b:d may lead to unexpected behavior. 166# ^^ FIXME: b:d may lead to unexpected behavior.
167BUILDLINK_DEPTH BuildlinkDepth [b:ps, builtin.mk:ps] 167BUILDLINK_DEPTH BuildlinkDepth [b:ps, builtin.mk:ps]
168BUILDLINK_DIR Pathname [$system] 168BUILDLINK_DIR Pathname [$system]
169BUILDLINK_FILES.* List of Pathmask [$bl_list] 169BUILDLINK_FILES.* List of Pathmask [$bl_list]
170BUILDLINK_FILES_CMD.* List of ShellWord [] 170BUILDLINK_FILES_CMD.* List of ShellWord []
171# ^^ ShellCommand 171# ^^ ShellCommand
172BUILDLINK_INCDIRS.* List of Pathname [b:ad] # b:d? 172BUILDLINK_INCDIRS.* List of Pathname [b:ad] # b:d?
173BUILDLINK_JAVA_PREFIX.* Pathname [b:s] 173BUILDLINK_JAVA_PREFIX.* Pathname [b:s]
174BUILDLINK_LDADD.* List of LdFlag [builtin.mk:adsu, b:, m:u, c:u, *.mk:u] 174BUILDLINK_LDADD.* List of LdFlag [builtin.mk:adsu, b:, m:u, c:u, *.mk:u]
175BUILDLINK_LDFLAGS List of LdFlag [$system] 175BUILDLINK_LDFLAGS List of LdFlag [$system]
176BUILDLINK_LDFLAGS.* List of LdFlag [$bl_list] 176BUILDLINK_LDFLAGS.* List of LdFlag [$bl_list]
177BUILDLINK_LIBDIRS.* List of Pathname [$bl_list] 177BUILDLINK_LIBDIRS.* List of Pathname [$bl_list]
178BUILDLINK_LIBS.* List of LdFlag [b:a] 178BUILDLINK_LIBS.* List of LdFlag [b:a]
179BUILDLINK_PACKAGES BuildlinkPackages [b:aps] 179BUILDLINK_PACKAGES BuildlinkPackages [b:aps]
180BUILDLINK_PASSTHRU_DIRS List of Pathname [m:a,c:a,b:a,h:a] 180BUILDLINK_PASSTHRU_DIRS List of Pathname [m:a,c:a,b:a,h:a]
181BUILDLINK_PASSTHRU_RPATHDIRS List of Pathname [m:a,c:a,b:a,h:a] 181BUILDLINK_PASSTHRU_RPATHDIRS List of Pathname [m:a,c:a,b:a,h:a]
182BUILDLINK_PKGSRCDIR.* RelativePkgDir [b:dp] 182BUILDLINK_PKGSRCDIR.* RelativePkgDir [b:dp]
183BUILDLINK_PREFIX.* Pathname [builtin.mk:su, b:, m:u, c:u, *.mk:u] 183BUILDLINK_PREFIX.* Pathname [builtin.mk:su, b:, m:u, c:u, *.mk:u]
184BUILDLINK_RPATHDIRS.* List of Pathname [b:a] 184BUILDLINK_RPATHDIRS.* List of Pathname [b:a]
185BUILDLINK_TARGETS List of Identifier [] 185BUILDLINK_TARGETS List of Identifier []
186BUILDLINK_FNAME_TRANSFORM.* SedCommands [m:a,builtin.mk:a,h:a,b:a] 186BUILDLINK_FNAME_TRANSFORM.* SedCommands [m:a,builtin.mk:a,h:a,b:a]
187BUILDLINK_TRANSFORM List of WrapperTransform [*:a] 187BUILDLINK_TRANSFORM List of WrapperTransform [*:a]
188BUILDLINK_TREE List of Identifier [b:a] 188BUILDLINK_TREE List of Identifier [b:a]
189BUILD_DEFS List of Varname [m:a,c:a,o:a] 189BUILD_DEFS List of Varname [m:a,c:a,o:a]
190BUILD_DEPENDS InternalList of DependencyWithPath [c:a,m:a,o:a,*.mk:a] 190BUILD_DEPENDS InternalList of DependencyWithPath [c:a,m:a,o:a,*.mk:a]
191BUILD_DIRS List of WrksrcSubdirectory [$package_list] 191BUILD_DIRS List of WrksrcSubdirectory [$package_list]
192BUILD_ENV List of ShellWord [$package_list] 192BUILD_ENV List of ShellWord [$package_list]
193BUILD_MAKE_CMD ShellCommand [$system] 193BUILD_MAKE_CMD ShellCommand [$system]
194BUILD_MAKE_FLAGS List of ShellWord [$package_list] 194BUILD_MAKE_FLAGS List of ShellWord [$package_list]
195BUILD_TARGET List of Identifier [$package] 195BUILD_TARGET List of Identifier [$package]
196BUILD_USES_MSGFMT Yes [$package] 196BUILD_USES_MSGFMT Yes [$package]
197BUILTIN_PKG Identifier [builtin.mk:psu] 197BUILTIN_PKG Identifier [builtin.mk:psu]
198BUILTIN_PKG.* PkgName [builtin.mk:psu] 198BUILTIN_PKG.* PkgName [builtin.mk:psu]
199BUILTIN_FIND_FILES_VAR List of Varname [builtin.mk:s] 199BUILTIN_FIND_FILES_VAR List of Varname [builtin.mk:s]
200BUILTIN_FIND_FILES.* List of Pathname [builtin.mk:s] 200BUILTIN_FIND_FILES.* List of Pathname [builtin.mk:s]
201BUILTIN_FIND_GREP.* String [builtin.mk:s] 201BUILTIN_FIND_GREP.* String [builtin.mk:s]
202BUILTIN_FIND_LIBS List of Pathname [builtin.mk:s] 202BUILTIN_FIND_LIBS List of Pathname [builtin.mk:s]
203BUILTIN_IMAKE_CHECK List of Unchecked [builtin.mk:s] 203BUILTIN_IMAKE_CHECK List of Unchecked [builtin.mk:s]
204BUILTIN_IMAKE_CHECK.* YesNo [] 204BUILTIN_IMAKE_CHECK.* YesNo []
205BUILTIN_X11_TYPE Unchecked [$system] 205BUILTIN_X11_TYPE Unchecked [$system]
206BUILTIN_X11_VERSION Unchecked [$system] 206BUILTIN_X11_VERSION Unchecked [$system]
207CATEGORIES List of Category [m:as,c:ads] 207CATEGORIES List of Category [m:as,c:ads]
208CC_VERSION Message [$system] 208CC_VERSION Message [$system]
209CC ShellCommand [$system] 209CC ShellCommand [$system]
210CFLAGS* List of CFlag [$package_list] 210CFLAGS* List of CFlag [$package_list]
211# ^^ may also be changed by the user 211# ^^ may also be changed by the user
212CHECK_BUILTIN YesNo [builtin.mk:d,m:s] 212CHECK_BUILTIN YesNo [builtin.mk:d,m:s]
213CHECK_BUILTIN.* YesNo [*:p] 213CHECK_BUILTIN.* YesNo [*:p]
214CHECK_FILES_SKIP List of Pathmask [m:a,c:a] 214CHECK_FILES_SKIP List of Pathmask [m:a,c:a]
215CHECK_FILES_SUPPORTED YesNo [$package] 215CHECK_FILES_SUPPORTED YesNo [$package]
216CHECK_HEADERS YesNo [$user] 216CHECK_HEADERS YesNo [$user]
217CHECK_HEADERS_SKIP List of Pathmask [$package_list] 217CHECK_HEADERS_SKIP List of Pathmask [$package_list]
218CHECK_INTERPRETER YesNo [$user] 218CHECK_INTERPRETER YesNo [$user]
219CHECK_INTERPRETER_SKIP List of Pathmask [$package_list] 219CHECK_INTERPRETER_SKIP List of Pathmask [$package_list]
220CHECK_PERMS YesNo [$user] 220CHECK_PERMS YesNo [$user]
221CHECK_PERMS_SKIP List of Pathmask [$package_list] 221CHECK_PERMS_SKIP List of Pathmask [$package_list]
222#CHECK_PERMS_AUTOFIX YesNo [$package] 222#CHECK_PERMS_AUTOFIX YesNo [$package]
223# ^^ experimental 223# ^^ experimental
224CHECK_PORTABILITY YesNo [$user] 224CHECK_PORTABILITY YesNo [$user]
225CHECK_PORTABILITY_SKIP List of Pathmask [$package_list] 225CHECK_PORTABILITY_SKIP List of Pathmask [$package_list]
226CHECK_SHLIBS YesNo [m:s] 226CHECK_SHLIBS YesNo [m:s]
227CHECK_SHLIBS_SUPPORTED YesNo [m:s] 227CHECK_SHLIBS_SUPPORTED YesNo [m:s]
228CHECK_WRKREF_SKIP List of Pathmask [$package_list] 228CHECK_WRKREF_SKIP List of Pathmask [$package_list]
229CMAKE_ARG_PATH Pathname [$package] 229CMAKE_ARG_PATH Pathname [$package]
230CMAKE_ARGS List of ShellWord [$package_list] 230CMAKE_ARGS List of ShellWord [$package_list]
231COMMENT Comment [m:as,c:as] 231COMMENT Comment [m:as,c:as]
232COMPILER_RPATH_FLAG { -Wl,-rpath } [$system] 232COMPILER_RPATH_FLAG { -Wl,-rpath } [$system]
233CONFIGURE_ARGS List of ShellWord [$package_list] 233CONFIGURE_ARGS List of ShellWord [$package_list]
234CONFIGURE_DIRS List of WrksrcSubdirectory [$package_list] 234CONFIGURE_DIRS List of WrksrcSubdirectory [$package_list]
235CONFIGURE_ENV List of ShellWord [$package_list] 235CONFIGURE_ENV List of ShellWord [$package_list]
236CONFIGURE_HAS_INFODIR YesNo [$package] 236CONFIGURE_HAS_INFODIR YesNo [$package]
237CONFIGURE_HAS_MANDIR YesNo [$package] 237CONFIGURE_HAS_MANDIR YesNo [$package]
238CONFIGURE_SCRIPT Pathname [$package] 238CONFIGURE_SCRIPT Pathname [$package]
239CONFIG_GUESS_OVERRIDE List of Pathmask [m:as,c:as] 239CONFIG_GUESS_OVERRIDE List of Pathmask [m:as,c:as]
240CONFIG_STATUS_OVERRIDE List of Pathmask [m:as,c:as] 240CONFIG_STATUS_OVERRIDE List of Pathmask [m:as,c:as]
241CONFIG_SHELL Pathname [m:s,c:s] 241CONFIG_SHELL Pathname [m:s,c:s]
242CONFIG_SUB_OVERRIDE List of Pathmask [m:as,c:as] 242CONFIG_SUB_OVERRIDE List of Pathmask [m:as,c:as]
243CONFLICTS InternalList of Dependency [$package_list] 243CONFLICTS InternalList of Dependency [$package_list]
244CONF_FILES List of ShellWord [$package_list] 244CONF_FILES List of ShellWord [$package_list]
245CONF_FILES_MODE { 0644 0640 0600 0400 } [$package] 245CONF_FILES_MODE { 0644 0640 0600 0400 } [$package]
246CONF_FILES_PERMS List of ShellWord [$package_list] 246CONF_FILES_PERMS List of ShellWord [$package_list]
247COPY { -c } [$system] 247COPY { -c } [$system]
248# ^^ the flag that tells ${INSTALL} to copy a file 248# ^^ the flag that tells ${INSTALL} to copy a file
249CPP ShellCommand [$system] 249CPP ShellCommand [$system]
250CPPFLAGS* List of CFlag [$package_list] 250CPPFLAGS* List of CFlag [$package_list]
251CRYPTO Yes [m:s] 251CRYPTO Yes [m:s]
252CXX ShellCommand [$system] 252CXX ShellCommand [$system]
253CXXFLAGS* List of CFlag [$package_list] 253CXXFLAGS* List of CFlag [$package_list]
254DEINSTALL_FILE Pathname [m:s] 254DEINSTALL_FILE Pathname [m:s]
255DEINSTALL_SRC List of Pathname [m:s,c:ds] 255DEINSTALL_SRC List of Pathname [m:s,c:ds]
256DEINSTALL_TEMPLATES List of Pathname [m:as,c:ads] 256DEINSTALL_TEMPLATES List of Pathname [m:as,c:ads]
257DELAYED_ERROR_MSG ShellCommand [$system] 257DELAYED_ERROR_MSG ShellCommand [$system]
258DELAYED_WARNING_MSG ShellCommand [$system] 258DELAYED_WARNING_MSG ShellCommand [$system]
259DEPENDS InternalList of DependencyWithPath [$package_list] 259DEPENDS InternalList of DependencyWithPath [$package_list]
260DEPENDS_TARGET List of Identifier [$user] 260DEPENDS_TARGET List of Identifier [$user]
261DESCR_SRC List of Pathname [m:s,c:ds] 261DESCR_SRC List of Pathname [m:s,c:ds]
262DESTDIR Pathname [$system] 262DESTDIR Pathname [$system]
263DEVOSSAUDIO Pathname [$system] 263DEVOSSAUDIO Pathname [$system]
264DEVOSSSOUND Pathname [$system] 264DEVOSSSOUND Pathname [$system]
265DISTFILES List of Filename [$package_list] 265DISTFILES List of Filename [$package_list]
266DISTINFO_FILE RelativePkgPath [$package] 266DISTINFO_FILE RelativePkgPath [$package]
267DISTNAME Filename [$package] 267DISTNAME Filename [$package]
268DIST_SUBDIR Pathname [$package] 268DIST_SUBDIR Pathname [$package]
269DJB_BUILD_ARGS List of ShellWord 269DJB_BUILD_ARGS List of ShellWord
270DJB_BUILD_TARGETS List of Identifier 270DJB_BUILD_TARGETS List of Identifier
271DJB_CONFIG_CMDS List of ShellWord [o:s] 271DJB_CONFIG_CMDS List of ShellWord [o:s]
272# ^^ ShellCommand, terminated by a semicolon 272# ^^ ShellCommand, terminated by a semicolon
273DJB_CONFIG_DIRS List of WrksrcSubdirectory 273DJB_CONFIG_DIRS List of WrksrcSubdirectory
274DJB_CONFIG_HOME Filename 274DJB_CONFIG_HOME Filename
275DJB_CONFIG_PREFIX Pathname 275DJB_CONFIG_PREFIX Pathname
276DJB_INSTALL_TARGETS List of Identifier 276DJB_INSTALL_TARGETS List of Identifier
277DJB_MAKE_TARGETS YesNo 277DJB_MAKE_TARGETS YesNo
278DJB_RESTRICTED YesNo [m:s] 278DJB_RESTRICTED YesNo [m:s]
279DJB_SLASHPACKAGE YesNo 279DJB_SLASHPACKAGE YesNo
280DLOPEN_REQUIRE_PTHREADS YesNo 280DLOPEN_REQUIRE_PTHREADS YesNo
281DL_AUTO_VARS Yes [m:s,c:s,o:s] 281DL_AUTO_VARS Yes [m:s,c:s,o:s]
282DL_LIBS List of LdFlag 282DL_LIBS List of LdFlag
283DOCOWN UserGroupName [$system] 283DOCOWN UserGroupName [$system]
284DOCGRP UserGroupName [$system] 284DOCGRP UserGroupName [$system]
285DOCMODE FileMode [$system] 285DOCMODE FileMode [$system]
286DOWNLOADED_DISTFILE Pathname [$system] 286DOWNLOADED_DISTFILE Pathname [$system]
287DO_NADA ShellCommand [$system] 287DO_NADA ShellCommand [$system]
288DYNAMIC_SITES_CMD ShellCommand [$package] 288DYNAMIC_SITES_CMD ShellCommand [$package]
289DYNAMIC_SITES_SCRIPT Pathname [$package] 289DYNAMIC_SITES_SCRIPT Pathname [$package]
290ECHO ShellCommand [$system] 290ECHO ShellCommand [$system]
291ECHO_MSG ShellCommand [$system] 291ECHO_MSG ShellCommand [$system]
292ECHO_N ShellCommand [$system] 292ECHO_N ShellCommand [$system]
293EGDIR Pathname [$package] 293EGDIR Pathname [$package]
294# ^^ This variable is not defined by the system, but has been established 294# ^^ This variable is not defined by the system, but has been established
295# as a convention. 295# as a convention.
296EMACS_BIN Pathname [$system] 296EMACS_BIN Pathname [$system]
297EMACS_ETCPREFIX Pathname [$system] 297EMACS_ETCPREFIX Pathname [$system]
298EMACS_FLAVOR { emacs xemacs } [$system] 298EMACS_FLAVOR { emacs xemacs } [$system]
299EMACS_INFOPREFIX Pathname [$system] 299EMACS_INFOPREFIX Pathname [$system]
300EMACS_LISPPREFIX Pathname [$system] 300EMACS_LISPPREFIX Pathname [$system]
301EMACS_MODULES List of Identifier [m:as,c:as] 301EMACS_MODULES List of Identifier [m:as,c:as]
302EMACS_PKGNAME_PREFIX Identifier [$system] 302EMACS_PKGNAME_PREFIX Identifier [$system]
303# ^^ or the empty string. 303# ^^ or the empty string.
304EMACS_TYPE { emacs xemacs } [$system] 304EMACS_TYPE { emacs xemacs } [$system]
305EMACS_USE_LEIM Yes 305EMACS_USE_LEIM Yes
306EMACS_VERSIONS_ACCEPTED List of { emacs24 emacs24nox emacs23 emacs23nox emacs22 emacs22nox emacs21 emacs21nox emacs20 xemacs215 xemacs214 } [m:s] 306EMACS_VERSIONS_ACCEPTED List of { emacs24 emacs24nox emacs23 emacs23nox emacs22 emacs22nox emacs21 emacs21nox emacs20 xemacs215 xemacs214 } [m:s]
307EMACS_VERSION_MAJOR Integer [$system] 307EMACS_VERSION_MAJOR Integer [$system]
308EMACS_VERSION_MINOR Integer [$system] 308EMACS_VERSION_MINOR Integer [$system]
309EMACS_VERSION_REQD List of { emacs24 emacs24nox emacs23 emacs23nox emacs22 emacs22nox emacs21 emacs21nox emacs20 xemacs215 xemacs214 } [m:as] 309EMACS_VERSION_REQD List of { emacs24 emacs24nox emacs23 emacs23nox emacs22 emacs22nox emacs21 emacs21nox emacs20 xemacs215 xemacs214 } [m:as]
310EMULDIR Pathname [$system] 310EMULDIR Pathname [$system]
311EMULSUBDIR Pathname [$system] 311EMULSUBDIR Pathname [$system]
312OPSYS_EMULDIR Pathname [$system] 312OPSYS_EMULDIR Pathname [$system]
313EMULSUBDIRSLASH Pathname [$system] 313EMULSUBDIRSLASH Pathname [$system]
314EMUL_ARCH { i386 none } [$system] 314EMUL_ARCH { i386 none } [$system]
315EMUL_DISTRO Identifier [$system] 315EMUL_DISTRO Identifier [$system]
316EMUL_IS_NATIVE Yes [$system] 316EMUL_IS_NATIVE Yes [$system]
317EMUL_MODULES.* List of Identifier [$package] 317EMUL_MODULES.* List of Identifier [$package]
318EMUL_OPSYS { linux } [$system] 318EMUL_OPSYS { linux } [$system]
319EMUL_PKG_FMT { plain rpm } [$package] 319EMUL_PKG_FMT { plain rpm } [$package]
320EMUL_PLATFORM EmulPlatform [$user] 320EMUL_PLATFORM EmulPlatform [$user]
321EMUL_PLATFORMS List of EmulPlatform [$package] 321EMUL_PLATFORMS List of EmulPlatform [$package]
322EMUL_PREFER List of EmulPlatform [$user] 322EMUL_PREFER List of EmulPlatform [$user]
323EMUL_REQD InternalList of Dependency [$package] 323EMUL_REQD InternalList of Dependency [$package]
324EMUL_TYPE.* { native builtin suse suse-9.1 suse-9.x suse-10.0 suse-10.x } [$user] 324EMUL_TYPE.* { native builtin suse suse-9.1 suse-9.x suse-10.0 suse-10.x } [$user]
325ERROR_CAT ShellCommand [$system] 325ERROR_CAT ShellCommand [$system]
326ERROR_MSG ShellCommand [$system] 326ERROR_MSG ShellCommand [$system]
327EVAL_PREFIX InternalList of ShellWord [m:a,c:a] 327EVAL_PREFIX InternalList of ShellWord [m:a,c:a]
328# ^^ FIXME: Looks like a type mismatch. 328# ^^ FIXME: Looks like a type mismatch.
329EXPORT_SYMBOLS_LDFLAGS List of LdFlag [$system] 329EXPORT_SYMBOLS_LDFLAGS List of LdFlag [$system]
330EXTRACT_CMD ShellCommand [$system] 330EXTRACT_CMD ShellCommand [$system]
331EXTRACT_DIR Pathname [$package] 331EXTRACT_DIR Pathname [$package]
332EXTRACT_ELEMENTS List of Pathmask [$package_list] 332EXTRACT_ELEMENTS List of Pathmask [$package_list]
333EXTRACT_ONLY List of Pathname [$package_list] 333EXTRACT_ONLY List of Pathname [$package_list]
334EXTRACT_OPTS List of ShellWord [m:as,c:as] 334EXTRACT_OPTS List of ShellWord [m:as,c:as]
335EXTRACT_OPTS_BIN List of ShellWord [m:as,c:as] 335EXTRACT_OPTS_BIN List of ShellWord [m:as,c:as]
336EXTRACT_OPTS_LHA List of ShellWord [m:as,c:as] 336EXTRACT_OPTS_LHA List of ShellWord [m:as,c:as]
337EXTRACT_OPTS_PAX List of ShellWord [m:as,c:as] 337EXTRACT_OPTS_PAX List of ShellWord [m:as,c:as]
338EXTRACT_OPTS_RAR List of ShellWord [m:as,c:as] 338EXTRACT_OPTS_RAR List of ShellWord [m:as,c:as]
339EXTRACT_OPTS_TAR List of ShellWord [m:as,c:as] 339EXTRACT_OPTS_TAR List of ShellWord [m:as,c:as]
340EXTRACT_OPTS_ZIP List of ShellWord [m:as,c:as] 340EXTRACT_OPTS_ZIP List of ShellWord [m:as,c:as]
341EXTRACT_OPTS_ZOO List of ShellWord [m:as,c:as] 341EXTRACT_OPTS_ZOO List of ShellWord [m:as,c:as]
342EXTRACT_SUFX DistSuffix [$package] 342EXTRACT_SUFX DistSuffix [$package]
343EXTRACT_USING { bsdtar gtar nbtar pax } [$package] 343EXTRACT_USING { bsdtar gtar nbtar pax } [$package]
344FAIL_MSG ShellCommand [$system] 344FAIL_MSG ShellCommand [$system]
345FAMBASE Pathname [$system] 345FAMBASE Pathname [$system]
346FAM_ACCEPTED List of { fam gamin } [$package] 346FAM_ACCEPTED List of { fam gamin } [$package]
347FAM_DEFAULT { fam gamin } [$user] 347FAM_DEFAULT { fam gamin } [$user]
348FAM_TYPE { fam gamin } [$system] 348FAM_TYPE { fam gamin } [$system]
349FETCH_BEFORE_ARGS List of ShellWord [m:as] 349FETCH_BEFORE_ARGS List of ShellWord [m:as]
350FETCH_MESSAGE List of ShellWord [$package_list] 350FETCH_MESSAGE List of ShellWord [$package_list]
351FILESDIR RelativePkgPath [$package] 351FILESDIR RelativePkgPath [$package]
352FILES_SUBST List of ShellWord [$package_list] 352FILES_SUBST List of ShellWord [$package_list]
353FILES_SUBST_SED List of ShellWord 353FILES_SUBST_SED List of ShellWord
354FIX_RPATH List of Varname [$package_list] 354FIX_RPATH List of Varname [$package_list]
355FLEX_REQD List of Version [$package_list] 355FLEX_REQD List of Version [$package_list]
356FONTS_DIRS.* List of Pathname [m:as,c:a] 356FONTS_DIRS.* List of Pathname [m:as,c:a]
357GAMEDATAMODE FileMode [$system] 357GAMEDATAMODE FileMode [$system]
358GAMES_GROUP UserGroupName [$system] 358GAMES_GROUP UserGroupName [$system]
359GAMEMODE FileMode [$system] 359GAMEMODE FileMode [$system]
360GAMES_USER UserGroupName [$system] 360GAMES_USER UserGroupName [$system]
361GCC_REQD List of Version [$package_list] 361GCC_REQD List of Version [$package_list]
362GENERATE_PLIST List of ShellWord [$package_list] 362GENERATE_PLIST List of ShellWord [$package_list]
363# ^^ List of Shellcommand, terminated with a semicolon 363# ^^ List of Shellcommand, terminated with a semicolon
364GNU_ARCH { mips } 364GNU_ARCH { mips }
365GNU_CONFIGURE Yes [c:s,m:s] 365GNU_CONFIGURE Yes [c:s,m:s]
366GNU_CONFIGURE_MANDIR Pathname [m:s,c:s] 366GNU_CONFIGURE_MANDIR Pathname [m:s,c:s]
367GNU_CONFIGURE_PREFIX Pathname [m:s] 367GNU_CONFIGURE_PREFIX Pathname [m:s]
368HAS_CONFIGURE Yes [m:s,c:s] 368HAS_CONFIGURE Yes [m:s,c:s]
369HEADER_TEMPLATES List of Pathname [$package_list] 369HEADER_TEMPLATES List of Pathname [$package_list]
370HOMEPAGE URL [$package] 370HOMEPAGE URL [$package]
371IGNORE_PKG.* Yes [*:sp] 371IGNORE_PKG.* Yes [*:sp]
372INCOMPAT_CURSES InternalList of PlatformTriple [m:as] 372INCOMPAT_CURSES InternalList of PlatformTriple [m:as]
373INCOMPAT_ICONV InternalList of PlatformTriple 373INCOMPAT_ICONV InternalList of PlatformTriple
374INFO_DIR Pathname 374INFO_DIR Pathname
375# ^^ relative to PREFIX 375# ^^ relative to PREFIX
376INFO_FILES Yes [$package] 376INFO_FILES Yes [$package]
377INSTALL ShellCommand [$system] 377INSTALL ShellCommand [$system]
378INSTALLATION_DIRS List of PrefixPathname [$package_list] 378INSTALLATION_DIRS List of PrefixPathname [$package_list]
379INSTALLATION_DIRS_FROM_PLIST Yes [$package] 379INSTALLATION_DIRS_FROM_PLIST Yes [$package]
380INSTALL_DATA ShellCommand [$system] 380INSTALL_DATA ShellCommand [$system]
381INSTALL_DATA_DIR ShellCommand [$system] 381INSTALL_DATA_DIR ShellCommand [$system]
382INSTALL_DIRS List of WrksrcSubdirectory [$package_list] 382INSTALL_DIRS List of WrksrcSubdirectory [$package_list]
383INSTALL_ENV List of ShellWord [$package_list] 383INSTALL_ENV List of ShellWord [$package_list]
384INSTALL_FILE Pathname [m:s] 384INSTALL_FILE Pathname [m:s]
385INSTALL_GAME ShellCommand [$system] 385INSTALL_GAME ShellCommand [$system]
386INSTALL_GAME_DATA ShellCommand [$system] 386INSTALL_GAME_DATA ShellCommand [$system]
387INSTALL_LIB ShellCommand [$system] 387INSTALL_LIB ShellCommand [$system]
388INSTALL_LIB_DIR ShellCommand [$system] 388INSTALL_LIB_DIR ShellCommand [$system]
389INSTALL_MAKE_FLAGS List of ShellWord [$package_list] 389INSTALL_MAKE_FLAGS List of ShellWord [$package_list]
390INSTALL_MAN ShellCommand [$system] 390INSTALL_MAN ShellCommand [$system]
391INSTALL_MAN_DIR ShellCommand [$system] 391INSTALL_MAN_DIR ShellCommand [$system]
392INSTALL_PROGRAM ShellCommand [$system] 392INSTALL_PROGRAM ShellCommand [$system]
393INSTALL_PROGRAM_DIR ShellCommand [$system] 393INSTALL_PROGRAM_DIR ShellCommand [$system]
394INSTALL_SCRIPT ShellCommand [$system] 394INSTALL_SCRIPT ShellCommand [$system]
395INSTALL_SCRIPTS_ENV List of ShellWord 395INSTALL_SCRIPTS_ENV List of ShellWord
396INSTALL_SCRIPT_DIR ShellCommand [$system] 396INSTALL_SCRIPT_DIR ShellCommand [$system]
397INSTALL_SRC List of Pathname [m:s,c:ds] 397INSTALL_SRC List of Pathname [m:s,c:ds]
398INSTALL_TARGET List of Identifier [$package] 398INSTALL_TARGET List of Identifier [$package]
399INSTALL_TEMPLATES List of Pathname [m:as,c:ads] 399INSTALL_TEMPLATES List of Pathname [m:as,c:ads]
400INSTALL_UNSTRIPPED YesNo [m:s,c:s] 400INSTALL_UNSTRIPPED YesNo [m:s,c:s]
401INTERACTIVE_STAGE List of { fetch extract configure build install } [$package] 401INTERACTIVE_STAGE List of { fetch extract configure build install } [$package]
402IS_BUILTIN.* YesNo_Indirectly [builtin.mk:psu] 402IS_BUILTIN.* YesNo_Indirectly [builtin.mk:psu]
403JAVA_BINPREFIX Pathname [$system] 403JAVA_BINPREFIX Pathname [$system]
404JAVA_CLASSPATH ShellWord [$package] 404JAVA_CLASSPATH ShellWord [$package]
405JAVA_HOME Pathname [$package] 405JAVA_HOME Pathname [$package]
406JAVA_NAME Filename [$package] 406JAVA_NAME Filename [$package]
407JAVA_UNLIMIT List of { cmdsize datasize stacksize } [$package_list] 407JAVA_UNLIMIT List of { cmdsize datasize stacksize } [$package_list]
408JAVA_WRAPPERS InternalList of Filename [$package_list] 408JAVA_WRAPPERS InternalList of Filename [$package_list]
409JAVA_WRAPPER_BIN.* Pathname [$package] 409JAVA_WRAPPER_BIN.* Pathname [$package]
410KRB5BASE Pathname [$system] 410KRB5BASE Pathname [$system]
411KRB5_ACCEPTED List of { heimdal mit-krb5 } 411KRB5_ACCEPTED List of { heimdal mit-krb5 }
412KRB5_DEFAULT { heimdal mit-krb5 } [$user] 412KRB5_DEFAULT { heimdal mit-krb5 } [$user]
413KRB5_TYPE Unchecked [$system] 413KRB5_TYPE Unchecked [$system]
414LD ShellCommand [$system] 414LD ShellCommand [$system]
415LDFLAGS* List of LdFlag [$package_list] 415LDFLAGS* List of LdFlag [$package_list]
416LIBGRP UserGroupName [$system] 416LIBGRP UserGroupName [$system]
417LIBMODE FileMode [$system] 417LIBMODE FileMode [$system]
418LIBOWN UserGroupName [$system] 418LIBOWN UserGroupName [$system]
419LIBOSSAUDIO Pathname [$system] 419LIBOSSAUDIO Pathname [$system]
420LIBS* List of LdFlag [$package_list] 420LIBS* List of LdFlag [$package_list]
421LIBTOOL ShellCommand [$system] 421LIBTOOL ShellCommand [$system]
422LIBTOOL_OVERRIDE List of Pathmask [m:as] 422LIBTOOL_OVERRIDE List of Pathmask [m:as]
423LICENCE License [m:s,c:s,o:s] 423LICENCE License [m:s,c:s,o:s]
424LICENSE License [m:s,c:s,o:s] 424LICENSE License [m:s,c:s,o:s]
425LICENSE_FILE Pathname [$package] 425LICENSE_FILE Pathname [$package]
426LINKER_RPATH_FLAG ShellWord [$system] 426LINKER_RPATH_FLAG ShellWord [$system]
427LOWER_OPSYS Identifier [$system] 427LOWER_OPSYS Identifier [$system]
428LTCONFIG_OVERRIDE List of Pathmask [m:as,c:a] 428LTCONFIG_OVERRIDE List of Pathmask [m:as,c:a]
429MACHINE_ARCH Identifier [$system] 429MACHINE_ARCH Identifier [$system]
430MACHINE_GNU_PLATFORM PlatformTriple [$system] 430MACHINE_GNU_PLATFORM PlatformTriple [$system]
431MAINTAINER Mail_Address [m:s,c:d] 431MAINTAINER Mail_Address [m:s,c:d]
432MAKE ShellCommand [$system] 432MAKE ShellCommand [$system]
433MAKEFLAGS List of ShellWord [$package_list] 433MAKEFLAGS List of ShellWord [$package_list]
434MAKEVARS List of Varname [builtin.mk:a,b:a,h:a] 434MAKEVARS List of Varname [builtin.mk:a,b:a,h:a]
435MAKE_DIRS List of Pathname [$package_list] 435MAKE_DIRS List of Pathname [$package_list]
436MAKE_DIRS_PERMS List of ShellWord [$package_list] 436MAKE_DIRS_PERMS List of ShellWord [$package_list]
437MAKE_ENV List of ShellWord [$package_list] 437MAKE_ENV List of ShellWord [$package_list]
438MAKE_FILE Pathname [$package] 438MAKE_FILE Pathname [$package]
439MAKE_FLAGS List of ShellWord [$package_list] 439MAKE_FLAGS List of ShellWord [$package_list]
440MAKE_JOBS Integer [$user] 440MAKE_JOBS Integer [$user]
441MAKE_JOBS_SAFE YesNo [$package] 441MAKE_JOBS_SAFE YesNo [$package]
442MAKE_PROGRAM ShellCommand [$package] 442MAKE_PROGRAM ShellCommand [$package]
443MANCOMPRESSED YesNo [m:s,c:ds] 443MANCOMPRESSED YesNo [m:s,c:ds]
444MANCOMPRESSED_IF_MANZ Yes [m:s,c:ds] 444MANCOMPRESSED_IF_MANZ Yes [m:s,c:ds]
445MANGRP UserGroupName [$system] 445MANGRP UserGroupName [$system]
446MANMODE FileMode [$system] 446MANMODE FileMode [$system]
447MANOWN UserGroupName [$system] 447MANOWN UserGroupName [$system]
448MASTER_SITES List of URL [$package_list] 448MASTER_SITES List of URL [$package_list]
449MASTER_SITE_APACHE List of URL [$system] 449MASTER_SITE_APACHE List of URL [$system]
450MASTER_SITE_BACKUP List of URL [$system] 450MASTER_SITE_BACKUP List of URL [$system]
451MASTER_SITE_CYGWIN List of URL [$system] 451MASTER_SITE_CYGWIN List of URL [$system]
452MASTER_SITE_DEBIAN List of URL [$system] 452MASTER_SITE_DEBIAN List of URL [$system]
453MASTER_SITE_FREEBSD List of URL [$system] 453MASTER_SITE_FREEBSD List of URL [$system]
454MASTER_SITE_FREEBSD_LOCAL List of URL [$system] 454MASTER_SITE_FREEBSD_LOCAL List of URL [$system]
455MASTER_SITE_GENTOO List of URL [$system] 455MASTER_SITE_GENTOO List of URL [$system]
456MASTER_SITE_GNOME List of URL [$system] 456MASTER_SITE_GNOME List of URL [$system]
457MASTER_SITE_GNU List of URL [$system] 457MASTER_SITE_GNU List of URL [$system]
458MASTER_SITE_GNUSTEP List of URL [$system] 458MASTER_SITE_GNUSTEP List of URL [$system]
459MASTER_SITE_IFARCHIVE List of URL [$system] 459MASTER_SITE_IFARCHIVE List of URL [$system]
460MASTER_SITE_KDE List of URL [$system] 460MASTER_SITE_KDE List of URL [$system]
461MASTER_SITE_LOCAL List of URL [$system] 461MASTER_SITE_LOCAL List of URL [$system]
462MASTER_SITE_MOZILLA List of URL [$system] 462MASTER_SITE_MOZILLA List of URL [$system]
463MASTER_SITE_MYSQL List of URL [$system] 463MASTER_SITE_MYSQL List of URL [$system]
464MASTER_SITE_OPENOFFICE List of URL [$system] 464MASTER_SITE_OPENOFFICE List of URL [$system]
465MASTER_SITE_PERL_CPAN List of URL [$system] 465MASTER_SITE_PERL_CPAN List of URL [$system]
466MASTER_SITE_R_CRAN List of URL [$system] 466MASTER_SITE_R_CRAN List of URL [$system]
467MASTER_SITE_SOURCEFORGE List of URL [$system] 467MASTER_SITE_SOURCEFORGE List of URL [$system]
468MASTER_SITE_SOURCEFORGE_JP List of URL [$system] 468MASTER_SITE_SOURCEFORGE_JP List of URL [$system]
469MASTER_SITE_SUNSITE List of URL [$system] 469MASTER_SITE_SUNSITE List of URL [$system]
470MASTER_SITE_SUSE List of URL [$system] 470MASTER_SITE_SUSE List of URL [$system]
471MASTER_SITE_TEX_CTAN List of URL [$system] 471MASTER_SITE_TEX_CTAN List of URL [$system]
472MASTER_SITE_XCONTRIB List of URL [$system] 472MASTER_SITE_XCONTRIB List of URL [$system]
473MASTER_SITE_XEMACS List of URL [$system] 473MASTER_SITE_XEMACS List of URL [$system]
474MESSAGE_SRC List of Pathname [$package_list] 474MESSAGE_SRC List of Pathname [$package_list]
475MESSAGE_SUBST List of ShellWord [c:a,m:a,o:a] 475MESSAGE_SUBST List of ShellWord [c:a,m:a,o:a]
476META_PACKAGE Yes [$package] 476META_PACKAGE Yes [$package]
477MISSING_FEATURES List of Identifier [$system] 477MISSING_FEATURES List of Identifier [$system]
478MYSQL_VERSIONS_ACCEPTED List of { 40 41 50 51 55 } [m:s] 478MYSQL_VERSIONS_ACCEPTED List of { 40 41 50 51 55 } [m:s]
479MYSQL_VERSION_DEFAULT Version [$user] 479MYSQL_VERSION_DEFAULT Version [$user]
480NM ShellCommand [$system] 480NM ShellCommand [$system]
481NONBINMODE FileMode [$system] 481NONBINMODE FileMode [$system]
482NOT_FOR_COMPILER List of { ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc } [$package] 482NOT_FOR_COMPILER List of { ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc } [$package]
483NOT_FOR_PLATFORM InternalList of PlatformTriple [$package_list] 483NOT_FOR_PLATFORM InternalList of PlatformTriple [$package_list]
484NOT_FOR_UNPRIVILEGED YesNo [$package] 484NOT_FOR_UNPRIVILEGED YesNo [$package]
485NO_BIN_ON_CDROM Restricted [m:s,c:s] 485NO_BIN_ON_CDROM Restricted [m:s,c:s]
486NO_BIN_ON_FTP Restricted [m:s,c:s] 486NO_BIN_ON_FTP Restricted [m:s,c:s]
487NO_BUILD Yes [m:s,c:s,Makefile.*:ds] 487NO_BUILD Yes [m:s,c:s,Makefile.*:ds]
488NO_CHECKSUM Yes [$package] 488NO_CHECKSUM Yes [$package]
489NO_CONFIGURE Yes [$package] 489NO_CONFIGURE Yes [$package]
490NO_EXPORT_CPP Yes [m:s] 490NO_EXPORT_CPP Yes [m:s]
491NO_EXTRACT Yes [$package] 491NO_EXTRACT Yes [$package]
492NO_INSTALL_MANPAGES Yes [$package] 492NO_INSTALL_MANPAGES Yes [$package]
493# ^^ only has an effect for Imake packages. 493# ^^ only has an effect for Imake packages.
494NO_PKGTOOLS_REQD_CHECK Yes [m:s] 494NO_PKGTOOLS_REQD_CHECK Yes [m:s]
495NO_SRC_ON_CDROM Restricted [m:s,c:s] 495NO_SRC_ON_CDROM Restricted [m:s,c:s]
496NO_SRC_ON_FTP Restricted [m:s,c:s] 496NO_SRC_ON_FTP Restricted [m:s,c:s]
497ONLY_FOR_COMPILER List of { ccc clang gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc } [$package_list] 497ONLY_FOR_COMPILER List of { ccc clang gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc } [$package_list]
498ONLY_FOR_PLATFORM InternalList of PlatformTriple [$package_list] 498ONLY_FOR_PLATFORM InternalList of PlatformTriple [$package_list]
499ONLY_FOR_UNPRIVILEGED YesNo [$package] 499ONLY_FOR_UNPRIVILEGED YesNo [$package]
500OPSYS Identifier [$system] 500OPSYS Identifier [$system]
501OPSYSVARS List of Varname [m:a,c:a] 501OPSYSVARS List of Varname [m:a,c:a]
502OSVERSION_SPECIFIC Yes [m:s,c:s] 502OSVERSION_SPECIFIC Yes [m:s,c:s]
503OS_VERSION Version [$system] 503OS_VERSION Version [$system]
504OVERRIDE_DIRDEPTH* Integer [$package] 504OVERRIDE_DIRDEPTH* Integer [$package]
505OVERRIDE_GNU_CONFIG_SCRIPTS Yes [$package] 505OVERRIDE_GNU_CONFIG_SCRIPTS Yes [$package]
506OWNER Mail_Address [m:s,c:d] 506OWNER Mail_Address [m:s,c:d]
507OWN_DIRS List of Pathname [$package_list] 507OWN_DIRS List of Pathname [$package_list]
508OWN_DIRS_PERMS List of ShellWord [$package_list] 508OWN_DIRS_PERMS List of ShellWord [$package_list]
509PAMBASE Pathname [$system] 509PAMBASE Pathname [$system]
510PAM_ACCEPTED List of { linux-pam openpam solaris-pam } 510PAM_ACCEPTED List of { linux-pam openpam solaris-pam }
511PAM_DEFAULT { linux-pam openpam solaris-pam } [$user] 511PAM_DEFAULT { linux-pam openpam solaris-pam } [$user]
512PAM_TYPE { linux-pam openpam solaris-pam } [$system] 512PAM_TYPE { linux-pam openpam solaris-pam } [$system]
513PATCHDIR RelativePkgPath [m:s,c:ds] 513PATCHDIR RelativePkgPath [m:s,c:ds]
514PATCHFILES List of Filename [$package_list] 514PATCHFILES List of Filename [$package_list]
515PATCH_ARGS List of ShellWord 515PATCH_ARGS List of ShellWord
516PATCH_DIST_ARGS List of ShellWord [m:as] 516PATCH_DIST_ARGS List of ShellWord [m:as]
517PATCH_DIST_CAT ShellCommand 517PATCH_DIST_CAT ShellCommand
518PATCH_DIST_STRIP* ShellWord [m:s, c:s, b:, builtin.mk:, *.mk:s] 518PATCH_DIST_STRIP* ShellWord [m:s, c:s, b:, builtin.mk:, *.mk:s]
519PATCH_SITES List of URL [m:s,o:s,c:s] 519PATCH_SITES List of URL [m:s,o:s,c:s]
520PATCH_STRIP ShellWord 520PATCH_STRIP ShellWord
521PERL5_USE_PACKLIST YesNo [$package] 521PERL5_USE_PACKLIST YesNo [$package]
522PERL5_PACKLIST List of Perl5Packlist [m:s,o:sa] 522PERL5_PACKLIST List of Perl5Packlist [m:s,o:sa]
523PERL5_PACKLIST_DIR Pathname [] 523PERL5_PACKLIST_DIR Pathname []
524PGSQL_PREFIX Pathname [$system] 524PGSQL_PREFIX Pathname [$system]
525PGSQL_VERSIONS_ACCEPTED List of { 82 83 84 90 91 } 525PGSQL_VERSIONS_ACCEPTED List of { 82 83 84 90 91 }
526PGSQL_VERSION_DEFAULT Version [$user] 526PGSQL_VERSION_DEFAULT Version [$user]
527PG_LIB_EXT { dylib so } [$system] 527PG_LIB_EXT { dylib so } [$system]
528PGSQL_TYPE { postgresql81-client postgresql80-client } [$system] 528PGSQL_TYPE { postgresql81-client postgresql80-client } [$system]
529PGPKGSRCDIR Pathname [$system] 529PGPKGSRCDIR Pathname [$system]
530PHASE_MSG ShellCommand [$system] 530PHASE_MSG ShellCommand [$system]
531PHP_VERSION_REQD Version [$user] 531PHP_VERSION_REQD Version [$user]
532PKGBASE Identifier [$system] 532PKGBASE Identifier [$system]
533PKGCONFIG_OVERRIDE List of Pathmask [m:as,c:a] 533PKGCONFIG_OVERRIDE List of Pathmask [m:as,c:a]
534PKGCONFIG_OVERRIDE_STAGE Stage [$package] 534PKGCONFIG_OVERRIDE_STAGE Stage [$package]
535PKGDIR RelativePkgDir [$package] 535PKGDIR RelativePkgDir [$package]
536PKGDIRMODE FileMode [$system] 536PKGDIRMODE FileMode [$system]
537PKGLOCALEDIR Pathname [$system] 537PKGLOCALEDIR Pathname [$system]
538PKGNAME PkgName [$package] 538PKGNAME PkgName [$package]
539PKGNAME_NOREV PkgName [$system] 539PKGNAME_NOREV PkgName [$system]
540PKGPATH Pathname [$system] 540PKGPATH Pathname [$system]
541PKGREPOSITORY Unchecked [] 541PKGREPOSITORY Unchecked []
542PKGREVISION PkgRevision [m:s] 542PKGREVISION PkgRevision [m:s]
543PKGSRCDIR Pathname [$system] 543PKGSRCDIR Pathname [$system]
 544PKGSRCTOP Yes [m:s]
544PKGTOOLS_ENV List of ShellWord 545PKGTOOLS_ENV List of ShellWord
545PKGVERSION Version [$system] 546PKGVERSION Version [$system]
546PKGWILDCARD Filemask [$system] 547PKGWILDCARD Filemask [$system]
547PKG_ADMIN ShellCommand [$system] 548PKG_ADMIN ShellCommand [$system]
548PKG_APACHE { apache13 apache2 apache22 apache24 } [$system] 549PKG_APACHE { apache13 apache2 apache22 apache24 } [$system]
549PKG_APACHE_ACCEPTED List of { apache13 apache2 apache22 apache24 } [$package] 550PKG_APACHE_ACCEPTED List of { apache13 apache2 apache22 apache24 } [$package]
550PKG_APACHE_DEFAULT { apache13 apache2 apache22 apache24 } [$user] 551PKG_APACHE_DEFAULT { apache13 apache2 apache22 apache24 } [$user]
551PKG_CONFIG Yes [$user] 552PKG_CONFIG Yes [$user]
552# ^^ No, this is not the popular command from GNOME, but the setting 553# ^^ No, this is not the popular command from GNOME, but the setting
553# whether the pkgsrc user wants configuration files automatically 554# whether the pkgsrc user wants configuration files automatically
554# installed or not. 555# installed or not.
555PKG_CREATE ShellCommand [$system] 556PKG_CREATE ShellCommand [$system]
556PKG_DBDIR Pathname [$system] 557PKG_DBDIR Pathname [$system]
557PKG_DEBUG_LEVEL Integer [$cmdline] 558PKG_DEBUG_LEVEL Integer [$cmdline]
558PKG_DEFAULT_OPTIONS List of Option [$user] 559PKG_DEFAULT_OPTIONS List of Option [$user]
559PKG_DELETE ShellCommand [$system] 560PKG_DELETE ShellCommand [$system]
560PKG_DESTDIR_SUPPORT List of { destdir user-destdir } [m:s,c:s] 561PKG_DESTDIR_SUPPORT List of { destdir user-destdir } [m:s,c:s]
561PKG_FAIL_REASON List of ShellWord [$package_list] 562PKG_FAIL_REASON List of ShellWord [$package_list]
562PKG_GECOS.* Message [m:s] 563PKG_GECOS.* Message [m:s]
563PKG_GID.* Integer [m:s] 564PKG_GID.* Integer [m:s]
564PKG_GROUPS List of ShellWord [m:as] 565PKG_GROUPS List of ShellWord [m:as]
565PKG_GROUPS_VARS List of Varname [$package_list] 566PKG_GROUPS_VARS List of Varname [$package_list]
566PKG_HOME.* Pathname [m:s] 567PKG_HOME.* Pathname [m:s]
567PKG_HACKS List of Identifier [h:a] 568PKG_HACKS List of Identifier [h:a]
568PKG_INFO ShellCommand [$system] 569PKG_INFO ShellCommand [$system]
569PKG_INSTALLATION_TYPES List of { overwrite pkgviews } [m:s,c:s] 570PKG_INSTALLATION_TYPES List of { overwrite pkgviews } [m:s,c:s]
570PKG_JAVA_HOME Pathname [$system] 571PKG_JAVA_HOME Pathname [$system]
571PKG_JVM { \ 572PKG_JVM { \
572 blackdown-jdk13 \ 573 blackdown-jdk13 \
573 jdk jdk14 \ 574 jdk jdk14 \
574 kaffe \ 575 kaffe \
575 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \ 576 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \
576 openjdk7 openjdk7-bin sun-jdk7 \ 577 openjdk7 openjdk7-bin sun-jdk7 \
577 } [$system] 578 } [$system]
578PKG_JVMS_ACCEPTED List of { \ 579PKG_JVMS_ACCEPTED List of { \
579 blackdown-jdk13 \ 580 blackdown-jdk13 \
580 jdk jdk14 \ 581 jdk jdk14 \
581 kaffe \ 582 kaffe \
582 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \ 583 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \
583 openjdk7 openjdk7-bin sun-jdk7 \ 584 openjdk7 openjdk7-bin sun-jdk7 \
584 } [m:s,c:ds] 585 } [m:s,c:ds]
585PKG_JVM_DEFAULT { \ 586PKG_JVM_DEFAULT { \
586 blackdown-jdk13 \ 587 blackdown-jdk13 \
587 jdk jdk14 \ 588 jdk jdk14 \
588 kaffe \ 589 kaffe \
589 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \ 590 sun-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 \
590 openjdk7 openjdk7-bin sun-jdk7 \ 591 openjdk7 openjdk7-bin sun-jdk7 \
591 } [$user] 592 } [$user]
592PKG_LEGACY_OPTIONS List of Option 593PKG_LEGACY_OPTIONS List of Option
593PKG_LIBTOOL Pathname [m:s] 594PKG_LIBTOOL Pathname [m:s]
594PKG_OPTIONS InternalList of Option [bsd.options.mk:s,*:pu] 595PKG_OPTIONS InternalList of Option [bsd.options.mk:s,*:pu]
595PKG_OPTIONS.* InternalList of Option [$user] 596PKG_OPTIONS.* InternalList of Option [$user]
596PKG_OPTIONS_DEPRECATED_WARNINGS List of ShellWord 597PKG_OPTIONS_DEPRECATED_WARNINGS List of ShellWord
597PKG_OPTIONS_GROUP.* InternalList of Option [o:s,m:s] 598PKG_OPTIONS_GROUP.* InternalList of Option [o:s,m:s]
598PKG_OPTIONS_LEGACY_OPTS InternalList of Unchecked [m:a,c:a,o:a] 599PKG_OPTIONS_LEGACY_OPTS InternalList of Unchecked [m:a,c:a,o:a]
599PKG_OPTIONS_LEGACY_VARS InternalList of Unchecked [m:a,c:a,o:a] 600PKG_OPTIONS_LEGACY_VARS InternalList of Unchecked [m:a,c:a,o:a]
600PKG_OPTIONS_NONEMPTY_SETS InternalList of Identifier 601PKG_OPTIONS_NONEMPTY_SETS InternalList of Identifier
601PKG_OPTIONS_OPTIONAL_GROUPS InternalList of Identifier [o:as] 602PKG_OPTIONS_OPTIONAL_GROUPS InternalList of Identifier [o:as]
602PKG_OPTIONS_REQUIRED_GROUPS InternalList of Identifier [o:s,m:s] 603PKG_OPTIONS_REQUIRED_GROUPS InternalList of Identifier [o:s,m:s]
603PKG_OPTIONS_SET.* InternalList of Option 604PKG_OPTIONS_SET.* InternalList of Option
604PKG_OPTIONS_VAR PkgOptionsVar [o:s,m:s,c:s, bsd.options.mk:p] 605PKG_OPTIONS_VAR PkgOptionsVar [o:s,m:s,c:s, bsd.options.mk:p]
605PKG_PRESERVE Yes [m:s] 606PKG_PRESERVE Yes [m:s]
606PKG_SHELL Pathname [m:s,c:s] 607PKG_SHELL Pathname [m:s,c:s]
607PKG_SHELL.* Pathname [m:s,c:s] 608PKG_SHELL.* Pathname [m:s,c:s]
608PKG_SHLIBTOOL Pathname 609PKG_SHLIBTOOL Pathname
609PKG_SKIP_REASON List of ShellWord [$package_list] 610PKG_SKIP_REASON List of ShellWord [$package_list]
610PKG_SUGGESTED_OPTIONS List of Option [o:as,m:as,c:s] 611PKG_SUGGESTED_OPTIONS List of Option [o:as,m:as,c:s]
611PKG_SUPPORTED_OPTIONS List of Option [o:as,m:as,c:s] 612PKG_SUPPORTED_OPTIONS List of Option [o:as,m:as,c:s]
612PKG_SYSCONFDIR* Pathname [$package] 613PKG_SYSCONFDIR* Pathname [$package]
613PKG_SYSCONFDIR_PERMS List of ShellWord [$package_list] 614PKG_SYSCONFDIR_PERMS List of ShellWord [$package_list]
614PKG_SYSCONFBASEDIR Pathname [$system] 615PKG_SYSCONFBASEDIR Pathname [$system]
615PKG_SYSCONFSUBDIR Pathname [$package] 616PKG_SYSCONFSUBDIR Pathname [$package]
616PKG_SYSCONFVAR Identifier 617PKG_SYSCONFVAR Identifier
617# ^^ FIXME: name/type mismatch. 618# ^^ FIXME: name/type mismatch.
618PKG_UID Integer [m:s] 619PKG_UID Integer [m:s]
619PKG_USERS List of ShellWord [m:as] 620PKG_USERS List of ShellWord [m:as]
620PKG_USERS_VARS List of Varname [$package] 621PKG_USERS_VARS List of Varname [$package]
621PKG_USE_KERBEROS Yes [m:s,c:s] 622PKG_USE_KERBEROS Yes [m:s,c:s]
622#PLIST.* # has special handling code 623#PLIST.* # has special handling code
623PLIST_VARS List of Identifier [$package_list] 624PLIST_VARS List of Identifier [$package_list]
624PLIST_SRC List of RelativePkgPath [$package_list] 625PLIST_SRC List of RelativePkgPath [$package_list]
625PLIST_SUBST List of ShellWord [$package_list] 626PLIST_SUBST List of ShellWord [$package_list]
626PLIST_TYPE { dynamic static } 627PLIST_TYPE { dynamic static }
627PREPEND_PATH List of Pathname 628PREPEND_PATH List of Pathname
628PREFIX Pathname [*:u] # ??? 629PREFIX Pathname [*:u] # ???
629PREV_PKGPATH Pathname [*:u] # doesn't exist any longer 630PREV_PKGPATH Pathname [*:u] # doesn't exist any longer
630PRINT_PLIST_AWK AwkCommand [*:a] 631PRINT_PLIST_AWK AwkCommand [*:a]
631PRIVILEGED_STAGES List of { install package clean } 632PRIVILEGED_STAGES List of { install package clean }
632PTHREAD_AUTO_VARS YesNo [m:s] 633PTHREAD_AUTO_VARS YesNo [m:s]
633PTHREAD_CFLAGS List of CFlag [$system] 634PTHREAD_CFLAGS List of CFlag [$system]
634PTHREAD_LDFLAGS List of LdFlag [$system] 635PTHREAD_LDFLAGS List of LdFlag [$system]
635PTHREAD_LIBS List of LdFlag [$system] 636PTHREAD_LIBS List of LdFlag [$system]
636PTHREAD_OPTS List of { native optional require } [m:as,c:a,b:a] 637PTHREAD_OPTS List of { native optional require } [m:as,c:a,b:a]
637PTHREAD_TYPE Identifier [$system] 638PTHREAD_TYPE Identifier [$system]
638# ^^ or "native" or "none". 639# ^^ or "native" or "none".
639PY_PATCHPLIST Yes [$package] 640PY_PATCHPLIST Yes [$package]
640PYPKGPREFIX { py26 py27 py31 py32 } [*:pu, pyversion.mk:s, *:] 641PYPKGPREFIX { py26 py27 py31 py32 } [*:pu, pyversion.mk:s, *:]
641PYTHON_FOR_BUILD_ONLY Yes [$package] 642PYTHON_FOR_BUILD_ONLY Yes [$package]
642PYTHON_PATCH_SCRIPTS List of Pathmask [$package_list] 643PYTHON_PATCH_SCRIPTS List of Pathmask [$package_list]
643PYTHON_VERSIONS_ACCEPTED List of Version [$package] 644PYTHON_VERSIONS_ACCEPTED List of Version [$package]
644PYTHON_VERSIONS_INCOMPATIBLE List of Version [$package] 645PYTHON_VERSIONS_INCOMPATIBLE List of Version [$package]
645PYTHON_VERSION_DEFAULT Version [$user] 646PYTHON_VERSION_DEFAULT Version [$user]
646PYTHON_VERSION_REQD Version [$user] 647PYTHON_VERSION_REQD Version [$user]
647RANLIB ShellCommand [$system] 648RANLIB ShellCommand [$system]
648RCD_SCRIPTS List of Filename [$package_list] 649RCD_SCRIPTS List of Filename [$package_list]
649RCD_SCRIPT_SRC.* List of Pathname [m:s] 650RCD_SCRIPT_SRC.* List of Pathname [m:s]
650REPLACE.* String [m:s] 651REPLACE.* String [m:s]
651REPLACE_AWK List of Pathmask [$package_list] 652REPLACE_AWK List of Pathmask [$package_list]
652REPLACE_BASH List of Pathmask [$package_list] 653REPLACE_BASH List of Pathmask [$package_list]
653REPLACE_EMACS List of Pathmask 654REPLACE_EMACS List of Pathmask
654REPLACE_FILES.* List of Pathmask [m:as,c:as] 655REPLACE_FILES.* List of Pathmask [m:as,c:as]
655REPLACE_INTERPRETER List of Identifier [m:a,c:a] 656REPLACE_INTERPRETER List of Identifier [m:a,c:a]
656REPLACE_KSH List of Pathmask [$package_list] 657REPLACE_KSH List of Pathmask [$package_list]
657REPLACE_LOCALEDIR_PATTERNS List of Filemask [$package_list] 658REPLACE_LOCALEDIR_PATTERNS List of Filemask [$package_list]
658REPLACE_PERL List of Pathmask [$package_list] 659REPLACE_PERL List of Pathmask [$package_list]
659REPLACE_PYTHON List of Pathmask [$package_list] 660REPLACE_PYTHON List of Pathmask [$package_list]
660REPLACE_SH List of Pathmask [$package_list] 661REPLACE_SH List of Pathmask [$package_list]
661REQD_DIRS List of Pathname [$package_list] 662REQD_DIRS List of Pathname [$package_list]
662REQD_DIRS_PERMS List of ShellWord [$package_list] 663REQD_DIRS_PERMS List of ShellWord [$package_list]
663REQD_FILES List of Pathname [$package_list] 664REQD_FILES List of Pathname [$package_list]
664REQD_FILES_MODE { 0644 0640 0600 0400 } [$package] 665REQD_FILES_MODE { 0644 0640 0600 0400 } [$package]
665REQD_FILES_PERMS List of ShellWord [$package_list] 666REQD_FILES_PERMS List of ShellWord [$package_list]
666RESTRICTED Message [$package] 667RESTRICTED Message [$package]
667ROOT_USER UserGroupName [$user] 668ROOT_USER UserGroupName [$user]
668ROOT_GROUP UserGroupName [$user] 669ROOT_GROUP UserGroupName [$user]
669RUBY_VERSION_REQD Version [$user] 670RUBY_VERSION_REQD Version [$user]
670RUN ShellCommand [$system] 671RUN ShellCommand [$system]
671SCRIPTS_ENV List of ShellWord [m:a,c:a] 672SCRIPTS_ENV List of ShellWord [m:a,c:a]
672SETUID_ROOT_PERMS List of ShellWord [$user] 673SETUID_ROOT_PERMS List of ShellWord [$user]
673SHAREGRP UserGroupName [$system] 674SHAREGRP UserGroupName [$system]
674SHAREMODE FileMode [$system] 675SHAREMODE FileMode [$system]
675SHAREOWN UserGroupName [$system] 676SHAREOWN UserGroupName [$system]
676SHCOMMENT ShellCommand [$system] 677SHCOMMENT ShellCommand [$system]
677SHLIB_HANDLING { YES NO no } 678SHLIB_HANDLING { YES NO no }
678SHLIBTOOL ShellCommand [] 679SHLIBTOOL ShellCommand []
679SHLIBTOOL_OVERRIDE List of Pathmask [m:as,c:a] 680SHLIBTOOL_OVERRIDE List of Pathmask [m:as,c:a]
680SITES.* List of URL [m:asu,c:asu,o:asu] 681SITES.* List of URL [m:asu,c:asu,o:asu]
681SPECIAL_PERMS List of ShellWord [$package_list] 682SPECIAL_PERMS List of ShellWord [$package_list]
682STEP_MSG ShellCommand [$system] 683STEP_MSG ShellCommand [$system]
683SUBDIR List of Filename [Makefile:a,*:] 684SUBDIR List of Filename [Makefile:a,*:]
684SUBST_CLASSES List of Identifier [m:a,c:a,h:a,Makefile.*:a] 685SUBST_CLASSES List of Identifier [m:a,c:a,h:a,Makefile.*:a]
685SUBST_FILES.* List of Pathmask [m:as,c:as,h:as,o:as,Makefile.*:as] 686SUBST_FILES.* List of Pathmask [m:as,c:as,h:as,o:as,Makefile.*:as]
686SUBST_FILTER_CMD.* ShellCommand [m:s,c:s,h:s,o:s,Makefile.*:s] 687SUBST_FILTER_CMD.* ShellCommand [m:s,c:s,h:s,o:s,Makefile.*:s]
687SUBST_MESSAGE.* Message [m:s,c:s,h:s,o:s,Makefile.*:s] 688SUBST_MESSAGE.* Message [m:s,c:s,h:s,o:s,Makefile.*:s]
688SUBST_SED.* SedCommands [m:as,c:as,h:as,o:as,Makefile.*:as] 689SUBST_SED.* SedCommands [m:as,c:as,h:as,o:as,Makefile.*:as]
689SUBST_STAGE.* Stage [$package] 690SUBST_STAGE.* Stage [$package]
690SUBST_VARS.* List of Varname [$package_list] 691SUBST_VARS.* List of Varname [$package_list]
691SUPERSEDES InternalList of Dependency [$package_list] 692SUPERSEDES InternalList of Dependency [$package_list]
692SVR4_PKGNAME SVR4PkgName [$package] 693SVR4_PKGNAME SVR4PkgName [$package]
693TEST_DIRS List of WrksrcSubdirectory [$package_list] 694TEST_DIRS List of WrksrcSubdirectory [$package_list]
694TEST_ENV List of ShellWord [$package_list] 695TEST_ENV List of ShellWord [$package_list]
695TEST_TARGET List of Identifier [m:s,c:ds] 696TEST_TARGET List of Identifier [m:s,c:ds]
696TEX_ACCEPTED List of { teTeX1 teTeX2 teTeX3 } [m:s,c:s] 697TEX_ACCEPTED List of { teTeX1 teTeX2 teTeX3 } [m:s,c:s]
697TEX_DEPMETHOD { build run } [m:s,c:s] 698TEX_DEPMETHOD { build run } [m:s,c:s]
698TEXINFO_REQD List of Version [$package_list] 699TEXINFO_REQD List of Version [$package_list]
699TOOLS_ALIASES List of Filename [$system] 700TOOLS_ALIASES List of Filename [$system]
700TOOLS_BROKEN List of Tool [$system] 701TOOLS_BROKEN List of Tool [$system]
701TOOLS_CREATE List of Tool [$system] 702TOOLS_CREATE List of Tool [$system]
702TOOLS_DEPENDS.* InternalList of DependencyWithPath [$system] 703TOOLS_DEPENDS.* InternalList of DependencyWithPath [$system]
703TOOLS_GNU_MISSING List of Tool [$system] 704TOOLS_GNU_MISSING List of Tool [$system]
704TOOLS_NOOP List of Tool [$system] 705TOOLS_NOOP List of Tool [$system]
705TOOLS_PATH.* Pathname [$system] 706TOOLS_PATH.* Pathname [$system]
706TOOLS_PLATFORM.* ShellCommand [$system] 707TOOLS_PLATFORM.* ShellCommand [$system]
707TOUCH_FLAGS List of ShellWord [$system] 708TOUCH_FLAGS List of ShellWord [$system]
708UAC_REQD_EXECS List of PrefixPathname [$package_list] 709UAC_REQD_EXECS List of PrefixPathname [$package_list]
709UNLIMIT_RESOURCES List of { datasize stacksize memorysize } [m:as,c:a] 710UNLIMIT_RESOURCES List of { datasize stacksize memorysize } [m:as,c:a]
710UNPRIVILEGED_USER UserGroupName [$user] 711UNPRIVILEGED_USER UserGroupName [$user]
711UNPRIVILEGED_GROUP UserGroupName [$user] 712UNPRIVILEGED_GROUP UserGroupName [$user]
712UNWRAP_FILES List of Pathmask [$package_list] 713UNWRAP_FILES List of Pathmask [$package_list]
713UPDATE_TARGET List of Identifier [$user] 714UPDATE_TARGET List of Identifier [$user]
714USE_BSD_MAKEFILE Yes [$package] 715USE_BSD_MAKEFILE Yes [$package]
715USE_BUILTIN.* YesNo_Indirectly [builtin.mk:s] 716USE_BUILTIN.* YesNo_Indirectly [builtin.mk:s]
716USE_CMAKE Yes [$package] 717USE_CMAKE Yes [$package]
717USE_CROSSBASE Yes [m:s] 718USE_CROSSBASE Yes [m:s]
718USE_FEATURES List of Identifier [$package] 719USE_FEATURES List of Identifier [$package]
719USE_GNU_CONFIGURE_HOST YesNo [$package] 720USE_GNU_CONFIGURE_HOST YesNo [$package]
720USE_GNU_ICONV Yes [m:s,c:s,o:s] 721USE_GNU_ICONV Yes [m:s,c:s,o:s]
721USE_IMAKE Yes [m:s] 722USE_IMAKE Yes [m:s]
722USE_JAVA { run yes build } [$package] 723USE_JAVA { run yes build } [$package]
723USE_JAVA2 { YES yes no 1.4 1.5 6 7 } [$package] 724USE_JAVA2 { YES yes no 1.4 1.5 6 7 } [$package]
724USE_LANGUAGES List of { ada c c99 c++ fortran fortran77 java objc } [m:s,c:s,o:s] 725USE_LANGUAGES List of { ada c c99 c++ fortran fortran77 java objc } [m:s,c:s,o:s]
725USE_LIBTOOL Yes [$package] 726USE_LIBTOOL Yes [$package]
726USE_MAKEINFO Yes [$package] 727USE_MAKEINFO Yes [$package]
727USE_MSGFMT_PLURALS Yes [$package] 728USE_MSGFMT_PLURALS Yes [$package]
728USE_NCURSES Yes [$package] 729USE_NCURSES Yes [$package]
729USE_OLD_DES_API YesNo [$package] 730USE_OLD_DES_API YesNo [$package]
730USE_PKGINSTALL Yes [$package] 731USE_PKGINSTALL Yes [$package]
731USE_PKGLOCALEDIR YesNo [$package] 732USE_PKGLOCALEDIR YesNo [$package]
732USE_PKGSRC_GCC Yes [$user] 733USE_PKGSRC_GCC Yes [$user]
733USE_TOOLS List of Tool [*:a] 734USE_TOOLS List of Tool [*:a]
734USE_X11 Yes [$package] 735USE_X11 Yes [$package]
735USE_X11BASE Yes [$package] 736USE_X11BASE Yes [$package]
736WARNING_MSG ShellCommand [$system] 737WARNING_MSG ShellCommand [$system]
737WARNING_CAT ShellCommand [$system] 738WARNING_CAT ShellCommand [$system]
738WRAPPER_REORDER_CMDS List of WrapperReorder [b:a,c:a,m:a] 739WRAPPER_REORDER_CMDS List of WrapperReorder [b:a,c:a,m:a]
739WRAPPER_TRANSFORM_CMDS List of WrapperTransform [b:a,c:a,m:a] 740WRAPPER_TRANSFORM_CMDS List of WrapperTransform [b:a,c:a,m:a]
740WRKDIR Pathname [$system] 741WRKDIR Pathname [$system]
741WRKSRC WrkdirSubdirectory [$package] 742WRKSRC WrkdirSubdirectory [$package]
742X11_PKGSRCDIR.* Pathname [$system] 743X11_PKGSRCDIR.* Pathname [$system]
743X11PREFIX Pathname [$system] 744X11PREFIX Pathname [$system]
744XAW_TYPE { 3d neXtaw standard xpm } [$user] 745XAW_TYPE { 3d neXtaw standard xpm } [$user]
745XMKMF_FLAGS List of ShellWord 746XMKMF_FLAGS List of ShellWord

cvs diff -r1.857 -r1.858 pkgsrc/pkgtools/pkglint/files/Attic/pkglint.pl (switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/pkglint.pl 2013/08/15 20:30:43 1.857
+++ pkgsrc/pkgtools/pkglint/files/Attic/pkglint.pl 2013/08/31 18:14:28 1.858
@@ -1,1001 +1,1001 @@ @@ -1,1001 +1,1001 @@
1#! @PERL@ 1#! @PERL@
2# $NetBSD: pkglint.pl,v 1.857 2013/08/15 20:30:43 rillig Exp $ 2# $NetBSD: pkglint.pl,v 1.858 2013/08/31 18:14:28 rillig Exp $
3# 3#
4 4
5# pkglint - static analyzer and checker for pkgsrc packages 5# pkglint - static analyzer and checker for pkgsrc packages
6# 6#
7# Written by: 7# Written by:
8# Roland Illig <rillig@NetBSD.org> 8# Roland Illig <rillig@NetBSD.org>
9# 9#
10# Based on work by: 10# Based on work by:
11# Hubert Feyrer <hubertf@NetBSD.org> 11# Hubert Feyrer <hubertf@NetBSD.org>
12# Thorsten Frueauf <frueauf@NetBSD.org> 12# Thorsten Frueauf <frueauf@NetBSD.org>
13# Thomas Klausner <wiz@NetBSD.org> 13# Thomas Klausner <wiz@NetBSD.org>
14# and others. 14# and others.
15# 15#
16# Based on FreeBSD's portlint by: 16# Based on FreeBSD's portlint by:
17# Jun-ichiro itojun Hagino <itojun@itojun.org> 17# Jun-ichiro itojun Hagino <itojun@itojun.org>
18# Yoshishige Arai <ryo2@on.rim.or.jp> 18# Yoshishige Arai <ryo2@on.rim.or.jp>
19# 19#
20# FreeBSD Id: portlint.pl,v 1.64 1998/02/28 02:34:05 itojun Exp 20# FreeBSD Id: portlint.pl,v 1.64 1998/02/28 02:34:05 itojun Exp
21# Copyright(c) 1997 by Jun-ichiro Hagino <itojun@itojun.org>. 21# Copyright(c) 1997 by Jun-ichiro Hagino <itojun@itojun.org>.
22# All rights reserved. 22# All rights reserved.
23# Freely redistributable. Absolutely no warranty. 23# Freely redistributable. Absolutely no warranty.
24 24
25# To get an overview of the code, run: 25# To get an overview of the code, run:
26# sed -n -e 's,^\(sub .*\) {.*, \1,p' -e '/^package/p' pkglint.pl 26# sed -n -e 's,^\(sub .*\) {.*, \1,p' -e '/^package/p' pkglint.pl
27 27
28#========================================================================== 28#==========================================================================
29# Note: The @EXPORT clauses in the packages must be in a BEGIN block, 29# Note: The @EXPORT clauses in the packages must be in a BEGIN block,
30# because otherwise the names starting with an uppercase letter are not 30# because otherwise the names starting with an uppercase letter are not
31# recognized as subroutines but as file handles. 31# recognized as subroutines but as file handles.
32#========================================================================== 32#==========================================================================
33 33
34use strict; 34use strict;
35use warnings; 35use warnings;
36 36
37use PkgLint::Util; 37use PkgLint::Util;
38use PkgLint::Logging; 38use PkgLint::Logging;
39use PkgLint::SimpleMatch; 39use PkgLint::SimpleMatch;
40use PkgLint::Line; 40use PkgLint::Line;
41use PkgLint::FileUtil; 41use PkgLint::FileUtil;
42use PkgLint::Type; 42use PkgLint::Type;
43use PkgLint::VarUseContext; 43use PkgLint::VarUseContext;
44use PkgLint::SubstContext; 44use PkgLint::SubstContext;
45use PkgLint::CVS_Entry; 45use PkgLint::CVS_Entry;
46use PkgLint::Change; 46use PkgLint::Change;
47 47
48package pkglint; 48package pkglint;
49#========================================================================== 49#==========================================================================
50# This package contains the application-specific code of pkglint. 50# This package contains the application-specific code of pkglint.
51# Most subroutines in this package follow a strict naming convention: 51# Most subroutines in this package follow a strict naming convention:
52# 52#
53# The get_*() functions provide easy access to important non-trivial data 53# The get_*() functions provide easy access to important non-trivial data
54# structures that are loaded from external files and are therefore cached. 54# structures that are loaded from external files and are therefore cached.
55# 55#
56# The is_*() functions return a boolean value and have no side effects. 56# The is_*() functions return a boolean value and have no side effects.
57# 57#
58# The checkline_*() procedures check a single line for compliance with some 58# The checkline_*() procedures check a single line for compliance with some
59# rules. 59# rules.
60# 60#
61# The checklines_*() procedures check an array of lines for compliance. 61# The checklines_*() procedures check an array of lines for compliance.
62# Usually they make use of several checkline_*() procedures. 62# Usually they make use of several checkline_*() procedures.
63# 63#
64# The checkfile_*() procedures load a file and check the lines of that 64# The checkfile_*() procedures load a file and check the lines of that
65# file. Usually they make use of several checklines_*() and checkline_*() 65# file. Usually they make use of several checklines_*() and checkline_*()
66# procedures. 66# procedures.
67# 67#
68# The checkdir_*() procedures check the files of a directory and call 68# The checkdir_*() procedures check the files of a directory and call
69# checkfile_*() on them. 69# checkfile_*() on them.
70# 70#
71# Note: I have tried to order the subroutines so that there are no 71# Note: I have tried to order the subroutines so that there are no
72# back-references, that is, if you start reading the code from the top to 72# back-references, that is, if you start reading the code from the top to
73# the bottom you should not find a call to a subroutine you haven't yet 73# the bottom you should not find a call to a subroutine you haven't yet
74# seen. 74# seen.
75#========================================================================== 75#==========================================================================
76use strict; 76use strict;
77use warnings; 77use warnings;
78 78
79use Data::Dumper; 79use Data::Dumper;
80use Digest::SHA1; 80use Digest::SHA1;
81use Getopt::Long qw(:config no_ignore_case bundling require_order); 81use Getopt::Long qw(:config no_ignore_case bundling require_order);
82use Fcntl qw(:mode); 82use Fcntl qw(:mode);
83use File::Basename; 83use File::Basename;
84use File::stat; 84use File::stat;
85use Cwd; 85use Cwd;
86use pkgsrc::Dewey; 86use pkgsrc::Dewey;
87 87
88BEGIN { 88BEGIN {
89 import PkgLint::Util qw( 89 import PkgLint::Util qw(
90 array_to_hash assert 90 array_to_hash assert
91 false true dont_know doesnt_matter 91 false true dont_know doesnt_matter
92 normalize_pathname 92 normalize_pathname
93 ); 93 );
94 import PkgLint::Logging qw( 94 import PkgLint::Logging qw(
95 NO_FILE NO_LINE_NUMBER NO_LINES 95 NO_FILE NO_LINE_NUMBER NO_LINES
96 log_fatal log_error log_warning log_note log_debug 96 log_fatal log_error log_warning log_note log_debug
97 explain_error explain_warning explain_info 97 explain_error explain_warning explain_info
98 ); 98 );
99 import PkgLint::FileUtil qw( 99 import PkgLint::FileUtil qw(
100 load_file load_lines 100 load_file load_lines
101 save_autofix_changes 101 save_autofix_changes
102 ); 102 );
103 import PkgLint::Type qw( 103 import PkgLint::Type qw(
104 LK_NONE LK_INTERNAL LK_EXTERNAL 104 LK_NONE LK_INTERNAL LK_EXTERNAL
105 GUESSED NOT_GUESSED 105 GUESSED NOT_GUESSED
106 ); 106 );
107 import PkgLint::VarUseContext qw( 107 import PkgLint::VarUseContext qw(
108 VUC_TIME_UNKNOWN VUC_TIME_LOAD VUC_TIME_RUN 108 VUC_TIME_UNKNOWN VUC_TIME_LOAD VUC_TIME_RUN
109 VUC_TYPE_UNKNOWN 109 VUC_TYPE_UNKNOWN
110 VUC_SHELLWORD_UNKNOWN VUC_SHELLWORD_PLAIN VUC_SHELLWORD_DQUOT 110 VUC_SHELLWORD_UNKNOWN VUC_SHELLWORD_PLAIN VUC_SHELLWORD_DQUOT
111 VUC_SHELLWORD_SQUOT VUC_SHELLWORD_BACKT VUC_SHELLWORD_FOR 111 VUC_SHELLWORD_SQUOT VUC_SHELLWORD_BACKT VUC_SHELLWORD_FOR
112 VUC_EXTENT_UNKNOWN VUC_EXTENT_FULL VUC_EXTENT_WORD 112 VUC_EXTENT_UNKNOWN VUC_EXTENT_FULL VUC_EXTENT_WORD
113 VUC_EXTENT_WORD_PART 113 VUC_EXTENT_WORD_PART
114 ); 114 );
115} 115}
116 116
117# 117#
118# Buildtime configuration 118# Buildtime configuration
119# 119#
120 120
121use constant conf_distver => '@DISTVER@'; 121use constant conf_distver => '@DISTVER@';
122use constant conf_make => '@MAKE@'; 122use constant conf_make => '@MAKE@';
123use constant conf_datadir => '@DATADIR@'; 123use constant conf_datadir => '@DATADIR@';
124 124
125# 125#
126# Global variables that can be modified via command line options. 126# Global variables that can be modified via command line options.
127# 127#
128 128
129# The pkgsrc directory, relative to the current working directory of 129# The pkgsrc directory, relative to the current working directory of
130# pkglint. 130# pkglint.
131my $cwd_pkgsrcdir = undef; 131my $cwd_pkgsrcdir = undef;
132 132
133# The pkgsrc directory, relative to the directory that is currently 133# The pkgsrc directory, relative to the directory that is currently
134# checked. 134# checked.
135my $cur_pkgsrcdir = undef; 135my $cur_pkgsrcdir = undef;
136 136
137# 137#
138# Command Line Options 138# Command Line Options
139# 139#
140 140
141my $opt_check_ALTERNATIVES = true; 141my $opt_check_ALTERNATIVES = true;
142my $opt_check_bl3 = true; 142my $opt_check_bl3 = true;
143my $opt_check_DESCR = true; 143my $opt_check_DESCR = true;
144my $opt_check_distinfo = true; 144my $opt_check_distinfo = true;
145my $opt_check_extra = false; 145my $opt_check_extra = false;
146my $opt_check_global = false; 146my $opt_check_global = false;
147my $opt_check_INSTALL = true; 147my $opt_check_INSTALL = true;
148my $opt_check_Makefile = true; 148my $opt_check_Makefile = true;
149my $opt_check_MESSAGE = true; 149my $opt_check_MESSAGE = true;
150my $opt_check_mk = true; 150my $opt_check_mk = true;
151my $opt_check_patches = true; 151my $opt_check_patches = true;
152my $opt_check_PLIST = true; 152my $opt_check_PLIST = true;
153my (%checks) = ( 153my (%checks) = (
154 "ALTERNATIVES" => [\$opt_check_ALTERNATIVES, "check ALTERNATIVES files"], 154 "ALTERNATIVES" => [\$opt_check_ALTERNATIVES, "check ALTERNATIVES files"],
155 "bl3" => [\$opt_check_bl3, "check buildlink3 files"], 155 "bl3" => [\$opt_check_bl3, "check buildlink3 files"],
156 "DESCR" => [\$opt_check_DESCR, "check DESCR file"], 156 "DESCR" => [\$opt_check_DESCR, "check DESCR file"],
157 "distinfo" => [\$opt_check_distinfo, "check distinfo file"], 157 "distinfo" => [\$opt_check_distinfo, "check distinfo file"],
158 "extra" => [\$opt_check_extra, "check various additional files"], 158 "extra" => [\$opt_check_extra, "check various additional files"],
159 "global" => [\$opt_check_global, "inter-package checks"], 159 "global" => [\$opt_check_global, "inter-package checks"],
160 "INSTALL" => [\$opt_check_INSTALL, "check INSTALL and DEINSTALL scripts"], 160 "INSTALL" => [\$opt_check_INSTALL, "check INSTALL and DEINSTALL scripts"],
161 "Makefile" => [\$opt_check_Makefile, "check Makefiles"], 161 "Makefile" => [\$opt_check_Makefile, "check Makefiles"],
162 "MESSAGE" => [\$opt_check_MESSAGE, "check MESSAGE files"], 162 "MESSAGE" => [\$opt_check_MESSAGE, "check MESSAGE files"],
163 "mk" => [\$opt_check_mk, "check other .mk files"], 163 "mk" => [\$opt_check_mk, "check other .mk files"],
164 "patches" => [\$opt_check_patches, "check patches"], 164 "patches" => [\$opt_check_patches, "check patches"],
165 "PLIST" => [\$opt_check_PLIST, "check PLIST files"], 165 "PLIST" => [\$opt_check_PLIST, "check PLIST files"],
166); 166);
167 167
168my $opt_debug_include = false; 168my $opt_debug_include = false;
169my $opt_debug_misc = false; 169my $opt_debug_misc = false;
170my $opt_debug_patches = false; 170my $opt_debug_patches = false;
171my $opt_debug_quoting = false; 171my $opt_debug_quoting = false;
172my $opt_debug_shell = false; 172my $opt_debug_shell = false;
173my $opt_debug_tools = false; 173my $opt_debug_tools = false;
174my $opt_debug_trace = false; 174my $opt_debug_trace = false;
175my $opt_debug_unchecked = false; 175my $opt_debug_unchecked = false;
176my $opt_debug_unused = false; 176my $opt_debug_unused = false;
177my $opt_debug_vartypes = false; 177my $opt_debug_vartypes = false;
178my $opt_debug_varuse = false; 178my $opt_debug_varuse = false;
179my (%debug) = ( 179my (%debug) = (
180 "include" => [\$opt_debug_include, "included files"], 180 "include" => [\$opt_debug_include, "included files"],
181 "misc" => [\$opt_debug_misc, "all things that didn't fit elsewhere"], 181 "misc" => [\$opt_debug_misc, "all things that didn't fit elsewhere"],
182 "patches" => [\$opt_debug_patches, "the states of the patch parser"], 182 "patches" => [\$opt_debug_patches, "the states of the patch parser"],
183 "quoting" => [\$opt_debug_quoting, "additional information about quoting"], 183 "quoting" => [\$opt_debug_quoting, "additional information about quoting"],
184 "shell" => [\$opt_debug_shell, "the parsers for shell words and shell commands"], 184 "shell" => [\$opt_debug_shell, "the parsers for shell words and shell commands"],
185 "tools" => [\$opt_debug_tools, "the tools framework"], 185 "tools" => [\$opt_debug_tools, "the tools framework"],
186 "trace" => [\$opt_debug_trace, "follow subroutine calls"], 186 "trace" => [\$opt_debug_trace, "follow subroutine calls"],
187 "unchecked" => [\$opt_debug_unchecked, "show the current limitations of pkglint"], 187 "unchecked" => [\$opt_debug_unchecked, "show the current limitations of pkglint"],
188 "unused" => [\$opt_debug_unused, "unused variables"], 188 "unused" => [\$opt_debug_unused, "unused variables"],
189 "vartypes" => [\$opt_debug_vartypes, "additional type information"], 189 "vartypes" => [\$opt_debug_vartypes, "additional type information"],
190 "varuse" => [\$opt_debug_varuse, "contexts where variables are used"], 190 "varuse" => [\$opt_debug_varuse, "contexts where variables are used"],
191); 191);
192 192
193my $opt_warn_absname = true; 193my $opt_warn_absname = true;
194my $opt_warn_directcmd = true; 194my $opt_warn_directcmd = true;
195our $opt_warn_extra = false; # used by PkgLint::SubstContext 195our $opt_warn_extra = false; # used by PkgLint::SubstContext
196my $opt_warn_order = true; 196my $opt_warn_order = true;
197my $opt_warn_perm = false; 197my $opt_warn_perm = false;
198my $opt_warn_plist_depr = false; 198my $opt_warn_plist_depr = false;
199my $opt_warn_plist_sort = false; 199my $opt_warn_plist_sort = false;
200my $opt_warn_quoting = false; 200my $opt_warn_quoting = false;
201my $opt_warn_space = false; 201my $opt_warn_space = false;
202my $opt_warn_style = false; 202my $opt_warn_style = false;
203my $opt_warn_types = true; 203my $opt_warn_types = true;
204my $opt_warn_varorder = false; 204my $opt_warn_varorder = false;
205my (%warnings) = ( 205my (%warnings) = (
206 "absname" => [\$opt_warn_absname, "warn about use of absolute file names"], 206 "absname" => [\$opt_warn_absname, "warn about use of absolute file names"],
207 "directcmd" => [\$opt_warn_directcmd, "warn about use of direct command names instead of Make variables"], 207 "directcmd" => [\$opt_warn_directcmd, "warn about use of direct command names instead of Make variables"],
208 "extra" => [\$opt_warn_extra, "enable some extra warnings"], 208 "extra" => [\$opt_warn_extra, "enable some extra warnings"],
209 "order" => [\$opt_warn_order, "warn if Makefile entries are unordered"], 209 "order" => [\$opt_warn_order, "warn if Makefile entries are unordered"],
210 "perm" => [\$opt_warn_perm, "warn about unforeseen variable definition and use"], 210 "perm" => [\$opt_warn_perm, "warn about unforeseen variable definition and use"],
211 "plist-depr" => [\$opt_warn_plist_depr, "warn about deprecated paths in PLISTs"], 211 "plist-depr" => [\$opt_warn_plist_depr, "warn about deprecated paths in PLISTs"],
212 "plist-sort" => [\$opt_warn_plist_sort, "warn about unsorted entries in PLISTs"], 212 "plist-sort" => [\$opt_warn_plist_sort, "warn about unsorted entries in PLISTs"],
213 "quoting" => [\$opt_warn_quoting, "warn about quoting issues"], 213 "quoting" => [\$opt_warn_quoting, "warn about quoting issues"],
214 "space" => [\$opt_warn_space, "warn about inconsistent use of white-space"], 214 "space" => [\$opt_warn_space, "warn about inconsistent use of white-space"],
215 "style" => [\$opt_warn_style, "warn about stylistic issues"], 215 "style" => [\$opt_warn_style, "warn about stylistic issues"],
216 "types" => [\$opt_warn_types, "do some simple type checking in Makefiles"], 216 "types" => [\$opt_warn_types, "do some simple type checking in Makefiles"],
217 "varorder" => [\$opt_warn_varorder, "warn about the ordering of variables"], 217 "varorder" => [\$opt_warn_varorder, "warn about the ordering of variables"],
218); 218);
219 219
220my $opt_autofix = false; 220my $opt_autofix = false;
221my $opt_dumpmakefile = false; 221my $opt_dumpmakefile = false;
222my $opt_import = false; 222my $opt_import = false;
223my $opt_quiet = false; 223my $opt_quiet = false;
224my $opt_recursive = false; 224my $opt_recursive = false;
225my $opt_rcsidstring = "NetBSD"; 225my $opt_rcsidstring = "NetBSD";
226my (@options) = ( 226my (@options) = (
227 # [ usage-opt, usage-message, getopt-opt, getopt-action ] 227 # [ usage-opt, usage-message, getopt-opt, getopt-action ]
228 [ "-C{check,...}", "Enable or disable specific checks", 228 [ "-C{check,...}", "Enable or disable specific checks",
229 "check|C=s", 229 "check|C=s",
230 sub { 230 sub {
231 my ($opt, $val) = @_; 231 my ($opt, $val) = @_;
232 parse_multioption($val, \%checks); 232 parse_multioption($val, \%checks);
233 } ], 233 } ],
234 [ "-D{debug,...}", "Enable or disable debugging categories", 234 [ "-D{debug,...}", "Enable or disable debugging categories",
235 "debugging|D=s", 235 "debugging|D=s",
236 sub ($$) { 236 sub ($$) {
237 my ($opt, $val) = @_; 237 my ($opt, $val) = @_;
238 parse_multioption($val, \%debug); 238 parse_multioption($val, \%debug);
239 } ], 239 } ],
240 [ "-F|--autofix", "Try to automatically fix some errors (experimental)", 240 [ "-F|--autofix", "Try to automatically fix some errors (experimental)",
241 "autofix|F", \$opt_autofix ], 241 "autofix|F", \$opt_autofix ],
242 [ "-I|--dumpmakefile", "Dump the Makefile after parsing", 242 [ "-I|--dumpmakefile", "Dump the Makefile after parsing",
243 "dumpmakefile|I", \$opt_dumpmakefile ], 243 "dumpmakefile|I", \$opt_dumpmakefile ],
244 [ "-R|--rcsidstring", "Set the allowed RCS Id strings", 244 [ "-R|--rcsidstring", "Set the allowed RCS Id strings",
245 "rcsidstring|R=s", \$opt_rcsidstring ], 245 "rcsidstring|R=s", \$opt_rcsidstring ],
246 [ "-V|--version", "print the version number of pkglint", 246 [ "-V|--version", "print the version number of pkglint",
247 "version|V", 247 "version|V",
248 sub { 248 sub {
249 print(conf_distver . "\n"); 249 print(conf_distver . "\n");
250 exit(0); 250 exit(0);
251 } ], 251 } ],
252 [ "-W{warn,...}", "enable or disable specific warnings", 252 [ "-W{warn,...}", "enable or disable specific warnings",
253 "warning|W=s", 253 "warning|W=s",
254 sub { 254 sub {
255 my ($opt, $val) = @_; 255 my ($opt, $val) = @_;
256 parse_multioption($val, \%warnings); 256 parse_multioption($val, \%warnings);
257 } ], 257 } ],
258 [ "-e|--explain", "Explain the diagnostics or give further help", 258 [ "-e|--explain", "Explain the diagnostics or give further help",
259 "explain|e", sub { 259 "explain|e", sub {
260 PkgLint::Logging::set_explain(); 260 PkgLint::Logging::set_explain();
261 } ], 261 } ],
262 [ "-g|--gcc-output-format", "Mimic the gcc output format", 262 [ "-g|--gcc-output-format", "Mimic the gcc output format",
263 "gcc-output-format|g", 263 "gcc-output-format|g",
264 sub { 264 sub {
265 PkgLint::Logging::set_gcc_output_format(); 265 PkgLint::Logging::set_gcc_output_format();
266 } ], 266 } ],
267 [ "-h|--help", "print a detailed help message", 267 [ "-h|--help", "print a detailed help message",
268 "help|h", 268 "help|h",
269 sub { 269 sub {
270 help(*STDOUT, 0, 1); 270 help(*STDOUT, 0, 1);
271 } ], 271 } ],
272 [ "-i|--import", "Prepare the import of a wip package", 272 [ "-i|--import", "Prepare the import of a wip package",
273 "import|i", \$opt_import ], 273 "import|i", \$opt_import ],
274 # Note: This is intentionally undocumented. 274 # Note: This is intentionally undocumented.
275 [ "--pkgsrcdir", "Set the root directory of pkgsrc explicitly.", 275 [ "--pkgsrcdir", "Set the root directory of pkgsrc explicitly.",
276 "pkgsrcdir=s", \$cwd_pkgsrcdir ], 276 "pkgsrcdir=s", \$cwd_pkgsrcdir ],
277 [ "-q|--quiet", "Don't print a summary line when finishing", 277 [ "-q|--quiet", "Don't print a summary line when finishing",
278 "quiet|q", \$opt_quiet ], 278 "quiet|q", \$opt_quiet ],
279 [ "-r|--recursive", "Recursive---check subdirectories, too", 279 [ "-r|--recursive", "Recursive---check subdirectories, too",
280 "recursive|r", \$opt_recursive ], 280 "recursive|r", \$opt_recursive ],
281 [ "-s|--source", "Show the source lines together with diagnostics", 281 [ "-s|--source", "Show the source lines together with diagnostics",
282 "source|s", 282 "source|s",
283 sub { 283 sub {
284 PkgLint::Logging::set_show_source_flag(); 284 PkgLint::Logging::set_show_source_flag();
285 } ], 285 } ],
286); 286);
287 287
288our $program = $0; 288our $program = $0;
289 289
290# 290#
291# Commonly used regular expressions. 291# Commonly used regular expressions.
292# 292#
293 293
294use constant regex_dependency_gt => qr"^((?:\$\{[\w_]+\}|[\w_\.]|-[^\d])+)>=(\d[^-]*)$"; 294use constant regex_dependency_gt => qr"^((?:\$\{[\w_]+\}|[\w_\.]|-[^\d])+)>=(\d[^-]*)$";
295use constant regex_dependency_wildcard 295use constant regex_dependency_wildcard
296 => qr"^((?:\$\{[\w_]+\}|[\w_\.]|-[^\d\[])+)-(?:\[0-9\]\*|\d[^-]*)$"; 296 => qr"^((?:\$\{[\w_]+\}|[\w_\.]|-[^\d\[])+)-(?:\[0-9\]\*|\d[^-]*)$";
297use constant regex_gnu_configure_volatile_vars 297use constant regex_gnu_configure_volatile_vars
298 => qr"^(?:.*_)?(?:CFLAGS||CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$"; 298 => qr"^(?:.*_)?(?:CFLAGS||CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$";
299use constant regex_mk_comment => qr"^ *\s*#(.*)$"; 299use constant regex_mk_comment => qr"^ *\s*#(.*)$";
300use constant regex_mk_cond => qr"^\.(\s*)(if|ifdef|ifndef|else|elif|endif|for|endfor|undef)(?:\s+([^\s#][^#]*?))?\s*(?:#.*)?$"; 300use constant regex_mk_cond => qr"^\.(\s*)(if|ifdef|ifndef|else|elif|endif|for|endfor|undef)(?:\s+([^\s#][^#]*?))?\s*(?:#.*)?$";
301use constant regex_mk_dependency=> qr"^([^\s:]+(?:\s*[^\s:]+)*)(\s*):\s*([^#]*?)(?:\s*#.*)?$"; 301use constant regex_mk_dependency=> qr"^([^\s:]+(?:\s*[^\s:]+)*)(\s*):\s*([^#]*?)(?:\s*#.*)?$";
302use constant regex_mk_include => qr"^\.\s*(s?include)\s+\"([^\"]+)\"\s*(?:#.*)?$"; 302use constant regex_mk_include => qr"^\.\s*(s?include)\s+\"([^\"]+)\"\s*(?:#.*)?$";
303use constant regex_mk_sysinclude=> qr"^\.\s*s?include\s+<([^>]+)>\s*(?:#.*)?$"; 303use constant regex_mk_sysinclude=> qr"^\.\s*s?include\s+<([^>]+)>\s*(?:#.*)?$";
304use constant regex_mk_shellvaruse => qr"(?:^|[^\$])\$\$\{?(\w+)\}?"; # XXX: not perfect 304use constant regex_mk_shellvaruse => qr"(?:^|[^\$])\$\$\{?(\w+)\}?"; # XXX: not perfect
305use constant regex_pkgname => qr"^([\w\-.+]+)-(\d(?:\w|\.\d)*)$"; 305use constant regex_pkgname => qr"^([\w\-.+]+)-(\d(?:\w|\.\d)*)$";
306use constant regex_mk_shellcmd => qr"^\t(.*)$"; 306use constant regex_mk_shellcmd => qr"^\t(.*)$";
307use constant regex_rcs_conflict => qr"^(<<<<<<<|=======|>>>>>>>)"; 307use constant regex_rcs_conflict => qr"^(<<<<<<<|=======|>>>>>>>)";
308use constant regex_unresolved => qr"\$\{"; 308use constant regex_unresolved => qr"\$\{";
309use constant regex_validchars => qr"[\011\040-\176]"; 309use constant regex_validchars => qr"[\011\040-\176]";
310# Note: the following regular expression looks more complicated than 310# Note: the following regular expression looks more complicated than
311# necessary to avoid a stack overflow in the Perl interpreter. 311# necessary to avoid a stack overflow in the Perl interpreter.
312# The leading white-space may only consist of \040 characters, otherwise 312# The leading white-space may only consist of \040 characters, otherwise
313# the order of regex_varassign and regex_mk_shellcmd becomes important. 313# the order of regex_varassign and regex_mk_shellcmd becomes important.
314use constant regex_varassign => qr"^ *([-*+A-Z_a-z0-9.\${}\[]+?)\s*(=|\?=|\+=|:=|!=)\s*((?:[^\\#\s]+|\s+?|(?:\\#)+|\\)*?)(?:\s*(#.*))?$"; 314use constant regex_varassign => qr"^ *([-*+A-Z_a-z0-9.\${}\[]+?)\s*(=|\?=|\+=|:=|!=)\s*((?:[^\\#\s]+|\s+?|(?:\\#)+|\\)*?)(?:\s*(#.*))?$";
315use constant regex_sh_varassign => qr"^([A-Z_a-z][0-9A-Z_a-z]*)="; 315use constant regex_sh_varassign => qr"^([A-Z_a-z][0-9A-Z_a-z]*)=";
316 316
317# The following "constants" are often used in contexts where 317# The following "constants" are often used in contexts where
318# interpolation comes handy, so they are variables. Nevertheless they 318# interpolation comes handy, so they are variables. Nevertheless they
319# are not modified. 319# are not modified.
320 320
321# This regular expression cannot parse all kinds of shell programs, but 321# This regular expression cannot parse all kinds of shell programs, but
322# it will catch almost all shell programs that are portable enough to be 322# it will catch almost all shell programs that are portable enough to be
323# used in pkgsrc. 323# used in pkgsrc.
324my $regex_shellword = qr"\s*( 324my $regex_shellword = qr"\s*(
325 \#.* # shell comment 325 \#.* # shell comment
326 | 326 |
327 (?: '[^']*' # single quoted string 327 (?: '[^']*' # single quoted string
328 | \"(?:\\.|[^\"\\])*\" # double quoted string 328 | \"(?:\\.|[^\"\\])*\" # double quoted string
329 | \`[^\`]*\` # backticks string 329 | \`[^\`]*\` # backticks string
330 | \\\$\$ # an escaped dollar sign 330 | \\\$\$ # an escaped dollar sign
331 | \\[^\$] # other escaped characters 331 | \\[^\$] # other escaped characters
332 | \$[\w_] # one-character make(1) variable 332 | \$[\w_] # one-character make(1) variable
333 | \$\{[^{}]+\} # make(1) variable 333 | \$\{[^{}]+\} # make(1) variable
334 | \$\([^()]+\) # make(1) variable, $(...) 334 | \$\([^()]+\) # make(1) variable, $(...)
335 | \$[/\@<^] # special make(1) variables 335 | \$[/\@<^] # special make(1) variables
336 | \$\$[0-9A-Z_a-z]+ # shell variable 336 | \$\$[0-9A-Z_a-z]+ # shell variable
337 | \$\$[\#?@] # special shell variables 337 | \$\$[\#?@] # special shell variables
338 | \$\$\$\$ # the special pid shell variable 338 | \$\$\$\$ # the special pid shell variable
339 | \$\$\{[0-9A-Z_a-z]+\} # shell variable in braces 339 | \$\$\{[0-9A-Z_a-z]+\} # shell variable in braces
340 | \$\$\( # POSIX-style backticks replacement 340 | \$\$\( # POSIX-style backticks replacement
341 | [^\(\)'\"\\\s;&\|<>\`\$] # non-special character 341 | [^\(\)'\"\\\s;&\|<>\`\$] # non-special character
342 | \$\{[^\s\"'`]+ # HACK: nested make(1) variables 342 | \$\{[^\s\"'`]+ # HACK: nested make(1) variables
343 )+ | ;;? | &&? | \|\|? | \( | \) | >& | <<? | >>? | \#.*)"sx; 343 )+ | ;;? | &&? | \|\|? | \( | \) | >& | <<? | >>? | \#.*)"sx;
344my $regex_varname = qr"(?:[-*+.0-9A-Z_a-z{}\[]+|\$\{[\w_]+\})+"; 344my $regex_varname = qr"(?:[-*+.0-9A-Z_a-z{}\[]+|\$\{[\w_]+\})+";
345my $regex_pkgbase = qr"(?:[+.0-9A-Z_a-z]|-[A-Z_a-z])+"; 345my $regex_pkgbase = qr"(?:[+.0-9A-Z_a-z]|-[A-Z_a-z])+";
346my $regex_pkgversion = qr"\d(?:\w|\.\d)*"; 346my $regex_pkgversion = qr"\d(?:\w|\.\d)*";
347 347
348# 348#
349# Commonly used explanations for diagnostics. 349# Commonly used explanations for diagnostics.
350# 350#
351 351
352use constant expl_relative_dirs => ( 352use constant expl_relative_dirs => (
353 "Directories in the form \"../../category/package\" make it easier to", 353 "Directories in the form \"../../category/package\" make it easier to",
354 "move a package around in pkgsrc, for example from pkgsrc-wip to the", 354 "move a package around in pkgsrc, for example from pkgsrc-wip to the",
355 "main pkgsrc repository."); 355 "main pkgsrc repository.");
356 356
357# 357#
358# Global variables. 358# Global variables.
359# 359#
360 360
361my $current_dir; # The currently checked directory. 361my $current_dir; # The currently checked directory.
362my $is_wip; # Is the current directory from pkgsrc-wip? 362my $is_wip; # Is the current directory from pkgsrc-wip?
363my $is_internal; # Is the current item from the infrastructure? 363my $is_internal; # Is the current item from the infrastructure?
364 364
365# 365#
366# Variables for inter-package checks. 366# Variables for inter-package checks.
367# 367#
368 368
369my $ipc_distinfo; # Maps "$alg:$fname" => "checksum". 369my $ipc_distinfo; # Maps "$alg:$fname" => "checksum".
370 370
371# Context of the package that is currently checked. 371# Context of the package that is currently checked.
372my $pkgpath; # The relative path to the package within PKGSRC. 372my $pkgpath; # The relative path to the package within PKGSRC.
373my $pkgdir; # PKGDIR from the package Makefile 373my $pkgdir; # PKGDIR from the package Makefile
374my $filesdir; # FILESDIR from the package Makefile 374my $filesdir; # FILESDIR from the package Makefile
375my $patchdir; # PATCHDIR from the package Makefile 375my $patchdir; # PATCHDIR from the package Makefile
376my $distinfo_file; # DISTINFO_FILE from the package Makefile 376my $distinfo_file; # DISTINFO_FILE from the package Makefile
377my $effective_pkgname; # PKGNAME or DISTNAME from the package Makefile 377my $effective_pkgname; # PKGNAME or DISTNAME from the package Makefile
378my $effective_pkgbase; # The effective PKGNAME without the version 378my $effective_pkgbase; # The effective PKGNAME without the version
379my $effective_pkgversion; # The version part of the effective PKGNAME 379my $effective_pkgversion; # The version part of the effective PKGNAME
380my $effective_pkgname_line; # The origin of the three effective_* values 380my $effective_pkgname_line; # The origin of the three effective_* values
381my $seen_bsd_prefs_mk; # Has bsd.prefs.mk already been included? 381my $seen_bsd_prefs_mk; # Has bsd.prefs.mk already been included?
382 382
383my $pkgctx_vardef; # { varname => line } 383my $pkgctx_vardef; # { varname => line }
384my $pkgctx_varuse; # { varname => line } 384my $pkgctx_varuse; # { varname => line }
385my $pkgctx_bl3; # { buildlink3.mk name => line } (contains 385my $pkgctx_bl3; # { buildlink3.mk name => line } (contains
386 # only buildlink3.mk files that are directly 386 # only buildlink3.mk files that are directly
387 # included) 387 # included)
388my $pkgctx_plist_subst_cond; # { varname => 1 } list of all variables 388my $pkgctx_plist_subst_cond; # { varname => 1 } list of all variables
389 # that are used as conditionals (@comment 389 # that are used as conditionals (@comment
390 # or nothing) in PLISTs. 390 # or nothing) in PLISTs.
391my $pkgctx_included; # { fname => line } 391my $pkgctx_included; # { fname => line }
392my $seen_Makefile_common; # Does the package have any .includes? 392my $seen_Makefile_common; # Does the package have any .includes?
393 393
394# Context of the Makefile that is currently checked. 394# Context of the Makefile that is currently checked.
395my $mkctx_for_variables; # The variables currently used in .for loops 395my $mkctx_for_variables; # The variables currently used in .for loops
396my $mkctx_indentations; # Indentation depth of preprocessing directives 396my $mkctx_indentations; # Indentation depth of preprocessing directives
397my $mkctx_target; # Current make(1) target 397my $mkctx_target; # Current make(1) target
398my $mkctx_vardef; # { varname => line } for all variables that 398my $mkctx_vardef; # { varname => line } for all variables that
399 # are defined in the current file 399 # are defined in the current file
400my $mkctx_varuse; # { varname => line } for all variables 400my $mkctx_varuse; # { varname => line } for all variables
401 # that are used in the current file 401 # that are used in the current file
402my $mkctx_build_defs; # Set of variables that are registered in 402my $mkctx_build_defs; # Set of variables that are registered in
403 # BUILD_DEFS, to assure that all user-defined 403 # BUILD_DEFS, to assure that all user-defined
404 # variables are added to it. 404 # variables are added to it.
405my $mkctx_plist_vars; # The same for PLIST_VARS. 405my $mkctx_plist_vars; # The same for PLIST_VARS.
406my $mkctx_tools; # Set of tools that are declared to be used. 406my $mkctx_tools; # Set of tools that are declared to be used.
407 407
408my @todo_items; # The list of directory entries that still need 408my @todo_items; # The list of directory entries that still need
409 # to be checked. Mostly relevant with 409 # to be checked. Mostly relevant with
410 # --recursive. 410 # --recursive.
411 411
412# 412#
413# Command line parsing and handling. 413# Command line parsing and handling.
414# 414#
415 415
416sub help($$$) { 416sub help($$$) {
417 my ($out, $exitval, $show_all) = @_; 417 my ($out, $exitval, $show_all) = @_;
418 my ($prog) = (basename($program, '.pl')); 418 my ($prog) = (basename($program, '.pl'));
419 print $out ("usage: $prog [options] [package_directory]\n\n"); 419 print $out ("usage: $prog [options] [package_directory]\n\n");
420 420
421 my (@option_table) = (); 421 my (@option_table) = ();
422 foreach my $opt (@options) { 422 foreach my $opt (@options) {
423 push(@option_table, [" ", $opt->[0], $opt->[1]]); 423 push(@option_table, [" ", $opt->[0], $opt->[1]]);
424 } 424 }
425 print $out ("options:\n"); 425 print $out ("options:\n");
426 PkgLint::Util::print_table($out, \@option_table); 426 PkgLint::Util::print_table($out, \@option_table);
427 print $out ("\n"); 427 print $out ("\n");
428 428
429 if (!$show_all) { 429 if (!$show_all) {
430 exit($exitval); 430 exit($exitval);
431 } 431 }
432 432
433 my $categories = [ 433 my $categories = [
434 # options, leading text,  434 # options, leading text,
435 [ \%checks, "checks", "check" ], 435 [ \%checks, "checks", "check" ],
436 [ \%debug, "debugging options", "debug" ], 436 [ \%debug, "debugging options", "debug" ],
437 [ \%warnings, "warnings", "warning" ], 437 [ \%warnings, "warnings", "warning" ],
438 ]; 438 ];
439 foreach my $category (@{$categories}) { 439 foreach my $category (@{$categories}) {
440 my ($options, $leading, $name) = (@{$category}); 440 my ($options, $leading, $name) = (@{$category});
441 my $table = [ 441 my $table = [
442 [" ", "all", "", "enable all ".$category->[1]], 442 [" ", "all", "", "enable all ".$category->[1]],
443 [" ", "none", "", "disable all ".$category->[1]], 443 [" ", "none", "", "disable all ".$category->[1]],
444 ]; 444 ];
445 445
446 foreach my $opt (sort keys %{$options}) { 446 foreach my $opt (sort keys %{$options}) {
447 push(@{$table}, [ " ", $opt, 447 push(@{$table}, [ " ", $opt,
448 (${$options->{$opt}->[0]} ? "(enabled)" : "(disabled)"), 448 (${$options->{$opt}->[0]} ? "(enabled)" : "(disabled)"),
449 $options->{$opt}->[1]]); 449 $options->{$opt}->[1]]);
450 } 450 }
451 451
452 print $out ("${leading}: (use \"${name}\" to enable, \"no-${name}\" to disable)\n"); 452 print $out ("${leading}: (use \"${name}\" to enable, \"no-${name}\" to disable)\n");
453 PkgLint::Util::print_table($out, $table); 453 PkgLint::Util::print_table($out, $table);
454 print $out ("\n"); 454 print $out ("\n");
455 } 455 }
456 456
457 exit($exitval); 457 exit($exitval);
458} 458}
459 459
460sub parse_multioption($$) { 460sub parse_multioption($$) {
461 my ($value, $optdefs) = @_; 461 my ($value, $optdefs) = @_;
462 foreach my $opt (split(qr",", $value)) { 462 foreach my $opt (split(qr",", $value)) {
463 if ($opt eq "none") { 463 if ($opt eq "none") {
464 foreach my $key (keys %{$optdefs}) { 464 foreach my $key (keys %{$optdefs}) {
465 ${$optdefs->{$key}->[0]} = false; 465 ${$optdefs->{$key}->[0]} = false;
466 } 466 }
467 467
468 } elsif ($opt eq "all") { 468 } elsif ($opt eq "all") {
469 foreach my $key (keys %{$optdefs}) { 469 foreach my $key (keys %{$optdefs}) {
470 ${$optdefs->{$key}->[0]} = true; 470 ${$optdefs->{$key}->[0]} = true;
471 } 471 }
472 472
473 } else { 473 } else {
474 my ($value) = (($opt =~ s/^no-//) ? false : true); 474 my ($value) = (($opt =~ s/^no-//) ? false : true);
475 if (exists($optdefs->{$opt})) { 475 if (exists($optdefs->{$opt})) {
476 ${$optdefs->{$opt}->[0]} = $value; 476 ${$optdefs->{$opt}->[0]} = $value;
477 } else { 477 } else {
478 print STDERR ("Invalid option: ${opt}\n"); 478 print STDERR ("Invalid option: ${opt}\n");
479 help(*STDERR, 1, 0); 479 help(*STDERR, 1, 0);
480 } 480 }
481 } 481 }
482 } 482 }
483} 483}
484 484
485sub parse_command_line() { 485sub parse_command_line() {
486 my (%options); 486 my (%options);
487 487
488 foreach my $opt (@options) { 488 foreach my $opt (@options) {
489 $options{$opt->[2]} = $opt->[3]; 489 $options{$opt->[2]} = $opt->[3];
490 } 490 }
491 491
492 { 492 {
493 local $SIG{__WARN__} = sub {}; 493 local $SIG{__WARN__} = sub {};
494 if (!GetOptions(%options)) { 494 if (!GetOptions(%options)) {
495 help(*STDERR, 1, false); 495 help(*STDERR, 1, false);
496 } 496 }
497 } 497 }
498} 498}
499 499
500# 500#
501# Caching subroutines. 501# Caching subroutines.
502# 502#
503 503
504# The get_regex_plurals() function returns a regular expression that 504# The get_regex_plurals() function returns a regular expression that
505# matches for all make(1) variable names that are considered lists 505# matches for all make(1) variable names that are considered lists
506# of something. 506# of something.
507# 507#
508# Rationale: 508# Rationale:
509# 509#
510# The pkglint author thinks that variables containing lists of things 510# The pkglint author thinks that variables containing lists of things
511# should have a name indicating some plural form. Sadly, there are other 511# should have a name indicating some plural form. Sadly, there are other
512# reasons like backwards compatibility and other developer's 512# reasons like backwards compatibility and other developer's
513# expectations that make changes to most of the following variables 513# expectations that make changes to most of the following variables
514# highly unlikely. 514# highly unlikely.
515my $get_regex_plurals_value = undef; 515my $get_regex_plurals_value = undef;
516sub get_regex_plurals() { 516sub get_regex_plurals() {
517 517
518 if (defined($get_regex_plurals_value)) { 518 if (defined($get_regex_plurals_value)) {
519 return $get_regex_plurals_value; 519 return $get_regex_plurals_value;
520 } 520 }
521 521
522 my @plurals_ok = qw( 522 my @plurals_ok = qw(
523 .*S 523 .*S
524 .*LIST 524 .*LIST
525 .*_AWK 525 .*_AWK
526 .*_ENV 526 .*_ENV
527 .*_REQD 527 .*_REQD
528 .*_SED 528 .*_SED
529 .*_SKIP 529 .*_SKIP
530 BUILDLINK_LDADD 530 BUILDLINK_LDADD
531 COMMENT 531 COMMENT
532 EXTRACT_ONLY 532 EXTRACT_ONLY
533 FETCH_MESSAGE 533 FETCH_MESSAGE
534 GENERATE_PLIST 534 GENERATE_PLIST
535 PLIST_CAT 535 PLIST_CAT
536 PLIST_PRE 536 PLIST_PRE
537 PREPEND_PATH 537 PREPEND_PATH
538 ); 538 );
539 my @plurals_missing_an_s = qw( 539 my @plurals_missing_an_s = qw(
540 .*_OVERRIDE 540 .*_OVERRIDE
541 .*_PREREQ 541 .*_PREREQ
542 .*_SRC 542 .*_SRC
543 .*_SUBST 543 .*_SUBST
544 .*_TARGET 544 .*_TARGET
545 .*_TMPL 545 .*_TMPL
546 BUILDLINK_DEPMETHOD 546 BUILDLINK_DEPMETHOD
547 BUILDLINK_TRANSFORM 547 BUILDLINK_TRANSFORM
548 EVAL_PREFIX 548 EVAL_PREFIX
549 INTERACTIVE_STAGE 549 INTERACTIVE_STAGE
550 LICENSE 550 LICENSE
551 MASTER_SITE_.* 551 MASTER_SITE_.*
552 MASTER_SORT_REGEX 552 MASTER_SORT_REGEX
553 NOT_FOR_COMPILER 553 NOT_FOR_COMPILER
554 NOT_FOR_PLATFORM 554 NOT_FOR_PLATFORM
555 ONLY_FOR_COMPILER 555 ONLY_FOR_COMPILER
556 ONLY_FOR_PLATFORM 556 ONLY_FOR_PLATFORM
557 PERL5_PACKLIST 557 PERL5_PACKLIST
558 PKG_FAIL_REASON 558 PKG_FAIL_REASON
559 PKG_SKIP_REASON 559 PKG_SKIP_REASON
560 ); 560 );
561 my @plurals_reluctantly_accepted = qw( 561 my @plurals_reluctantly_accepted = qw(
562 CRYPTO 562 CRYPTO
563 DEINSTALL_TEMPLATE 563 DEINSTALL_TEMPLATE
564 FIX_RPATH 564 FIX_RPATH
565 INSTALL_TEMPLATE 565 INSTALL_TEMPLATE
566 PYTHON_VERSIONS_INCOMPATIBLE 566 PYTHON_VERSIONS_INCOMPATIBLE
567 REPLACE_INTERPRETER 567 REPLACE_INTERPRETER
568 REPLACE_PERL 568 REPLACE_PERL
569 REPLACE_RUBY 569 REPLACE_RUBY
570 RESTRICTED 570 RESTRICTED
571 SITES_.* 571 SITES_.*
572 TOOLS_ALIASES\.* 572 TOOLS_ALIASES\.*
573 TOOLS_BROKEN 573 TOOLS_BROKEN
574 TOOLS_CREATE 574 TOOLS_CREATE
575 TOOLS_GNU_MISSING 575 TOOLS_GNU_MISSING
576 TOOLS_NOOP 576 TOOLS_NOOP
577 ); 577 );
578 my $plurals = join("|", 578 my $plurals = join("|",
579 @plurals_ok, 579 @plurals_ok,
580 @plurals_missing_an_s, 580 @plurals_missing_an_s,
581 @plurals_reluctantly_accepted 581 @plurals_reluctantly_accepted
582 ); 582 );
583 583
584 $get_regex_plurals_value = qr"^(?:${plurals})$"; 584 $get_regex_plurals_value = qr"^(?:${plurals})$";
585 return $get_regex_plurals_value; 585 return $get_regex_plurals_value;
586} 586}
587 587
588# 588#
589# Loading pkglint-specific data from files. 589# Loading pkglint-specific data from files.
590# 590#
591 591
592# The symbol table for ACL definitions maps ACL names to ACLs. 592# The symbol table for ACL definitions maps ACL names to ACLs.
593my $acl_definitions = {}; 593my $acl_definitions = {};
594 594
595sub parse_acls($$) { 595sub parse_acls($$) {
596 my ($line, $acltext) = @_; 596 my ($line, $acltext) = @_;
597 my ($acls); 597 my ($acls);
598 598
599 use constant ACL_shortcuts => { 599 use constant ACL_shortcuts => {
600 "b" => qr"(?:^|/)buildlink3\.mk$", 600 "b" => qr"(?:^|/)buildlink3\.mk$",
601 "c" => qr"(?:^|/)Makefile\.common$", 601 "c" => qr"(?:^|/)Makefile\.common$",
602 "h" => qr"(?:^|/)hacks\.mk$", 602 "h" => qr"(?:^|/)hacks\.mk$",
603 "m" => qr"(?:^|/)Makefile$", 603 "m" => qr"(?:^|/)Makefile$",
604 "o" => qr"(?:^|/)options\.mk$", 604 "o" => qr"(?:^|/)options\.mk$",
605 }; 605 };
606 606
607 my $regex_acl_entry = qr"^(?: 607 my $regex_acl_entry = qr"^(?:
608 \$([\w_]+) # $acl_name 608 \$([\w_]+) # $acl_name
609 | ([\w.*]+|_):([adpsu]*) # file*mask:perms 609 | ([\w.*]+|_):([adpsu]*) # file*mask:perms
610 ) (?:\,\s*|$)"x; 610 ) (?:\,\s*|$)"x;
611 611
612 if (!defined($acltext)) { 612 if (!defined($acltext)) {
613 return undef; 613 return undef;
614 } 614 }
615 615
616 $acls = []; 616 $acls = [];
617 while ($acltext =~ s,$regex_acl_entry,,) { 617 while ($acltext =~ s,$regex_acl_entry,,) {
618 my ($acldef, $subject, $perms) = ($1, $2, $3); 618 my ($acldef, $subject, $perms) = ($1, $2, $3);
619 619
620 if (defined($acldef)) { 620 if (defined($acldef)) {
621 if (!exists($acl_definitions->{$acldef})) { 621 if (!exists($acl_definitions->{$acldef})) {
622 $line->log_fatal("ACL definition ${acldef} not found."); 622 $line->log_fatal("ACL definition ${acldef} not found.");
623 } else { 623 } else {
624 push(@{$acls}, @{$acl_definitions->{$acldef}}); 624 push(@{$acls}, @{$acl_definitions->{$acldef}});
625 } 625 }
626 626
627 } else { 627 } else {
628 # Transform $subject to a regular expression. 628 # Transform $subject to a regular expression.
629 $subject =~ s/\./[.]/g; 629 $subject =~ s/\./[.]/g;
630 $subject =~ s/\*/.*/g; 630 $subject =~ s/\*/.*/g;
631 631
632 push(@{$acls}, [exists(ACL_shortcuts->{$subject}) ? ACL_shortcuts->{$subject} : qr"(?:^|/)${subject}$", $perms]); 632 push(@{$acls}, [exists(ACL_shortcuts->{$subject}) ? ACL_shortcuts->{$subject} : qr"(?:^|/)${subject}$", $perms]);
633 } 633 }
634 } 634 }
635 if ($acltext ne "") { 635 if ($acltext ne "") {
636 $line->log_fatal("Invalid ACL: ${acltext}."); 636 $line->log_fatal("Invalid ACL: ${acltext}.");
637 } 637 }
638 638
639 return $acls; 639 return $acls;
640} 640}
641 641
642my $get_vartypes_basictypes_result = undef; 642my $get_vartypes_basictypes_result = undef;
643sub get_vartypes_basictypes() { 643sub get_vartypes_basictypes() {
644 if (defined($get_vartypes_basictypes_result)) { 644 if (defined($get_vartypes_basictypes_result)) {
645 return $get_vartypes_basictypes_result; 645 return $get_vartypes_basictypes_result;
646 } 646 }
647 647
648 my $lines = load_file($program); 648 my $lines = load_file($program);
649 my $types = {}; 649 my $types = {};
650 assert($lines, "Couldn't load pkglint.pl from $program"); 650 assert($lines, "Couldn't load pkglint.pl from $program");
651 foreach my $line (@$lines) { 651 foreach my $line (@$lines) {
652 if ($line->text =~ m"^\s+(\w+) => sub \{$") { 652 if ($line->text =~ m"^\s+(\w+) => sub \{$") {
653 # XXX lookup in %type_dispatch instead 653 # XXX lookup in %type_dispatch instead
654 $types->{$1} = 1; 654 $types->{$1} = 1;
655 } 655 }
656 } 656 }
657 return ($get_vartypes_basictypes_result = $types); 657 return ($get_vartypes_basictypes_result = $types);
658} 658}
659 659
660my $get_vartypes_map_result = undef; 660my $get_vartypes_map_result = undef;
661sub get_vartypes_map() { 661sub get_vartypes_map() {
662 my ($fname, $vartypes); 662 my ($fname, $vartypes);
663 663
664 if (defined($get_vartypes_map_result)) { 664 if (defined($get_vartypes_map_result)) {
665 return $get_vartypes_map_result; 665 return $get_vartypes_map_result;
666 } 666 }
667 667
668 use constant re_acl_def => qr"^ 668 use constant re_acl_def => qr"^
669 acl \s+ 669 acl \s+
670 (\w+) \s+ # ACL name 670 (\w+) \s+ # ACL name
671 = \s+ 671 = \s+
672 \[ ([^\]]*) \] # ACL value 672 \[ ([^\]]*) \] # ACL value
673 (?:\s*\#.*)? # optional comment 673 (?:\s*\#.*)? # optional comment
674 $"x; 674 $"x;
675 675
676 use constant re_vartypedef => qr"^ 676 use constant re_vartypedef => qr"^
677 ([\w\d_.]+?) # $1 = variable name 677 ([\w\d_.]+?) # $1 = variable name
678 (\*|\.\*|) \s+ # $2 = parameterized? 678 (\*|\.\*|) \s+ # $2 = parameterized?
679 (?:(InternalList|List) \s+ of \s+)? # $3 ?= kind of list 679 (?:(InternalList|List) \s+ of \s+)? # $3 ?= kind of list
680 (?:([\w\d_]+) # $4 ?= basic type 680 (?:([\w\d_]+) # $4 ?= basic type
681 | \{\s*([\w\d_+,\-.\s]+?)\s*\}) # $5 ?= enumeration values 681 | \{\s*([\w\d_+,\-.\s]+?)\s*\}) # $5 ?= enumeration values
682 (?:\s+ \[ ([^\]]*) \])? # $6 ?= optional ACL 682 (?:\s+ \[ ([^\]]*) \])? # $6 ?= optional ACL
683 (?:\s*\#.*)? # $7 ?= optional comment 683 (?:\s*\#.*)? # $7 ?= optional comment
684 $"x; 684 $"x;
685 685
686 $fname = conf_datadir."/makevars.map"; 686 $fname = conf_datadir."/makevars.map";
687 $vartypes = {}; 687 $vartypes = {};
688 688
689 if ((my $lines = load_lines($fname, true))) { 689 if ((my $lines = load_lines($fname, true))) {
690 foreach my $line (@{$lines}) { 690 foreach my $line (@{$lines}) {
691 if ($line->text =~ m"^(?:#.*|\s*)$") { 691 if ($line->text =~ m"^(?:#.*|\s*)$") {
692 # ignore empty and comment lines 692 # ignore empty and comment lines
693 693
694 } elsif ($line->text =~ re_acl_def) { 694 } elsif ($line->text =~ re_acl_def) {
695 my ($aclname, $aclvalue) = ($1, $2); 695 my ($aclname, $aclvalue) = ($1, $2);
696 696
697 $acl_definitions->{$aclname} = parse_acls($line, $aclvalue); 697 $acl_definitions->{$aclname} = parse_acls($line, $aclvalue);
698 698
699 } elsif ($line->text =~ re_vartypedef) { 699 } elsif ($line->text =~ re_vartypedef) {
700 my ($varname, $par, $kind_of_list_text, $typename, $enums, $acltext) = ($1, $2, $3, $4, $5, $6); 700 my ($varname, $par, $kind_of_list_text, $typename, $enums, $acltext) = ($1, $2, $3, $4, $5, $6);
701 my $kind_of_list = !defined($kind_of_list_text) ? LK_NONE 701 my $kind_of_list = !defined($kind_of_list_text) ? LK_NONE
702 : ($kind_of_list_text eq "List") ? LK_EXTERNAL 702 : ($kind_of_list_text eq "List") ? LK_EXTERNAL
703 : LK_INTERNAL; 703 : LK_INTERNAL;
704 704
705 if (defined($typename) && !exists(get_vartypes_basictypes()->{$typename})) { 705 if (defined($typename) && !exists(get_vartypes_basictypes()->{$typename})) {
706 $line->log_fatal("Unknown basic type \"$typename\" for variable $varname. " 706 $line->log_fatal("Unknown basic type \"$typename\" for variable $varname. "
707 . "Valid basic types are " 707 . "Valid basic types are "
708 . join(", ", sort keys %{get_vartypes_basictypes()}) 708 . join(", ", sort keys %{get_vartypes_basictypes()})
709 . "."); 709 . ".");
710 } 710 }
711 711
712 my $basic_type = defined($enums) 712 my $basic_type = defined($enums)
713 ? array_to_hash(split(qr"\s+", $enums)) 713 ? array_to_hash(split(qr"\s+", $enums))
714 : $typename; 714 : $typename;
715 my $type = PkgLint::Type->new($kind_of_list, $basic_type, parse_acls($line, $acltext), NOT_GUESSED); 715 my $type = PkgLint::Type->new($kind_of_list, $basic_type, parse_acls($line, $acltext), NOT_GUESSED);
716 if ($par eq "" || $par eq "*") { 716 if ($par eq "" || $par eq "*") {
717 $vartypes->{$varname} = $type; 717 $vartypes->{$varname} = $type;
718 } 718 }
719 if ($par eq "*" || $par eq ".*") { 719 if ($par eq "*" || $par eq ".*") {
720 $vartypes->{"${varname}.*"} = $type; 720 $vartypes->{"${varname}.*"} = $type;
721 } 721 }
722 722
723 } else { 723 } else {
724 $line->log_fatal("Unknown line format."); 724 $line->log_fatal("Unknown line format.");
725 } 725 }
726 } 726 }
727 } else { 727 } else {
728 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 728 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
729 } 729 }
730 730
731# TODO: Enable when the time is ripe. 731# TODO: Enable when the time is ripe.
732if (false) { 732if (false) {
733 # Additionally, scan mk/defaults/mk.conf for variable 733 # Additionally, scan mk/defaults/mk.conf for variable
734 # definitions. All these variables are reserved for the user and 734 # definitions. All these variables are reserved for the user and
735 # must not be set within packages. 735 # must not be set within packages.
736 $fname = "${cwd_pkgsrcdir}/mk/defaults/mk.conf"; 736 $fname = "${cwd_pkgsrcdir}/mk/defaults/mk.conf";
737 if ((my $lines = load_file($fname))) { 737 if ((my $lines = load_file($fname))) {
738 foreach my $line (@{$lines}) { 738 foreach my $line (@{$lines}) {
739 if ($line->text =~ m"^#?([\w_]+)\?=") { 739 if ($line->text =~ m"^#?([\w_]+)\?=") {
740 my ($varname) = ($1); 740 my ($varname) = ($1);
741 $opt_debug_misc and $line->log_debug("Found user-definable variable ${varname}."); 741 $opt_debug_misc and $line->log_debug("Found user-definable variable ${varname}.");
742 $vartypes->{$varname} = "Userdefined"; # FIXME: type error 742 $vartypes->{$varname} = "Userdefined"; # FIXME: type error
743 } 743 }
744 } 744 }
745 } else { 745 } else {
746 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 746 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
747 } 747 }
748} 748}
749 749
750 return ($get_vartypes_map_result = $vartypes); 750 return ($get_vartypes_map_result = $vartypes);
751} 751}
752 752
753my $get_deprecated_map_result = undef; 753my $get_deprecated_map_result = undef;
754sub get_deprecated_map() { 754sub get_deprecated_map() {
755 my ($fname, $lines, $vars); 755 my ($fname, $lines, $vars);
756 756
757 if (defined($get_deprecated_map_result)) { 757 if (defined($get_deprecated_map_result)) {
758 return $get_deprecated_map_result; 758 return $get_deprecated_map_result;
759 } 759 }
760 760
761 $fname = conf_datadir."/deprecated.map"; 761 $fname = conf_datadir."/deprecated.map";
762 if (!($lines = load_file($fname))) { 762 if (!($lines = load_file($fname))) {
763 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 763 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
764 } 764 }
765 765
766 $vars = {}; 766 $vars = {};
767 foreach my $line (@{$lines}) { 767 foreach my $line (@{$lines}) {
768 if ($line->text =~ m"^#" || $line->text =~ m"^\s*$") { 768 if ($line->text =~ m"^#" || $line->text =~ m"^\s*$") {
769 # Ignore empty and comment lines. 769 # Ignore empty and comment lines.
770 770
771 } elsif ($line->text =~ m"^(\S+)\s+(.*)$") { 771 } elsif ($line->text =~ m"^(\S+)\s+(.*)$") {
772 $vars->{$1} = $2; 772 $vars->{$1} = $2;
773 773
774 } else { 774 } else {
775 $line->log_fatal("Unknown line format."); 775 $line->log_fatal("Unknown line format.");
776 } 776 }
777 } 777 }
778 return ($get_deprecated_map_result = $vars); 778 return ($get_deprecated_map_result = $vars);
779} 779}
780 780
781my $load_dist_sites_url2name = undef; 781my $load_dist_sites_url2name = undef;
782my $load_dist_sites_names = undef; 782my $load_dist_sites_names = undef;
783sub load_dist_sites() { 783sub load_dist_sites() {
784 my ($fname) = ("${cwd_pkgsrcdir}/mk/fetch/sites.mk"); 784 my ($fname) = ("${cwd_pkgsrcdir}/mk/fetch/sites.mk");
785 my ($lines) = load_file($fname); 785 my ($lines) = load_file($fname);
786 my ($varname) = undef; 786 my ($varname) = undef;
787 my ($ignoring) = false; 787 my ($ignoring) = false;
788 my ($url2name) = {}; 788 my ($url2name) = {};
789 my ($names) = {}; 789 my ($names) = {};
790 790
791 if (!$lines) { 791 if (!$lines) {
792 log_error($fname, NO_LINE_NUMBER, "Could not be read."); 792 log_error($fname, NO_LINE_NUMBER, "Could not be read.");
793 $load_dist_sites_url2name = $url2name; 793 $load_dist_sites_url2name = $url2name;
794 $load_dist_sites_names = $names; 794 $load_dist_sites_names = $names;
795 return; 795 return;
796 } 796 }
797 foreach my $line (@{$lines}) { 797 foreach my $line (@{$lines}) {
798 my $text = $line->text; 798 my $text = $line->text;
799 799
800 if ($text =~ m"^(MASTER_SITE_\w+)\+=\s*\\$"o) { 800 if ($text =~ m"^(MASTER_SITE_\w+)\+=\s*\\$"o) {
801 $varname = $1; 801 $varname = $1;
802 $names->{$varname} = true; 802 $names->{$varname} = true;
803 $ignoring = false; 803 $ignoring = false;
804 804
805 } elsif ($text eq "MASTER_SITE_BACKUP?=\t\\") { 805 } elsif ($text eq "MASTER_SITE_BACKUP?=\t\\") {
806 $ignoring = true; 806 $ignoring = true;
807 807
808 } elsif ($text =~ m"^\t((?:http://|ftp://)\S+/)(?:|\s*\\)$"o) { 808 } elsif ($text =~ m"^\t((?:http://|ftp://)\S+/)(?:|\s*\\)$"o) {
809 if (!$ignoring) { 809 if (!$ignoring) {
810 if (defined($varname)) { 810 if (defined($varname)) {
811 $url2name->{$1} = $varname; 811 $url2name->{$1} = $varname;
812 } else { 812 } else {
813 $line->log_error("Lonely URL found."); 813 $line->log_error("Lonely URL found.");
814 } 814 }
815 } 815 }
816 816
817 } elsif ($text =~ m"^(?:#.*|\s*)$") { 817 } elsif ($text =~ m"^(?:#.*|\s*)$") {
818 # ignore empty and comment lines 818 # ignore empty and comment lines
819 819
820 } elsif ($text =~ m"BSD_SITES_MK") { 820 } elsif ($text =~ m"BSD_SITES_MK") {
821 # ignore multiple inclusion guards 821 # ignore multiple inclusion guards
822 822
823 } else { 823 } else {
824 $line->log_fatal("Unknown line type."); 824 $line->log_fatal("Unknown line type.");
825 } 825 }
826 } 826 }
827 827
828 # Explicitly allowed, although not defined in mk/fetch/sites.mk. 828 # Explicitly allowed, although not defined in mk/fetch/sites.mk.
829 $names->{"MASTER_SITE_SUSE_UPD"} = true; 829 $names->{"MASTER_SITE_SUSE_UPD"} = true;
830 $names->{"MASTER_SITE_LOCAL"} = true; 830 $names->{"MASTER_SITE_LOCAL"} = true;
831 831
832 $opt_debug_misc and log_debug($fname, NO_LINES, "Loaded " . scalar(keys(%{$url2name})) . " MASTER_SITE_* definitions."); 832 $opt_debug_misc and log_debug($fname, NO_LINES, "Loaded " . scalar(keys(%{$url2name})) . " MASTER_SITE_* definitions.");
833 $load_dist_sites_url2name = $url2name; 833 $load_dist_sites_url2name = $url2name;
834 $load_dist_sites_names = $names; 834 $load_dist_sites_names = $names;
835} 835}
836 836
837sub get_dist_sites() { 837sub get_dist_sites() {
838 if (!defined($load_dist_sites_url2name)) { 838 if (!defined($load_dist_sites_url2name)) {
839 load_dist_sites(); 839 load_dist_sites();
840 } 840 }
841 return $load_dist_sites_url2name; 841 return $load_dist_sites_url2name;
842} 842}
843 843
844sub get_dist_sites_names() { 844sub get_dist_sites_names() {
845 if (!defined($load_dist_sites_names)) { 845 if (!defined($load_dist_sites_names)) {
846 load_dist_sites(); 846 load_dist_sites();
847 } 847 }
848 return $load_dist_sites_names; 848 return $load_dist_sites_names;
849} 849}
850 850
851my $get_pkg_options_result = undef; 851my $get_pkg_options_result = undef;
852sub get_pkg_options() { 852sub get_pkg_options() {
853 853
854 if (defined($get_pkg_options_result)) { 854 if (defined($get_pkg_options_result)) {
855 return $get_pkg_options_result; 855 return $get_pkg_options_result;
856 } 856 }
857 857
858 my ($fname) = ("${cwd_pkgsrcdir}/mk/defaults/options.description"); 858 my ($fname) = ("${cwd_pkgsrcdir}/mk/defaults/options.description");
859 my ($lines, $options); 859 my ($lines, $options);
860 860
861 if (!($lines = load_file($fname))) { 861 if (!($lines = load_file($fname))) {
862 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 862 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
863 } 863 }
864 864
865 $options = {}; 865 $options = {};
866 foreach my $line (@{$lines}) { 866 foreach my $line (@{$lines}) {
867 if ($line->text =~ m"^([-0-9a-z_+]+)(?:\s+(.*))?$") { 867 if ($line->text =~ m"^([-0-9a-z_+]+)(?:\s+(.*))?$") {
868 my ($optname, $optdescr) = ($1, $2); 868 my ($optname, $optdescr) = ($1, $2);
869 869
870 $options->{$optname} = defined($optdescr) 870 $options->{$optname} = defined($optdescr)
871 ? $optdescr 871 ? $optdescr
872 : ""; 872 : "";
873 } else { 873 } else {
874 $line->log_error("Unknown line format."); 874 $line->log_error("Unknown line format.");
875 } 875 }
876 } 876 }
877 877
878 return ($get_pkg_options_result = $options); 878 return ($get_pkg_options_result = $options);
879} 879}
880 880
881my $load_tool_names_system_build_defs = undef; # XXX: misplaced, but works 881my $load_tool_names_system_build_defs = undef; # XXX: misplaced, but works
882my $load_tool_names_tools = undef; 882my $load_tool_names_tools = undef;
883my $load_tool_names_vartools = undef; 883my $load_tool_names_vartools = undef;
884my $load_tool_names_varname_to_toolname = undef; 884my $load_tool_names_varname_to_toolname = undef;
885my $load_tool_names_predefined_tools = undef; 885my $load_tool_names_predefined_tools = undef;
886sub load_tool_names() { 886sub load_tool_names() {
887 my ($tools, $vartools, $predefined_tools, $varname_to_toolname, @tool_files); 887 my ($tools, $vartools, $predefined_tools, $varname_to_toolname, @tool_files);
888 my ($system_build_defs); 888 my ($system_build_defs);
889 889
890 # 890 #
891 # Get the list of files that define the tools from bsd.tools.mk. 891 # Get the list of files that define the tools from bsd.tools.mk.
892 # 892 #
893 893
894 @tool_files = ("defaults.mk"); 894 @tool_files = ("defaults.mk");
895 { 895 {
896 my $fname = "${cwd_pkgsrcdir}/mk/tools/bsd.tools.mk"; 896 my $fname = "${cwd_pkgsrcdir}/mk/tools/bsd.tools.mk";
897 my $lines = load_lines($fname, true); 897 my $lines = load_lines($fname, true);
898 if (!$lines) { 898 if (!$lines) {
899 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 899 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
900 } 900 }
901 901
902 foreach my $line (@{$lines}) { 902 foreach my $line (@{$lines}) {
903 if ($line->text =~ regex_mk_include) { 903 if ($line->text =~ regex_mk_include) {
904 my (undef, $includefile) = ($1, $2); 904 my (undef, $includefile) = ($1, $2);
905 if ($includefile =~ m"^(?:\$\{PKGSRCDIR\}/mk/tools/)?([^/]+)$") { 905 if ($includefile =~ m"^(?:\$\{PKGSRCDIR\}/mk/tools/)?([^/]+)$") {
906 push(@tool_files, $1); 906 push(@tool_files, $1);
907 } 907 }
908 } 908 }
909 } 909 }
910 } 910 }
911 assert(scalar(@tool_files) > 1, "Too few tool files. Maybe the files have been renamed again?"); 911 assert(scalar(@tool_files) > 1, "Too few tool files. Maybe the files have been renamed again?");
912 912
913 # 913 #
914 # Scan the tool files for the actual definitions of the tools. 914 # Scan the tool files for the actual definitions of the tools.
915 # 915 #
916 916
917 $tools = {}; 917 $tools = {};
918 $vartools = {}; 918 $vartools = {};
919 $predefined_tools = {}; 919 $predefined_tools = {};
920 $varname_to_toolname = {}; 920 $varname_to_toolname = {};
921 $system_build_defs = {}; 921 $system_build_defs = {};
922 foreach my $basename (@tool_files) { 922 foreach my $basename (@tool_files) {
923 my $fname = "${cwd_pkgsrcdir}/mk/tools/${basename}"; 923 my $fname = "${cwd_pkgsrcdir}/mk/tools/${basename}";
924 my $lines = load_lines($fname, true); 924 my $lines = load_lines($fname, true);
925 925
926 if (!$lines) { 926 if (!$lines) {
927 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 927 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
928 } 928 }
929 929
930 foreach my $line (@{$lines}) { 930 foreach my $line (@{$lines}) {
931 if ($line->text =~ regex_varassign) { 931 if ($line->text =~ regex_varassign) {
932 my ($varname, undef, $value, undef) = ($1, $2, $3, $4); 932 my ($varname, undef, $value, undef) = ($1, $2, $3, $4);
933 if ($varname eq "TOOLS_CREATE" && $value =~ m"^([-\w.]+|\[)$") { 933 if ($varname eq "TOOLS_CREATE" && $value =~ m"^([-\w.]+|\[)$") {
934 $tools->{$value} = true; 934 $tools->{$value} = true;
935 935
936 } elsif ($varname =~ m"^(?:_TOOLS_VARNAME)\.([-\w.]+|\[)$") { 936 } elsif ($varname =~ m"^(?:_TOOLS_VARNAME)\.([-\w.]+|\[)$") {
937 $tools->{$1} = true; 937 $tools->{$1} = true;
938 $vartools->{$1} = $value; 938 $vartools->{$1} = $value;
939 $varname_to_toolname->{$value} = $1; 939 $varname_to_toolname->{$value} = $1;
940 940
941 } elsif ($varname =~ m"^(?:TOOLS_PATH|_TOOLS_DEPMETHOD)\.([-\w.]+|\[)$") { 941 } elsif ($varname =~ m"^(?:TOOLS_PATH|_TOOLS_DEPMETHOD)\.([-\w.]+|\[)$") {
942 $tools->{$1} = true; 942 $tools->{$1} = true;
943 943
944 } elsif ($varname =~ m"^_TOOLS\.(.*)") { 944 } elsif ($varname =~ m"^_TOOLS\.(.*)") {
945 $tools->{$1} = true; 945 $tools->{$1} = true;
946 foreach my $tool (split(qr"\s+", $value)) { 946 foreach my $tool (split(qr"\s+", $value)) {
947 $tools->{$tool} = true; 947 $tools->{$tool} = true;
948 } 948 }
949 } 949 }
950 } 950 }
951 } 951 }
952 } 952 }
953 953
954 foreach my $basename ("bsd.pkg.mk") { 954 foreach my $basename ("bsd.pkg.mk") {
955 my $fname = "${cwd_pkgsrcdir}/mk/${basename}"; 955 my $fname = "${cwd_pkgsrcdir}/mk/${basename}";
956 my $lines = load_lines($fname, true); 956 my $lines = load_lines($fname, true);
957 my $cond_depth = 0; 957 my $cond_depth = 0;
958 958
959 if (!$lines) { 959 if (!$lines) {
960 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read."); 960 log_fatal($fname, NO_LINE_NUMBER, "Cannot be read.");
961 } 961 }
962 962
963 foreach my $line (@{$lines}) { 963 foreach my $line (@{$lines}) {
964 my $text = $line->text; 964 my $text = $line->text;
965 965
966 if ($text =~ regex_varassign) { 966 if ($text =~ regex_varassign) {
967 my ($varname, undef, $value, undef) = ($1, $2, $3, $4); 967 my ($varname, undef, $value, undef) = ($1, $2, $3, $4);
968 968
969 if ($varname eq "USE_TOOLS") { 969 if ($varname eq "USE_TOOLS") {
970 $opt_debug_tools and $line->log_debug("[cond_depth=${cond_depth}] $value"); 970 $opt_debug_tools and $line->log_debug("[cond_depth=${cond_depth}] $value");
971 if ($cond_depth == 0) { 971 if ($cond_depth == 0) {
972 foreach my $tool (split(qr"\s+", $value)) { 972 foreach my $tool (split(qr"\s+", $value)) {
973 if ($tool !~ regex_unresolved && exists($tools->{$tool})) { 973 if ($tool !~ regex_unresolved && exists($tools->{$tool})) {
974 $predefined_tools->{$tool} = true; 974 $predefined_tools->{$tool} = true;
975 # The path (without arguments) to the tool 975 # The path (without arguments) to the tool
976 $predefined_tools->{"TOOLS_${tool}"} = true; 976 $predefined_tools->{"TOOLS_${tool}"} = true;
977 } 977 }
978 } 978 }
979 } 979 }
980 } elsif ($varname eq "_BUILD_DEFS") { 980 } elsif ($varname eq "_BUILD_DEFS") {
981 foreach my $bdvar (split(qr"\s+", $value)) { 981 foreach my $bdvar (split(qr"\s+", $value)) {
982 $system_build_defs->{$bdvar} = true; 982 $system_build_defs->{$bdvar} = true;
983 } 983 }
984 } 984 }
985 985
986 } elsif ($text =~ regex_mk_cond) { 986 } elsif ($text =~ regex_mk_cond) {
987 my ($indent, $cond, $args, $comment) = ($1, $2, $3, $4); 987 my ($indent, $cond, $args, $comment) = ($1, $2, $3, $4);
988 988
989 if ($cond =~ m"^(?:if|ifdef|ifndef|for)$") { 989 if ($cond =~ m"^(?:if|ifdef|ifndef|for)$") {
990 $cond_depth++; 990 $cond_depth++;
991 } elsif ($cond =~ m"^(?:endif|endfor)$") { 991 } elsif ($cond =~ m"^(?:endif|endfor)$") {
992 $cond_depth--; 992 $cond_depth--;
993 } 993 }
994 } 994 }
995 } 995 }
996 } 996 }
997 997
998 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known tools: ".join(" ", sort(keys(%{$tools})))); 998 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known tools: ".join(" ", sort(keys(%{$tools}))));
999 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known vartools: ".join(" ", sort(keys(%{$vartools})))); 999 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known vartools: ".join(" ", sort(keys(%{$vartools}))));
1000 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Predefined tools: " . join(" ", sort(keys(%{$predefined_tools})))); 1000 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Predefined tools: " . join(" ", sort(keys(%{$predefined_tools}))));
1001 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known varnames: " . join(" ", sort(keys(%{$varname_to_toolname})))); 1001 $opt_debug_tools and log_debug(NO_FILE, NO_LINE_NUMBER, "Known varnames: " . join(" ", sort(keys(%{$varname_to_toolname}))));
@@ -1531,3871 +1531,3881 @@ sub resolve_variable_rec2($$) { @@ -1531,3871 +1531,3881 @@ sub resolve_variable_rec2($$) {
1531 $expanded =~ s/\$\{(\w+)\}/resolve_variable_rec1($1, $visited)/eg; 1531 $expanded =~ s/\$\{(\w+)\}/resolve_variable_rec1($1, $visited)/eg;
1532 return $expanded; 1532 return $expanded;
1533} 1533}
1534 1534
1535sub expand_variable($) { 1535sub expand_variable($) {
1536 my ($varname) = @_; 1536 my ($varname) = @_;
1537 1537
1538 return unless exists($pkgctx_vardef->{$varname}); 1538 return unless exists($pkgctx_vardef->{$varname});
1539 my $line = $pkgctx_vardef->{$varname}; 1539 my $line = $pkgctx_vardef->{$varname};
1540 my $value = $line->get("value"); 1540 my $value = $line->get("value");
1541 1541
1542 $value = resolve_relative_path($value, true); 1542 $value = resolve_relative_path($value, true);
1543 if ($value =~ regex_unresolved) { 1543 if ($value =~ regex_unresolved) {
1544 $opt_debug_misc and log_debug(NO_FILE, NO_LINES, "[expand_variable] Trying harder to resolve variable references in ${varname}=\"${value}\"."); 1544 $opt_debug_misc and log_debug(NO_FILE, NO_LINES, "[expand_variable] Trying harder to resolve variable references in ${varname}=\"${value}\".");
1545 $value = resolve_variable_rec2($value, {}); 1545 $value = resolve_variable_rec2($value, {});
1546 if ($value =~ regex_unresolved) { 1546 if ($value =~ regex_unresolved) {
1547 $opt_debug_misc and log_debug(NO_FILE, NO_LINES, "[expand_variable] Failed to resolve ${varname}=\"${value}\"."); 1547 $opt_debug_misc and log_debug(NO_FILE, NO_LINES, "[expand_variable] Failed to resolve ${varname}=\"${value}\".");
1548 } 1548 }
1549 } 1549 }
1550 return $value; 1550 return $value;
1551} 1551}
1552 1552
1553sub set_default_value($$) { 1553sub set_default_value($$) {
1554 my ($varref, $value) = @_; 1554 my ($varref, $value) = @_;
1555 1555
1556 if (!defined(${$varref}) || ${$varref} =~ regex_unresolved) { 1556 if (!defined(${$varref}) || ${$varref} =~ regex_unresolved) {
1557 ${$varref} = $value; 1557 ${$varref} = $value;
1558 } 1558 }
1559} 1559}
1560 1560
1561sub strip_mk_comment($) { 1561sub strip_mk_comment($) {
1562 my ($text) = @_; 1562 my ($text) = @_;
1563 1563
1564 $text =~ s/(^|[^\\])#.*/$1/; 1564 $text =~ s/(^|[^\\])#.*/$1/;
1565 $text =~ s/\\#/#/g; 1565 $text =~ s/\\#/#/g;
1566 return $text; 1566 return $text;
1567} 1567}
1568 1568
1569# Returns the value of a shell word, with one level of quoting removed. 1569# Returns the value of a shell word, with one level of quoting removed.
1570# This makes pattern matching easier when the interesting part is not 1570# This makes pattern matching easier when the interesting part is not
1571# what make(1) or sh(1) sees, but the command that is called by the 1571# what make(1) or sh(1) sees, but the command that is called by the
1572# shell. This function does not resolve or replace any variables. 1572# shell. This function does not resolve or replace any variables.
1573sub unescape_shellword($) { 1573sub unescape_shellword($) {
1574 my ($text) = @_; 1574 my ($text) = @_;
1575 1575
1576 # TODO: implement this. 1576 # TODO: implement this.
1577 assert(false, "unescape_shellword is not yet implemented."); 1577 assert(false, "unescape_shellword is not yet implemented.");
1578} 1578}
1579 1579
1580# Removes all uses of make variables from a string. 1580# Removes all uses of make variables from a string.
1581sub remove_variables($) { 1581sub remove_variables($) {
1582 my ($text) = @_; 1582 my ($text) = @_;
1583 1583
1584 while ($text =~ s/\$\{([^{}]*)\}//g) { 1584 while ($text =~ s/\$\{([^{}]*)\}//g) {
1585 } 1585 }
1586 return $text; 1586 return $text;
1587} 1587}
1588 1588
1589sub backtrace($) { 1589sub backtrace($) {
1590 my $msg = shift(); 1590 my $msg = shift();
1591 my (@callers); 1591 my (@callers);
1592 1592
1593 my $n = 0; 1593 my $n = 0;
1594 while (my @info = caller($n)) { 1594 while (my @info = caller($n)) {
1595 push(@callers, [$info[2], $info[3]]); 1595 push(@callers, [$info[2], $info[3]]);
1596 $n++; 1596 $n++;
1597 } 1597 }
1598 1598
1599 log_debug(NO_FILE, NO_LINE_NUMBER, $msg); 1599 log_debug(NO_FILE, NO_LINE_NUMBER, $msg);
1600 for (my $i = $#callers; $i >= 0; $i--) { 1600 for (my $i = $#callers; $i >= 0; $i--) {
1601 my $info = $callers[$i]; 1601 my $info = $callers[$i];
1602 log_debug(NO_FILE, NO_LINE_NUMBER, sprintf(" line %4d called %s", $info->[0], $info->[1])); 1602 log_debug(NO_FILE, NO_LINE_NUMBER, sprintf(" line %4d called %s", $info->[0], $info->[1]));
1603 } 1603 }
1604} 1604}
1605 1605
1606# Returns the number of columns that a string occupies when printed with 1606# Returns the number of columns that a string occupies when printed with
1607# a tabulator size of 8. 1607# a tabulator size of 8.
1608sub tablen($) { 1608sub tablen($) {
1609 my ($s) = @_; 1609 my ($s) = @_;
1610 my ($len); 1610 my ($len);
1611 1611
1612 $len = 0; 1612 $len = 0;
1613 foreach my $c (split(qr"", $s)) { 1613 foreach my $c (split(qr"", $s)) {
1614 if ($c eq "\t") { 1614 if ($c eq "\t") {
1615 $len = ($len + 7) & ~7; 1615 $len = ($len + 7) & ~7;
1616 } else { 1616 } else {
1617 $len++; 1617 $len++;
1618 } 1618 }
1619 } 1619 }
1620 return $len; 1620 return $len;
1621} 1621}
1622 1622
1623sub shell_split($) { 1623sub shell_split($) {
1624 my ($text) = @_; 1624 my ($text) = @_;
1625 my ($words); 1625 my ($words);
1626 1626
1627 $words = []; 1627 $words = [];
1628 while ($text =~ s/^$regex_shellword//) { 1628 while ($text =~ s/^$regex_shellword//) {
1629 push(@{$words}, $1); 1629 push(@{$words}, $1);
1630 } 1630 }
1631 return (($text =~ m"^\s*$") ? $words : false); 1631 return (($text =~ m"^\s*$") ? $words : false);
1632} 1632}
1633 1633
1634sub varname_base($) { 1634sub varname_base($) {
1635 my ($varname) = @_; 1635 my ($varname) = @_;
1636 1636
1637 return ($varname =~ m"^(.*?)\..*$") ? $1 : $varname; 1637 return ($varname =~ m"^(.*?)\..*$") ? $1 : $varname;
1638} 1638}
1639 1639
1640sub varname_canon($) { 1640sub varname_canon($) {
1641 my ($varname) = @_; 1641 my ($varname) = @_;
1642 1642
1643 return ($varname =~ m"^(.*?)\..*$") ? "$1.*" : $varname; 1643 return ($varname =~ m"^(.*?)\..*$") ? "$1.*" : $varname;
1644} 1644}
1645 1645
1646sub varname_param($) { 1646sub varname_param($) {
1647 my ($varname) = @_; 1647 my ($varname) = @_;
1648 1648
1649 return ($varname =~ m"^.*?\.(.*)$") ? $2 : undef; 1649 return ($varname =~ m"^.*?\.(.*)$") ? $2 : undef;
1650} 1650}
1651 1651
1652sub use_var($$) { 1652sub use_var($$) {
1653 my ($line, $varname) = @_; 1653 my ($line, $varname) = @_;
1654 my $varcanon = varname_canon($varname); 1654 my $varcanon = varname_canon($varname);
1655 1655
1656 if (defined($mkctx_varuse)) { 1656 if (defined($mkctx_varuse)) {
1657 $mkctx_varuse->{$varname} = $line; 1657 $mkctx_varuse->{$varname} = $line;
1658 $mkctx_varuse->{$varcanon} = $line; 1658 $mkctx_varuse->{$varcanon} = $line;
1659 } 1659 }
1660 1660
1661 if (defined($pkgctx_varuse)) { 1661 if (defined($pkgctx_varuse)) {
1662 $pkgctx_varuse->{$varname} = $line; 1662 $pkgctx_varuse->{$varname} = $line;
1663 $pkgctx_varuse->{$varcanon} = $line; 1663 $pkgctx_varuse->{$varcanon} = $line;
1664 } 1664 }
1665} 1665}
1666 1666
1667sub var_is_used($) { 1667sub var_is_used($) {
1668 my ($varname) = @_; 1668 my ($varname) = @_;
1669 my $varcanon = varname_canon($varname); 1669 my $varcanon = varname_canon($varname);
1670 1670
1671 if (defined($mkctx_varuse)) { 1671 if (defined($mkctx_varuse)) {
1672 return $mkctx_varuse->{$varname} if exists($mkctx_varuse->{$varname}); 1672 return $mkctx_varuse->{$varname} if exists($mkctx_varuse->{$varname});
1673 return $mkctx_varuse->{$varcanon} if exists($mkctx_varuse->{$varcanon}); 1673 return $mkctx_varuse->{$varcanon} if exists($mkctx_varuse->{$varcanon});
1674 } 1674 }
1675 if (defined($pkgctx_varuse)) { 1675 if (defined($pkgctx_varuse)) {
1676 return $pkgctx_varuse->{$varname} if exists($pkgctx_varuse->{$varname}); 1676 return $pkgctx_varuse->{$varname} if exists($pkgctx_varuse->{$varname});
1677 return $pkgctx_varuse->{$varcanon} if exists($pkgctx_varuse->{$varcanon}); 1677 return $pkgctx_varuse->{$varcanon} if exists($pkgctx_varuse->{$varcanon});
1678 } 1678 }
1679 return false; 1679 return false;
1680} 1680}
1681 1681
1682sub def_var($$) { 1682sub def_var($$) {
1683 my ($line, $varname) = @_; 1683 my ($line, $varname) = @_;
1684 my $varcanon = varname_canon($varname); 1684 my $varcanon = varname_canon($varname);
1685 1685
1686 if (defined($mkctx_vardef)) { 1686 if (defined($mkctx_vardef)) {
1687 $mkctx_vardef->{$varname} = $line; 1687 $mkctx_vardef->{$varname} = $line;
1688 $mkctx_vardef->{$varcanon} = $line; 1688 $mkctx_vardef->{$varcanon} = $line;
1689 } 1689 }
1690 1690
1691 if (defined($pkgctx_vardef)) { 1691 if (defined($pkgctx_vardef)) {
1692 $pkgctx_vardef->{$varname} = $line; 1692 $pkgctx_vardef->{$varname} = $line;
1693 $pkgctx_vardef->{$varcanon} = $line; 1693 $pkgctx_vardef->{$varcanon} = $line;
1694 } 1694 }
1695} 1695}
1696 1696
1697sub var_is_defined($) { 1697sub var_is_defined($) {
1698 my ($varname) = @_; 1698 my ($varname) = @_;
1699 my $varcanon = varname_canon($varname); 1699 my $varcanon = varname_canon($varname);
1700 1700
1701 if (defined($mkctx_vardef)) { 1701 if (defined($mkctx_vardef)) {
1702 return $mkctx_vardef->{$varname} if exists($mkctx_vardef->{$varname}); 1702 return $mkctx_vardef->{$varname} if exists($mkctx_vardef->{$varname});
1703 return $mkctx_vardef->{$varcanon} if exists($mkctx_vardef->{$varcanon}); 1703 return $mkctx_vardef->{$varcanon} if exists($mkctx_vardef->{$varcanon});
1704 } 1704 }
1705 if (defined($pkgctx_vardef)) { 1705 if (defined($pkgctx_vardef)) {
1706 return $pkgctx_vardef->{$varname} if exists($pkgctx_vardef->{$varname}); 1706 return $pkgctx_vardef->{$varname} if exists($pkgctx_vardef->{$varname});
1707 return $pkgctx_vardef->{$varcanon} if exists($pkgctx_vardef->{$varcanon}); 1707 return $pkgctx_vardef->{$varcanon} if exists($pkgctx_vardef->{$varcanon});
1708 } 1708 }
1709 return false; 1709 return false;
1710} 1710}
1711 1711
1712sub determine_used_variables($) { 1712sub determine_used_variables($) {
1713 my ($lines) = @_; 1713 my ($lines) = @_;
1714 my ($rest); 1714 my ($rest);
1715 1715
1716 foreach my $line (@{$lines}) { 1716 foreach my $line (@{$lines}) {
1717 $rest = $line->text; 1717 $rest = $line->text;
1718 while ($rest =~ s/(?:\$\{|\$\(|defined\(|empty\()([0-9+.A-Z_a-z]+)[:})]//) { 1718 while ($rest =~ s/(?:\$\{|\$\(|defined\(|empty\()([0-9+.A-Z_a-z]+)[:})]//) {
1719 my ($varname) = ($1); 1719 my ($varname) = ($1);
1720 use_var($line, $varname); 1720 use_var($line, $varname);
1721 $opt_debug_unused and $line->log_debug("Variable ${varname} is used."); 1721 $opt_debug_unused and $line->log_debug("Variable ${varname} is used.");
1722 } 1722 }
1723 } 1723 }
1724} 1724}
1725 1725
1726sub extract_used_variables($$) { 1726sub extract_used_variables($$) {
1727 my ($line, $text) = @_; 1727 my ($line, $text) = @_;
1728 my ($rest, $result); 1728 my ($rest, $result);
1729 1729
1730 $rest = $text; 1730 $rest = $text;
1731 $result = []; 1731 $result = [];
1732 while ($rest =~ s/^(?:[^\$]+|\$[\$*<>?\@]|\$\{([.0-9A-Z_a-z]+)(?::(?:[^\${}]|\$[^{])+)?\})//) { 1732 while ($rest =~ s/^(?:[^\$]+|\$[\$*<>?\@]|\$\{([.0-9A-Z_a-z]+)(?::(?:[^\${}]|\$[^{])+)?\})//) {
1733 my ($varname) = ($1); 1733 my ($varname) = ($1);
1734 1734
1735 if (defined($varname)) { 1735 if (defined($varname)) {
1736 push(@{$result}, $varname); 1736 push(@{$result}, $varname);
1737 } 1737 }
1738 } 1738 }
1739 1739
1740 if ($rest ne "") { 1740 if ($rest ne "") {
1741 $opt_debug_misc and $line->log_warning("Could not extract variables: ${rest}"); 1741 $opt_debug_misc and $line->log_warning("Could not extract variables: ${rest}");
1742 } 1742 }
1743 1743
1744 return $result; 1744 return $result;
1745} 1745}
1746 1746
1747sub get_nbpart() { 1747sub get_nbpart() {
1748 my $line = $pkgctx_vardef->{"PKGREVISION"}; 1748 my $line = $pkgctx_vardef->{"PKGREVISION"};
1749 return "" unless defined($line); 1749 return "" unless defined($line);
1750 my $pkgrevision = $line->get("value"); 1750 my $pkgrevision = $line->get("value");
1751 return "" unless $pkgrevision =~ m"^\d+$"; 1751 return "" unless $pkgrevision =~ m"^\d+$";
1752 return "" unless $pkgrevision + 0 != 0; 1752 return "" unless $pkgrevision + 0 != 0;
1753 return "nb$pkgrevision"; 1753 return "nb$pkgrevision";
1754} 1754}
1755 1755
1756my $check_pkglint_version_done = false; 1756my $check_pkglint_version_done = false;
1757sub check_pkglint_version() { 1757sub check_pkglint_version() {
1758 1758
1759 return if $check_pkglint_version_done; 1759 return if $check_pkglint_version_done;
1760 $check_pkglint_version_done = true; 1760 $check_pkglint_version_done = true;
1761 1761
1762 my $lines = load_lines("${cwd_pkgsrcdir}/pkgtools/pkglint/Makefile", true); 1762 my $lines = load_lines("${cwd_pkgsrcdir}/pkgtools/pkglint/Makefile", true);
1763 return unless $lines; 1763 return unless $lines;
1764 1764
1765 my $pkglint_version = undef; 1765 my $pkglint_version = undef;
1766 foreach my $line (@{$lines}) { 1766 foreach my $line (@{$lines}) {
1767 if ($line->text =~ regex_varassign) { 1767 if ($line->text =~ regex_varassign) {
1768 my ($varname, undef, $value, undef) = ($1, $2, $3, $4); 1768 my ($varname, undef, $value, undef) = ($1, $2, $3, $4);
1769 1769
1770 if ($varname eq "DISTNAME" || $varname eq "PKGNAME") { 1770 if ($varname eq "DISTNAME" || $varname eq "PKGNAME") {
1771 if ($value =~ regex_pkgname) { 1771 if ($value =~ regex_pkgname) {
1772 $pkglint_version = $2; 1772 $pkglint_version = $2;
1773 } 1773 }
1774 } 1774 }
1775 } 1775 }
1776 } 1776 }
1777 return unless defined($pkglint_version); 1777 return unless defined($pkglint_version);
1778 1778
1779 if (dewey_cmp($pkglint_version, ">", conf_distver)) { 1779 if (dewey_cmp($pkglint_version, ">", conf_distver)) {
1780 log_note(NO_FILE, NO_LINE_NUMBER, "A newer version of pkglint is available."); 1780 log_note(NO_FILE, NO_LINE_NUMBER, "A newer version of pkglint is available.");
1781 } elsif (dewey_cmp($pkglint_version, "<", conf_distver)) { 1781 } elsif (dewey_cmp($pkglint_version, "<", conf_distver)) {
1782 log_error(NO_FILE, NO_LINE_NUMBER, "The pkglint version is newer than the tree to check."); 1782 log_error(NO_FILE, NO_LINE_NUMBER, "The pkglint version is newer than the tree to check.");
1783 } 1783 }
1784} 1784}
1785 1785
1786# When processing a file using the expect* subroutines below, it may 1786# When processing a file using the expect* subroutines below, it may
1787# happen that $lineno points past the end of the file. In that case, 1787# happen that $lineno points past the end of the file. In that case,
1788# print the warning without associated source code. 1788# print the warning without associated source code.
1789sub lines_log_warning($$$) { 1789sub lines_log_warning($$$) {
1790 my ($lines, $lineno, $msg) = @_; 1790 my ($lines, $lineno, $msg) = @_;
1791 1791
1792 assert(0 <= $lineno, "The line number is negative (${lineno})."); 1792 assert(0 <= $lineno, "The line number is negative (${lineno}).");
1793 assert(@{$lines} != 0, "The lines may not be empty."); 1793 assert(@{$lines} != 0, "The lines may not be empty.");
1794 1794
1795 if ($lineno <= $#{$lines}) { 1795 if ($lineno <= $#{$lines}) {
1796 $lines->[$lineno]->log_warning($msg); 1796 $lines->[$lineno]->log_warning($msg);
1797 } else { 1797 } else {
1798 log_warning($lines->[0]->fname, "EOF", $msg); 1798 log_warning($lines->[0]->fname, "EOF", $msg);
1799 } 1799 }
1800} 1800}
1801 1801
1802# Checks if the current line ($lines->{${$lineno_ref}}) matches the 1802# Checks if the current line ($lines->{${$lineno_ref}}) matches the
1803# regular expression, and if it does, increments ${${lineno_ref}}. 1803# regular expression, and if it does, increments ${${lineno_ref}}.
1804# @param $lines 1804# @param $lines
1805# The lines that are checked. 1805# The lines that are checked.
1806# @param $lineno_ref 1806# @param $lineno_ref
1807# A reference to the line number, an integer variable. 1807# A reference to the line number, an integer variable.
1808# @param $regex 1808# @param $regex
1809# The regular expression to be checked. 1809# The regular expression to be checked.
1810# @return 1810# @return
1811# The result of the regular expression match or false. 1811# The result of the regular expression match or false.
1812sub expect($$$) { 1812sub expect($$$) {
1813 my ($lines, $lineno_ref, $regex) = @_; 1813 my ($lines, $lineno_ref, $regex) = @_;
1814 my $lineno = ${$lineno_ref}; 1814 my $lineno = ${$lineno_ref};
1815 1815
1816 if ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ $regex) { 1816 if ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ $regex) {
1817 ${$lineno_ref}++; 1817 ${$lineno_ref}++;
1818 return PkgLint::SimpleMatch->new($lines->[$lineno]->text, \@-, \@+); 1818 return PkgLint::SimpleMatch->new($lines->[$lineno]->text, \@-, \@+);
1819 } else { 1819 } else {
1820 return false; 1820 return false;
1821 } 1821 }
1822} 1822}
1823 1823
1824sub expect_empty_line($$) { 1824sub expect_empty_line($$) {
1825 my ($lines, $lineno_ref) = @_; 1825 my ($lines, $lineno_ref) = @_;
1826 1826
1827 if (expect($lines, $lineno_ref, qr"^$")) { 1827 if (expect($lines, $lineno_ref, qr"^$")) {
1828 return true; 1828 return true;
1829 } else { 1829 } else {
1830 $opt_warn_space and $lines->[${$lineno_ref}]->log_note("Empty line expected."); 1830 $opt_warn_space and $lines->[${$lineno_ref}]->log_note("Empty line expected.");
1831 return false; 1831 return false;
1832 } 1832 }
1833} 1833}
1834 1834
1835sub expect_text($$$) { 1835sub expect_text($$$) {
1836 my ($lines, $lineno_ref, $text) = @_; 1836 my ($lines, $lineno_ref, $text) = @_;
1837 1837
1838 my $rv = expect($lines, $lineno_ref, qr"^\Q${text}\E$"); 1838 my $rv = expect($lines, $lineno_ref, qr"^\Q${text}\E$");
1839 $rv or lines_log_warning($lines, ${$lineno_ref}, "Expected \"${text}\"."); 1839 $rv or lines_log_warning($lines, ${$lineno_ref}, "Expected \"${text}\".");
1840 return $rv; 1840 return $rv;
1841} 1841}
1842 1842
1843sub expect_re($$$) { 1843sub expect_re($$$) {
1844 my ($lines, $lineno_ref, $re) = @_; 1844 my ($lines, $lineno_ref, $re) = @_;
1845 1845
1846 my $rv = expect($lines, $lineno_ref, $re); 1846 my $rv = expect($lines, $lineno_ref, $re);
1847 $rv or lines_log_warning($lines, ${$lineno_ref}, "Expected text matching $re."); 1847 $rv or lines_log_warning($lines, ${$lineno_ref}, "Expected text matching $re.");
1848 return $rv; 1848 return $rv;
1849} 1849}
1850 1850
1851# Returns an object of type Pkglint::Type that represents the type of 1851# Returns an object of type Pkglint::Type that represents the type of
1852# the variable (maybe guessed based on the variable name), or undef if 1852# the variable (maybe guessed based on the variable name), or undef if
1853# the type cannot even be guessed. 1853# the type cannot even be guessed.
1854# 1854#
1855sub get_variable_type($$) { 1855sub get_variable_type($$) {
1856 my ($line, $varname) = @_; 1856 my ($line, $varname) = @_;
1857 my ($type); 1857 my ($type);
1858 1858
1859 assert(defined($varname), "The varname parameter must be defined."); 1859 assert(defined($varname), "The varname parameter must be defined.");
1860 1860
1861 if (exists(get_vartypes_map()->{$varname})) { 1861 if (exists(get_vartypes_map()->{$varname})) {
1862 return get_vartypes_map()->{$varname}; 1862 return get_vartypes_map()->{$varname};
1863 } 1863 }
1864 1864
1865 my $varcanon = varname_canon($varname); 1865 my $varcanon = varname_canon($varname);
1866 if (exists(get_vartypes_map()->{$varcanon})) { 1866 if (exists(get_vartypes_map()->{$varcanon})) {
1867 return get_vartypes_map()->{$varcanon}; 1867 return get_vartypes_map()->{$varcanon};
1868 } 1868 }
1869 1869
1870 if (exists(get_varname_to_toolname()->{$varname})) { 1870 if (exists(get_varname_to_toolname()->{$varname})) {
1871 return PkgLint::Type->new(LK_NONE, "ShellCommand", [[ qr".*", "u" ]], NOT_GUESSED); 1871 return PkgLint::Type->new(LK_NONE, "ShellCommand", [[ qr".*", "u" ]], NOT_GUESSED);
1872 } 1872 }
1873 1873
1874 if ($varname =~ m"^TOOLS_(.*)" && exists(get_varname_to_toolname()->{$1})) { 1874 if ($varname =~ m"^TOOLS_(.*)" && exists(get_varname_to_toolname()->{$1})) {
1875 return PkgLint::Type->new(LK_NONE, "Pathname", [[ qr".*", "u" ]], NOT_GUESSED); 1875 return PkgLint::Type->new(LK_NONE, "Pathname", [[ qr".*", "u" ]], NOT_GUESSED);
1876 } 1876 }
1877 1877
1878 use constant allow_all => [[ qr".*", "adpsu" ]]; 1878 use constant allow_all => [[ qr".*", "adpsu" ]];
1879 use constant allow_runtime => [[ qr".*", "adsu" ]]; 1879 use constant allow_runtime => [[ qr".*", "adsu" ]];
1880 1880
1881 # Guess the datatype of the variable based on 1881 # Guess the datatype of the variable based on
1882 # naming conventions. 1882 # naming conventions.
1883 $type = ($varname =~ m"DIRS$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathmask", allow_runtime, GUESSED) 1883 $type = ($varname =~ m"DIRS$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathmask", allow_runtime, GUESSED)
1884 : ($varname =~ m"(?:DIR|_HOME)$") ? PkgLint::Type->new(LK_NONE, "Pathname", allow_runtime, GUESSED) 1884 : ($varname =~ m"(?:DIR|_HOME)$") ? PkgLint::Type->new(LK_NONE, "Pathname", allow_runtime, GUESSED)
1885 : ($varname =~ m"FILES$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathmask", allow_runtime, GUESSED) 1885 : ($varname =~ m"FILES$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathmask", allow_runtime, GUESSED)
1886 : ($varname =~ m"FILE$") ? PkgLint::Type->new(LK_NONE, "Pathname", allow_runtime, GUESSED) 1886 : ($varname =~ m"FILE$") ? PkgLint::Type->new(LK_NONE, "Pathname", allow_runtime, GUESSED)
1887 : ($varname =~ m"PATH$") ? PkgLint::Type->new(LK_NONE, "Pathlist", allow_runtime, GUESSED) 1887 : ($varname =~ m"PATH$") ? PkgLint::Type->new(LK_NONE, "Pathlist", allow_runtime, GUESSED)
1888 : ($varname =~ m"PATHS$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathname", allow_runtime, GUESSED) 1888 : ($varname =~ m"PATHS$") ? PkgLint::Type->new(LK_EXTERNAL, "Pathname", allow_runtime, GUESSED)
1889 : ($varname =~ m"_USER$") ? PkgLint::Type->new(LK_NONE, "UserGroupName", allow_all, GUESSED) 1889 : ($varname =~ m"_USER$") ? PkgLint::Type->new(LK_NONE, "UserGroupName", allow_all, GUESSED)
1890 : ($varname =~ m"_GROUP$") ? PkgLint::Type->new(LK_NONE, "UserGroupName", allow_all, GUESSED) 1890 : ($varname =~ m"_GROUP$") ? PkgLint::Type->new(LK_NONE, "UserGroupName", allow_all, GUESSED)
1891 : ($varname =~ m"_ENV$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED) 1891 : ($varname =~ m"_ENV$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED)
1892 : ($varname =~ m"_CMD$") ? PkgLint::Type->new(LK_NONE, "ShellCommand", allow_runtime, GUESSED) 1892 : ($varname =~ m"_CMD$") ? PkgLint::Type->new(LK_NONE, "ShellCommand", allow_runtime, GUESSED)
1893 : ($varname =~ m"_ARGS$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED) 1893 : ($varname =~ m"_ARGS$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED)
1894 : ($varname =~ m"_(?:C|CPP|CXX|LD|)FLAGS$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED) 1894 : ($varname =~ m"_(?:C|CPP|CXX|LD|)FLAGS$") ? PkgLint::Type->new(LK_EXTERNAL, "ShellWord", allow_runtime, GUESSED)
1895 : ($varname =~ m"_MK$") ? PkgLint::Type->new(LK_NONE, "Unchecked", allow_all, GUESSED) 1895 : ($varname =~ m"_MK$") ? PkgLint::Type->new(LK_NONE, "Unchecked", allow_all, GUESSED)
1896 : ($varname =~ m"^PLIST.") ? PkgLint::Type->new(LK_NONE, "Yes", allow_all, GUESSED) 1896 : ($varname =~ m"^PLIST.") ? PkgLint::Type->new(LK_NONE, "Yes", allow_all, GUESSED)
1897 : undef; 1897 : undef;
1898 1898
1899 if (defined($type)) { 1899 if (defined($type)) {
1900 $opt_debug_vartypes and $line->log_debug("The guessed type of ${varname} is \"" . $type->to_string . "\"."); 1900 $opt_debug_vartypes and $line->log_debug("The guessed type of ${varname} is \"" . $type->to_string . "\".");
1901 return $type; 1901 return $type;
1902 } 1902 }
1903 1903
1904 $opt_debug_vartypes and $line->log_debug("No type definition found for ${varcanon}."); 1904 $opt_debug_vartypes and $line->log_debug("No type definition found for ${varcanon}.");
1905 return undef; 1905 return undef;
1906} 1906}
1907 1907
1908sub get_variable_perms($$) { 1908sub get_variable_perms($$) {
1909 my ($line, $varname) = @_; 1909 my ($line, $varname) = @_;
1910 1910
1911 my $type = get_variable_type($line, $varname); 1911 my $type = get_variable_type($line, $varname);
1912 if (!defined($type)) { 1912 if (!defined($type)) {
1913 $opt_debug_misc and $line->log_debug("No type definition found for ${varname}."); 1913 $opt_debug_misc and $line->log_debug("No type definition found for ${varname}.");
1914 return "adpsu"; 1914 return "adpsu";
1915 } 1915 }
1916 1916
1917 my $perms = $type->perms($line->fname, $varname); 1917 my $perms = $type->perms($line->fname, $varname);
1918 if (!defined($perms)) { 1918 if (!defined($perms)) {
1919 $opt_debug_misc and $line->log_debug("No permissions specified for ${varname}."); 1919 $opt_debug_misc and $line->log_debug("No permissions specified for ${varname}.");
1920 return "?"; 1920 return "?";
1921 } 1921 }
1922 return $perms; 1922 return $perms;
1923} 1923}
1924 1924
1925# This function returns whether a variable needs the :Q operator in a 1925# This function returns whether a variable needs the :Q operator in a
1926# certain context. There are four possible outcomes: 1926# certain context. There are four possible outcomes:
1927# 1927#
1928# false: The variable should not be quoted. 1928# false: The variable should not be quoted.
1929# true: The variable should be quoted. 1929# true: The variable should be quoted.
1930# doesnt_matter: 1930# doesnt_matter:
1931# Since the values of the variable usually don't contain 1931# Since the values of the variable usually don't contain
1932# special characters, it does not matter whether the 1932# special characters, it does not matter whether the
1933# variable is quoted or not. 1933# variable is quoted or not.
1934# dont_know: pkglint cannot say whether the variable should be quoted 1934# dont_know: pkglint cannot say whether the variable should be quoted
1935# or not, most likely because type information is missing. 1935# or not, most likely because type information is missing.
1936# 1936#
1937sub variable_needs_quoting($$$) { 1937sub variable_needs_quoting($$$) {
1938 my ($line, $varname, $context) = @_; 1938 my ($line, $varname, $context) = @_;
1939 my $type = get_variable_type($line, $varname); 1939 my $type = get_variable_type($line, $varname);
1940 my ($want_list, $have_list); 1940 my ($want_list, $have_list);
1941 1941
1942 $opt_debug_trace and $line->log_debug("variable_needs_quoting($varname, " . $context->to_string() . ")"); 1942 $opt_debug_trace and $line->log_debug("variable_needs_quoting($varname, " . $context->to_string() . ")");
1943 1943
1944 use constant safe_types => array_to_hash(qw( 1944 use constant safe_types => array_to_hash(qw(
1945 DistSuffix 1945 DistSuffix
1946 FileMode Filename 1946 FileMode Filename
1947 Identifier 1947 Identifier
1948 Option 1948 Option
1949 Pathname PkgName PkgOptionsVar PkgRevision 1949 Pathname PkgName PkgOptionsVar PkgRevision
1950 RelativePkgDir RelativePkgPath 1950 RelativePkgDir RelativePkgPath
1951 UserGroupName 1951 UserGroupName
1952 Varname Version 1952 Varname Version
1953 WrkdirSubdirectory 1953 WrkdirSubdirectory
1954 )); 1954 ));
1955 1955
1956 if (!defined($type) || !defined($context->type)) { 1956 if (!defined($type) || !defined($context->type)) {
1957 return dont_know; 1957 return dont_know;
1958 } 1958 }
1959 1959
1960 # Variables of certain predefined types, as well as all 1960 # Variables of certain predefined types, as well as all
1961 # enumerations, are expected to not require the :Q operator. 1961 # enumerations, are expected to not require the :Q operator.
1962 if (ref($type->basic_type) eq "HASH" || exists(safe_types->{$type->basic_type})) { 1962 if (ref($type->basic_type) eq "HASH" || exists(safe_types->{$type->basic_type})) {
1963 if ($type->kind_of_list == LK_NONE) { 1963 if ($type->kind_of_list == LK_NONE) {
1964 return doesnt_matter; 1964 return doesnt_matter;
1965 1965
1966 } elsif ($type->kind_of_list == LK_EXTERNAL && $context->extent != VUC_EXTENT_WORD_PART) { 1966 } elsif ($type->kind_of_list == LK_EXTERNAL && $context->extent != VUC_EXTENT_WORD_PART) {
1967 return false; 1967 return false;
1968 } 1968 }
1969 } 1969 }
1970 1970
1971 # In .for loops, the :Q operator is always misplaced, since 1971 # In .for loops, the :Q operator is always misplaced, since
1972 # the items are broken up at white-space, not as shell words 1972 # the items are broken up at white-space, not as shell words
1973 # like in all other parts of make(1). 1973 # like in all other parts of make(1).
1974 if ($context->shellword == VUC_SHELLWORD_FOR) { 1974 if ($context->shellword == VUC_SHELLWORD_FOR) {
1975 return false; 1975 return false;
1976 } 1976 }
1977 1977
1978 # Determine whether the context expects a list of shell words or 1978 # Determine whether the context expects a list of shell words or
1979 # not. 1979 # not.
1980 $want_list = $context->type->is_practically_a_list() && ($context->shellword == VUC_SHELLWORD_BACKT || $context->extent != VUC_EXTENT_WORD_PART); 1980 $want_list = $context->type->is_practically_a_list() && ($context->shellword == VUC_SHELLWORD_BACKT || $context->extent != VUC_EXTENT_WORD_PART);
1981 $have_list = $type->is_practically_a_list(); 1981 $have_list = $type->is_practically_a_list();
1982 1982
1983 $opt_debug_quoting and $line->log_debug("[variable_needs_quoting]" 1983 $opt_debug_quoting and $line->log_debug("[variable_needs_quoting]"
1984 . " varname=$varname" 1984 . " varname=$varname"
1985 . " context=" . $context->to_string() 1985 . " context=" . $context->to_string()
1986 . " type=" . $type->to_string() 1986 . " type=" . $type->to_string()
1987 . " want_list=" . ($want_list ? "yes" : "no") 1987 . " want_list=" . ($want_list ? "yes" : "no")
1988 . " have_list=" . ($have_list ? "yes" : "no") 1988 . " have_list=" . ($have_list ? "yes" : "no")
1989 . "."); 1989 . ".");
1990 1990
1991 # A shell word may appear as part of a shell word, for example 1991 # A shell word may appear as part of a shell word, for example
1992 # COMPILER_RPATH_FLAG. 1992 # COMPILER_RPATH_FLAG.
1993 if ($context->extent == VUC_EXTENT_WORD_PART && $context->shellword == VUC_SHELLWORD_PLAIN) { 1993 if ($context->extent == VUC_EXTENT_WORD_PART && $context->shellword == VUC_SHELLWORD_PLAIN) {
1994 if ($type->kind_of_list == LK_NONE && $type->basic_type eq "ShellWord") { 1994 if ($type->kind_of_list == LK_NONE && $type->basic_type eq "ShellWord") {
1995 return false; 1995 return false;
1996 } 1996 }
1997 } 1997 }
1998 1998
1999 # Assume that the tool definitions don't include very special 1999 # Assume that the tool definitions don't include very special
2000 # characters, so they can safely be used inside any quotes. 2000 # characters, so they can safely be used inside any quotes.
2001 if (exists(get_varname_to_toolname()->{$varname})) { 2001 if (exists(get_varname_to_toolname()->{$varname})) {
2002 my $sw = $context->shellword; 2002 my $sw = $context->shellword;
2003 2003
2004 if ($sw == VUC_SHELLWORD_PLAIN && $context->extent != VUC_EXTENT_WORD_PART) { 2004 if ($sw == VUC_SHELLWORD_PLAIN && $context->extent != VUC_EXTENT_WORD_PART) {
2005 return false; 2005 return false;
2006 2006
2007 } elsif ($sw == VUC_SHELLWORD_BACKT) { 2007 } elsif ($sw == VUC_SHELLWORD_BACKT) {
2008 return false; 2008 return false;
2009 2009
2010 } elsif ($sw == VUC_SHELLWORD_DQUOT || $sw == VUC_SHELLWORD_SQUOT) { 2010 } elsif ($sw == VUC_SHELLWORD_DQUOT || $sw == VUC_SHELLWORD_SQUOT) {
2011 return doesnt_matter; 2011 return doesnt_matter;
2012 2012
2013 } else { 2013 } else {
2014 # Let the other rules decide. 2014 # Let the other rules decide.
2015 } 2015 }
2016 } 2016 }
2017 2017
2018 # Variables that appear as parts of shell words generally need 2018 # Variables that appear as parts of shell words generally need
2019 # to be quoted. An exception is in the case of backticks, 2019 # to be quoted. An exception is in the case of backticks,
2020 # because the whole backticks expression is parsed as a single 2020 # because the whole backticks expression is parsed as a single
2021 # shell word by pkglint. 2021 # shell word by pkglint.
2022 # 2022 #
2023 # XXX: When the shell word parser gets rewritten the next time, 2023 # XXX: When the shell word parser gets rewritten the next time,
2024 # this test can be refined. 2024 # this test can be refined.
2025 if ($context->extent == VUC_EXTENT_WORD_PART && $context->shellword != VUC_SHELLWORD_BACKT) { 2025 if ($context->extent == VUC_EXTENT_WORD_PART && $context->shellword != VUC_SHELLWORD_BACKT) {
2026 return true; 2026 return true;
2027 } 2027 }
2028 2028
2029 # Assigning lists to lists does not require any quoting, though 2029 # Assigning lists to lists does not require any quoting, though
2030 # there may be cases like "CONFIGURE_ARGS+= -libs ${LDFLAGS:Q}" 2030 # there may be cases like "CONFIGURE_ARGS+= -libs ${LDFLAGS:Q}"
2031 # where quoting is necessary. So let's hope that no developer 2031 # where quoting is necessary. So let's hope that no developer
2032 # ever makes the mistake of using :Q when appending a list to 2032 # ever makes the mistake of using :Q when appending a list to
2033 # a list. 2033 # a list.
2034 if ($want_list && $have_list) { 2034 if ($want_list && $have_list) {
2035 return doesnt_matter; 2035 return doesnt_matter;
2036 } 2036 }
2037 2037
2038 # Appending elements to a list requires quoting, as well as 2038 # Appending elements to a list requires quoting, as well as
2039 # assigning a list value to a non-list variable. 2039 # assigning a list value to a non-list variable.
2040 if ($want_list != $have_list) { 2040 if ($want_list != $have_list) {
2041 return true; 2041 return true;
2042 } 2042 }
2043 2043
2044 $opt_debug_quoting and $line->log_debug("Don't know whether :Q is needed for ${varname}."); 2044 $opt_debug_quoting and $line->log_debug("Don't know whether :Q is needed for ${varname}.");
2045 return dont_know; 2045 return dont_know;
2046} 2046}
2047 2047
2048# 2048#
2049# Parsing. 2049# Parsing.
2050# 2050#
2051 2051
2052# Checks whether $tree matches $pattern, and if so, instanciates the 2052# Checks whether $tree matches $pattern, and if so, instanciates the
2053# variables in $pattern. If they don't match, some variables may be 2053# variables in $pattern. If they don't match, some variables may be
2054# instanciated nevertheless, but the exact behavior is unspecified. 2054# instanciated nevertheless, but the exact behavior is unspecified.
2055# 2055#
2056sub tree_match($$); 2056sub tree_match($$);
2057sub tree_match($$) { 2057sub tree_match($$) {
2058 my ($tree, $pattern) = @_; 2058 my ($tree, $pattern) = @_;
2059 2059
2060 my $d1 = Data::Dumper->new([$tree, $pattern])->Terse(true)->Indent(0); 2060 my $d1 = Data::Dumper->new([$tree, $pattern])->Terse(true)->Indent(0);
2061 my $d2 = Data::Dumper->new([$pattern])->Terse(true)->Indent(0); 2061 my $d2 = Data::Dumper->new([$pattern])->Terse(true)->Indent(0);
2062 $opt_debug_trace and log_debug(NO_FILE, NO_LINES, sprintf("tree_match(%s, %s)", $d1->Dump, $d2->Dump)); 2062 $opt_debug_trace and log_debug(NO_FILE, NO_LINES, sprintf("tree_match(%s, %s)", $d1->Dump, $d2->Dump));
2063 2063
2064 return true if (!defined($tree) && !defined($pattern)); 2064 return true if (!defined($tree) && !defined($pattern));
2065 return false if (!defined($tree) || !defined($pattern)); 2065 return false if (!defined($tree) || !defined($pattern));
2066 my $aref = ref($tree); 2066 my $aref = ref($tree);
2067 my $pref = ref($pattern); 2067 my $pref = ref($pattern);
2068 if ($pref eq "SCALAR" && !defined($$pattern)) { 2068 if ($pref eq "SCALAR" && !defined($$pattern)) {
2069 $$pattern = $tree; 2069 $$pattern = $tree;
2070 return true; 2070 return true;
2071 } 2071 }
2072 if ($aref eq "" && ($pref eq "" || $pref eq "SCALAR")) { 2072 if ($aref eq "" && ($pref eq "" || $pref eq "SCALAR")) {
2073 return $tree eq $pattern; 2073 return $tree eq $pattern;
2074 } 2074 }
2075 if ($aref eq "ARRAY" && $pref eq "ARRAY") { 2075 if ($aref eq "ARRAY" && $pref eq "ARRAY") {
2076 return false if scalar(@$tree) != scalar(@$pattern); 2076 return false if scalar(@$tree) != scalar(@$pattern);
2077 for (my $i = 0; $i < scalar(@$tree); $i++) { 2077 for (my $i = 0; $i < scalar(@$tree); $i++) {
2078 return false unless tree_match($tree->[$i], $pattern->[$i]); 2078 return false unless tree_match($tree->[$i], $pattern->[$i]);
2079 } 2079 }
2080 return true; 2080 return true;
2081 } 2081 }
2082 return false; 2082 return false;
2083} 2083}
2084 2084
2085# TODO: Needs to be redesigned to handle more complex expressions. 2085# TODO: Needs to be redesigned to handle more complex expressions.
2086sub parse_mk_cond($$); 2086sub parse_mk_cond($$);
2087sub parse_mk_cond($$) { 2087sub parse_mk_cond($$) {
2088 my ($line, $cond) = @_; 2088 my ($line, $cond) = @_;
2089 2089
2090 $opt_debug_trace and $line->log_debug("parse_mk_cond(\"${cond}\")"); 2090 $opt_debug_trace and $line->log_debug("parse_mk_cond(\"${cond}\")");
2091 2091
2092 my $re_simple_varname = qr"[A-Z_][A-Z0-9_]*(?:\.[\w_+\-]+)?"; 2092 my $re_simple_varname = qr"[A-Z_][A-Z0-9_]*(?:\.[\w_+\-]+)?";
2093 while ($cond ne "") { 2093 while ($cond ne "") {
2094 if ($cond =~ s/^!//) { 2094 if ($cond =~ s/^!//) {
2095 return ["not", parse_mk_cond($line, $cond)]; 2095 return ["not", parse_mk_cond($line, $cond)];
2096 } elsif ($cond =~ s/^defined\((${re_simple_varname})\)$//) { 2096 } elsif ($cond =~ s/^defined\((${re_simple_varname})\)$//) {
2097 return ["defined", $1]; 2097 return ["defined", $1];
2098 } elsif ($cond =~ s/^empty\((${re_simple_varname})\)$//) { 2098 } elsif ($cond =~ s/^empty\((${re_simple_varname})\)$//) {
2099 return ["empty", $1]; 2099 return ["empty", $1];
2100 } elsif ($cond =~ s/^empty\((${re_simple_varname}):M([^\$:{})]+)\)$//) { 2100 } elsif ($cond =~ s/^empty\((${re_simple_varname}):M([^\$:{})]+)\)$//) {
2101 return ["empty", ["match", $1, $2]]; 2101 return ["empty", ["match", $1, $2]];
2102 } elsif ($cond =~ s/^\$\{(${re_simple_varname})\}\s+(==|!=)\s+"([^"\$\\]*)"$//) { 2102 } elsif ($cond =~ s/^\$\{(${re_simple_varname})\}\s+(==|!=)\s+"([^"\$\\]*)"$//) {
2103 return [$2, ["var", $1], ["string", $3]]; 2103 return [$2, ["var", $1], ["string", $3]];
2104 } else { 2104 } else {
2105 $opt_debug_unchecked and $line->log_debug("parse_mk_cond: ${cond}"); 2105 $opt_debug_unchecked and $line->log_debug("parse_mk_cond: ${cond}");
2106 return ["unknown", $cond]; 2106 return ["unknown", $cond];
2107 } 2107 }
2108 } 2108 }
2109} 2109}
2110 2110
2111sub parse_licenses($) { 2111sub parse_licenses($) {
2112 my ($licenses) = @_; 2112 my ($licenses) = @_;
2113 2113
2114 # XXX: this is clearly cheating 2114 # XXX: this is clearly cheating
2115 $licenses =~ s,\${PERL5_LICENSE},gnu-gpl-v2 OR artistic,g; 2115 $licenses =~ s,\${PERL5_LICENSE},gnu-gpl-v2 OR artistic,g;
2116 $licenses =~ s,[()]|AND|OR,,g; 2116 $licenses =~ s,[()]|AND|OR,,g;
2117 my @licenses = split(/\s+/, $licenses); 2117 my @licenses = split(/\s+/, $licenses);
2118 return \@licenses; 2118 return \@licenses;
2119} 2119}
2120 2120
2121# This procedure fills in the extra fields of a line, depending on the 2121# This procedure fills in the extra fields of a line, depending on the
2122# line type. These fields can later be queried without having to parse 2122# line type. These fields can later be queried without having to parse
2123# them again and again. 2123# them again and again.
2124# 2124#
2125sub parseline_mk($) { 2125sub parseline_mk($) {
2126 my ($line) = @_; 2126 my ($line) = @_;
2127 my $text = $line->text; 2127 my $text = $line->text;
2128 2128
2129 if ($text =~ regex_varassign) { 2129 if ($text =~ regex_varassign) {
2130 my ($varname, $op, $value, $comment) = ($1, $2, $3, $4); 2130 my ($varname, $op, $value, $comment) = ($1, $2, $3, $4);
2131 2131
2132 # In variable assignments, a '#' character is preceded 2132 # In variable assignments, a '#' character is preceded
2133 # by a backslash. In shell commands, it is interpreted 2133 # by a backslash. In shell commands, it is interpreted
2134 # literally. 2134 # literally.
2135 $value =~ s/\\\#/\#/g; 2135 $value =~ s/\\\#/\#/g;
2136 2136
2137 $line->set("is_varassign", true); 2137 $line->set("is_varassign", true);
2138 $line->set("varname", $varname); 2138 $line->set("varname", $varname);
2139 $line->set("varcanon", varname_canon($varname)); 2139 $line->set("varcanon", varname_canon($varname));
2140 my $varparam = varname_param($varname); 2140 my $varparam = varname_param($varname);
2141 defined($varparam) and $line->set("varparam", $varparam); 2141 defined($varparam) and $line->set("varparam", $varparam);
2142 $line->set("op", $op); 2142 $line->set("op", $op);
2143 $line->set("value", $value); 2143 $line->set("value", $value);
2144 defined($comment) and $line->set("comment", $comment); 2144 defined($comment) and $line->set("comment", $comment);
2145 2145
2146 } elsif ($text =~ regex_mk_shellcmd) { 2146 } elsif ($text =~ regex_mk_shellcmd) {
2147 my ($shellcmd) = ($1); 2147 my ($shellcmd) = ($1);
2148 2148
2149 # Shell command lines cannot have embedded comments. 2149 # Shell command lines cannot have embedded comments.
2150 $line->set("is_shellcmd", true); 2150 $line->set("is_shellcmd", true);
2151 $line->set("shellcmd", $shellcmd); 2151 $line->set("shellcmd", $shellcmd);
2152 2152
2153 my ($shellwords, $rest) = match_all($shellcmd, $regex_shellword); 2153 my ($shellwords, $rest) = match_all($shellcmd, $regex_shellword);
2154 $line->set("shellwords", $shellwords); 2154 $line->set("shellwords", $shellwords);
2155 if ($rest !~ m"^\s*$") { 2155 if ($rest !~ m"^\s*$") {
2156 $line->set("shellwords_rest", $rest); 2156 $line->set("shellwords_rest", $rest);
2157 } 2157 }
2158 2158
2159 } elsif ($text =~ regex_mk_comment) { 2159 } elsif ($text =~ regex_mk_comment) {
2160 my ($comment) = ($1); 2160 my ($comment) = ($1);
2161 2161
2162 $line->set("is_comment", true); 2162 $line->set("is_comment", true);
2163 $line->set("comment", $comment); 2163 $line->set("comment", $comment);
2164 2164
2165 } elsif ($text =~ m"^\s*$") { 2165 } elsif ($text =~ m"^\s*$") {
2166 2166
2167 $line->set("is_empty", true); 2167 $line->set("is_empty", true);
2168 2168
2169 } elsif ($text =~ regex_mk_cond) { 2169 } elsif ($text =~ regex_mk_cond) {
2170 my ($indent, $directive, $args, $comment) = ($1, $2, $3, $4); 2170 my ($indent, $directive, $args, $comment) = ($1, $2, $3, $4);
2171 2171
2172 $line->set("is_cond", true); 2172 $line->set("is_cond", true);
2173 $line->set("indent", $indent); 2173 $line->set("indent", $indent);
2174 $line->set("directive", $directive); 2174 $line->set("directive", $directive);
2175 defined($args) and $line->set("args", $args); 2175 defined($args) and $line->set("args", $args);
2176 defined($comment) and $line->set("comment", $comment); 2176 defined($comment) and $line->set("comment", $comment);
2177 2177
2178 } elsif ($text =~ regex_mk_include) { 2178 } elsif ($text =~ regex_mk_include) {
2179 my (undef, $includefile, $comment) = ($1, $2, $3); 2179 my (undef, $includefile, $comment) = ($1, $2, $3);
2180 2180
2181 $line->set("is_include", true); 2181 $line->set("is_include", true);
2182 $line->set("includefile", $includefile); 2182 $line->set("includefile", $includefile);
2183 defined($comment) and $line->set("comment", $comment); 2183 defined($comment) and $line->set("comment", $comment);
2184 2184
2185 } elsif ($text =~ regex_mk_sysinclude) { 2185 } elsif ($text =~ regex_mk_sysinclude) {
2186 my ($includefile, $comment) = ($1, $2); 2186 my ($includefile, $comment) = ($1, $2);
2187 2187
2188 $line->set("is_sysinclude", true); 2188 $line->set("is_sysinclude", true);
2189 $line->set("includefile", $includefile); 2189 $line->set("includefile", $includefile);
2190 defined($comment) and $line->set("comment", $comment); 2190 defined($comment) and $line->set("comment", $comment);
2191 2191
2192 } elsif ($text =~ regex_mk_dependency) { 2192 } elsif ($text =~ regex_mk_dependency) {
2193 my ($targets, $whitespace, $sources, $comment) = ($1, $2, $3, $4); 2193 my ($targets, $whitespace, $sources, $comment) = ($1, $2, $3, $4);
2194 2194
2195 $line->set("is_dependency", true); 2195 $line->set("is_dependency", true);
2196 $line->set("targets", $targets); 2196 $line->set("targets", $targets);
2197 $line->set("sources", $sources); 2197 $line->set("sources", $sources);
2198 $line->log_warning("Space before colon in dependency line: " . $line->to_string()) if ($whitespace); 2198 $line->log_warning("Space before colon in dependency line: " . $line->to_string()) if ($whitespace);
2199 defined($comment) and $line->set("comment", $comment); 2199 defined($comment) and $line->set("comment", $comment);
2200 2200
2201 } elsif ($text =~ regex_rcs_conflict) { 2201 } elsif ($text =~ regex_rcs_conflict) {
2202 # This line is useless 2202 # This line is useless
2203 2203
2204 } else { 2204 } else {
2205 $line->log_fatal("Unknown line format: " . $line->to_string()); 2205 $line->log_fatal("Unknown line format: " . $line->to_string());
2206 } 2206 }
2207} 2207}
2208 2208
2209sub parselines_mk($) { 2209sub parselines_mk($) {
2210 my ($lines) = @_; 2210 my ($lines) = @_;
2211 2211
2212 foreach my $line (@{$lines}) { 2212 foreach my $line (@{$lines}) {
2213 parseline_mk($line); 2213 parseline_mk($line);
2214 } 2214 }
2215} 2215}
2216 2216
2217# 2217#
2218# Loading package-specific data from files. 2218# Loading package-specific data from files.
2219# 2219#
2220 2220
2221sub readmakefile($$$$); 2221sub readmakefile($$$$);
2222sub readmakefile($$$$) { 2222sub readmakefile($$$$) {
2223 my ($fname, $main_lines, $all_lines, $seen_Makefile_include) = @_; 2223 my ($fname, $main_lines, $all_lines, $seen_Makefile_include) = @_;
2224 my ($includefile, $dirname, $lines, $is_main_Makefile); 2224 my ($includefile, $dirname, $lines, $is_main_Makefile);
2225 2225
2226 $lines = load_lines($fname, true); 2226 $lines = load_lines($fname, true);
2227 if (!$lines) { 2227 if (!$lines) {
2228 return false; 2228 return false;
2229 } 2229 }
2230 parselines_mk($lines); 2230 parselines_mk($lines);
2231 2231
2232 $is_main_Makefile = (@{$main_lines} == 0); 2232 $is_main_Makefile = (@{$main_lines} == 0);
2233 2233
2234 foreach my $line (@{$lines}) { 2234 foreach my $line (@{$lines}) {
2235 my $text = $line->text; 2235 my $text = $line->text;
2236 2236
2237 if ($is_main_Makefile) { 2237 if ($is_main_Makefile) {
2238 push(@{$main_lines}, $line); 2238 push(@{$main_lines}, $line);
2239 } 2239 }
2240 push(@{$all_lines}, $line); 2240 push(@{$all_lines}, $line);
2241 2241
2242 # try to get any included file 2242 # try to get any included file
2243 my $is_include_line = false; 2243 my $is_include_line = false;
2244 if ($text =~ m"^\.\s*include\s+\"(.*)\"$") { 2244 if ($text =~ m"^\.\s*include\s+\"(.*)\"$") {
2245 $includefile = resolve_relative_path($1, true); 2245 $includefile = resolve_relative_path($1, true);
2246 if ($includefile =~ regex_unresolved) { 2246 if ($includefile =~ regex_unresolved) {
2247 if ($fname !~ m"/mk/") { 2247 if ($fname !~ m"/mk/") {
2248 $line->log_note("Skipping include file \"${includefile}\". This may result in false warnings."); 2248 $line->log_note("Skipping include file \"${includefile}\". This may result in false warnings.");
2249 } 2249 }
2250 2250
2251 } else { 2251 } else {
2252 $is_include_line = true; 2252 $is_include_line = true;
2253 } 2253 }
2254 } 2254 }
2255 2255
2256 if ($is_include_line) { 2256 if ($is_include_line) {
2257 if ($fname !~ m"buildlink3\.mk$" && $includefile =~ m"^\.\./\.\./(.*)/buildlink3\.mk$") { 2257 if ($fname !~ m"buildlink3\.mk$" && $includefile =~ m"^\.\./\.\./(.*)/buildlink3\.mk$") {
2258 my ($bl3_file) = ($1); 2258 my ($bl3_file) = ($1);
2259 2259
2260 $pkgctx_bl3->{$bl3_file} = $line; 2260 $pkgctx_bl3->{$bl3_file} = $line;
2261 $opt_debug_misc and $line->log_debug("Buildlink3 file in package: ${bl3_file}"); 2261 $opt_debug_misc and $line->log_debug("Buildlink3 file in package: ${bl3_file}");
2262 } 2262 }
2263 } 2263 }
2264 2264
2265 if ($is_include_line && !exists($seen_Makefile_include->{$includefile})) { 2265 if ($is_include_line && !exists($seen_Makefile_include->{$includefile})) {
2266 $seen_Makefile_include->{$includefile} = true; 2266 $seen_Makefile_include->{$includefile} = true;
2267 2267
2268 if ($includefile =~ m"^\.\./[^./][^/]*/[^/]+") { 2268 if ($includefile =~ m"^\.\./[^./][^/]*/[^/]+") {
2269 $line->log_warning("Relative directories should look like \"../../category/package\", not \"../package\"."); 2269 $line->log_warning("Relative directories should look like \"../../category/package\", not \"../package\".");
2270 $line->explain_warning(expl_relative_dirs); 2270 $line->explain_warning(expl_relative_dirs);
2271 } 2271 }
2272 if ($includefile =~ m"(?:^|/)Makefile.common$" 2272 if ($includefile =~ m"(?:^|/)Makefile.common$"
2273 || ($includefile =~ m"^(?:\.\./(\.\./[^/]+/)?[^/]+/)?([^/]+)$" 2273 || ($includefile =~ m"^(?:\.\./(\.\./[^/]+/)?[^/]+/)?([^/]+)$"
2274 && (!defined($1) || $1 ne "../mk") 2274 && (!defined($1) || $1 ne "../mk")
2275 && $2 ne "buildlink3.mk" 2275 && $2 ne "buildlink3.mk"
2276 && $2 ne "options.mk")) { 2276 && $2 ne "options.mk")) {
2277 $opt_debug_include and $line->log_debug("including ${includefile} sets seen_Makefile_common."); 2277 $opt_debug_include and $line->log_debug("including ${includefile} sets seen_Makefile_common.");
2278 $seen_Makefile_common = true; 2278 $seen_Makefile_common = true;
2279 } 2279 }
2280 if ($includefile =~ m"/mk/") { 2280 if ($includefile =~ m"/mk/") {
2281 # skip these files 2281 # skip these files
2282 2282
2283 } else { 2283 } else {
2284 $dirname = dirname($fname); 2284 $dirname = dirname($fname);
2285 # Only look in the directory relative to the 2285 # Only look in the directory relative to the
2286 # current file and in the current working directory. 2286 # current file and in the current working directory.
2287 # We don't have an include dir list, like make(1) does. 2287 # We don't have an include dir list, like make(1) does.
2288 if (!-f "$dirname/$includefile") { 2288 if (!-f "$dirname/$includefile") {
2289 $dirname = $current_dir; 2289 $dirname = $current_dir;
2290 } 2290 }
2291 if (!-f "$dirname/$includefile") { 2291 if (!-f "$dirname/$includefile") {
2292 $line->log_error("Cannot read $dirname/$includefile."); 2292 $line->log_error("Cannot read $dirname/$includefile.");
2293 } else { 2293 } else {
2294 $opt_debug_include and $line->log_debug("Including \"$dirname/$includefile\"."); 2294 $opt_debug_include and $line->log_debug("Including \"$dirname/$includefile\".");
2295 my $last_lineno = $#{$all_lines}; 2295 my $last_lineno = $#{$all_lines};
2296 readmakefile("$dirname/$includefile", $main_lines, $all_lines, $seen_Makefile_include) or return false; 2296 readmakefile("$dirname/$includefile", $main_lines, $all_lines, $seen_Makefile_include) or return false;
2297 2297
2298 # Check that there is a comment in each 2298 # Check that there is a comment in each
2299 # Makefile.common that says which files 2299 # Makefile.common that says which files
2300 # include it. 2300 # include it.
2301 if ($includefile =~ m"/Makefile\.common$") { 2301 if ($includefile =~ m"/Makefile\.common$") {
2302 my @mc_lines = @{$all_lines}[$last_lineno+1 .. $#{$all_lines}]; 2302 my @mc_lines = @{$all_lines}[$last_lineno+1 .. $#{$all_lines}];
2303 my $expected = "# used by " . relative_path($cwd_pkgsrcdir, $fname); 2303 my $expected = "# used by " . relative_path($cwd_pkgsrcdir, $fname);
2304 2304
2305 if (!(grep { $_->text eq $expected } @mc_lines)) { 2305 if (!(grep { $_->text eq $expected } @mc_lines)) {
2306 my $lineno = 0; 2306 my $lineno = 0;
2307 while ($lineno < $#mc_lines && $mc_lines[$lineno]->has("is_comment")) { 2307 while ($lineno < $#mc_lines && $mc_lines[$lineno]->has("is_comment")) {
2308 $lineno++; 2308 $lineno++;
2309 } 2309 }
2310 my $iline = $mc_lines[$lineno]; 2310 my $iline = $mc_lines[$lineno];
2311 $iline->log_warning("Please add a line \"$expected\" here."); 2311 $iline->log_warning("Please add a line \"$expected\" here.");
2312 $iline->explain_warning( 2312 $iline->explain_warning(
2313"Since Makefile.common files usually don't have any comments and", 2313"Since Makefile.common files usually don't have any comments and",
2314"therefore not a clearly defined interface, they should at least contain", 2314"therefore not a clearly defined interface, they should at least contain",
2315"references to all files that include them, so that it is easier to see", 2315"references to all files that include them, so that it is easier to see",
2316"what effects future changes may have.", 2316"what effects future changes may have.",
2317"", 2317"",
2318"If there are more than five packages that use a Makefile.common,", 2318"If there are more than five packages that use a Makefile.common,",
2319"you should think about giving it a proper name (maybe plugin.mk) and", 2319"you should think about giving it a proper name (maybe plugin.mk) and",
2320"documenting its interface."); 2320"documenting its interface.");
2321 $iline->append_before($expected); 2321 $iline->append_before($expected);
2322 autofix(\@mc_lines); 2322 autofix(\@mc_lines);
2323 } 2323 }
2324 } 2324 }
2325 } 2325 }
2326 } 2326 }
2327 2327
2328 } elsif ($line->has("is_varassign")) { 2328 } elsif ($line->has("is_varassign")) {
2329 my ($varname, $op, $value) = ($line->get("varname"), $line->get("op"), $line->get("value")); 2329 my ($varname, $op, $value) = ($line->get("varname"), $line->get("op"), $line->get("value"));
2330 2330
2331 # Record all variables that are defined in these lines, so that they 2331 # Record all variables that are defined in these lines, so that they
2332 # are not reported as "used but not defined". 2332 # are not reported as "used but not defined".
2333 if ($op ne "?=" || !exists($pkgctx_vardef->{$varname})) { 2333 if ($op ne "?=" || !exists($pkgctx_vardef->{$varname})) {
2334 $opt_debug_misc and $line->log_debug("varassign(${varname}, ${op}, ${value})"); 2334 $opt_debug_misc and $line->log_debug("varassign(${varname}, ${op}, ${value})");
2335 $pkgctx_vardef->{$varname} = $line; 2335 $pkgctx_vardef->{$varname} = $line;
2336 } 2336 }
2337 } 2337 }
2338 } 2338 }
2339 2339
2340 return true; 2340 return true;
2341} 2341}
2342 2342
2343sub load_package_Makefile($$) { 2343sub load_package_Makefile($$) {
2344 my ($fname, $ref_lines) = @_; 2344 my ($fname, $ref_lines) = @_;
2345 my ($subr) = "load_package_Makefile"; 2345 my ($subr) = "load_package_Makefile";
2346 my ($lines, $all_lines, $seen_php_pecl_version); 2346 my ($lines, $all_lines, $seen_php_pecl_version);
2347 2347
2348 $opt_debug_trace and log_debug($fname, NO_LINES, "load_package_Makefile()"); 2348 $opt_debug_trace and log_debug($fname, NO_LINES, "load_package_Makefile()");
2349 2349
2350 if (!readmakefile($fname, $lines = [], $all_lines = [], $pkgctx_included = {})) { 2350 if (!readmakefile($fname, $lines = [], $all_lines = [], $pkgctx_included = {})) {
2351 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 2351 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
2352 return false; 2352 return false;
2353 } 2353 }
2354 2354
2355 if ($opt_dumpmakefile) { 2355 if ($opt_dumpmakefile) {
2356 log_debug(NO_FILE, NO_LINES, "Whole Makefile (with all included files) follows:"); 2356 log_debug(NO_FILE, NO_LINES, "Whole Makefile (with all included files) follows:");
2357 foreach my $line (@{$all_lines}) { 2357 foreach my $line (@{$all_lines}) {
2358 print($line->to_string() . "\n"); 2358 print($line->to_string() . "\n");
2359 } 2359 }
2360 } 2360 }
2361 2361
2362 determine_used_variables($all_lines); 2362 determine_used_variables($all_lines);
2363 2363
2364 $pkgdir = expand_variable("PKGDIR"); 2364 $pkgdir = expand_variable("PKGDIR");
2365 set_default_value(\$pkgdir, "."); 2365 set_default_value(\$pkgdir, ".");
2366 $distinfo_file = expand_variable("DISTINFO_FILE"); 2366 $distinfo_file = expand_variable("DISTINFO_FILE");
2367 set_default_value(\$distinfo_file, "distinfo"); 2367 set_default_value(\$distinfo_file, "distinfo");
2368 $filesdir = expand_variable("FILESDIR"); 2368 $filesdir = expand_variable("FILESDIR");
2369 set_default_value(\$filesdir, "files"); 2369 set_default_value(\$filesdir, "files");
2370 $patchdir = expand_variable("PATCHDIR"); 2370 $patchdir = expand_variable("PATCHDIR");
2371 set_default_value(\$patchdir, "patches"); 2371 set_default_value(\$patchdir, "patches");
2372 2372
2373 if (var_is_defined("PHPEXT_MK")) { 2373 if (var_is_defined("PHPEXT_MK")) {
2374 if (!var_is_defined("USE_PHP_EXT_PATCHES")) { 2374 if (!var_is_defined("USE_PHP_EXT_PATCHES")) {
2375 $patchdir = "patches"; 2375 $patchdir = "patches";
2376 } 2376 }
2377 if (var_is_defined("PECL_VERSION")) { 2377 if (var_is_defined("PECL_VERSION")) {
2378 $distinfo_file = "distinfo"; 2378 $distinfo_file = "distinfo";
2379 } 2379 }
2380 } 2380 }
2381 2381
2382 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] DISTINFO_FILE=$distinfo_file"); 2382 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] DISTINFO_FILE=$distinfo_file");
2383 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] FILESDIR=$filesdir"); 2383 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] FILESDIR=$filesdir");
2384 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] PATCHDIR=$patchdir"); 2384 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] PATCHDIR=$patchdir");
2385 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] PKGDIR=$pkgdir"); 2385 $opt_debug_misc and log_debug(NO_FILE, NO_LINE_NUMBER, "[${subr}] PKGDIR=$pkgdir");
2386 2386
2387 ${$ref_lines} = $lines; 2387 ${$ref_lines} = $lines;
2388 return true; 2388 return true;
2389} 2389}
2390 2390
2391sub warn_about_PLIST_imake_mannewsuffix($) { 2391sub warn_about_PLIST_imake_mannewsuffix($) {
2392 my ($line) = @_; 2392 my ($line) = @_;
2393 2393
2394 $line->log_warning("IMAKE_MANNEWSUFFIX is not meant to appear in PLISTs."); 2394 $line->log_warning("IMAKE_MANNEWSUFFIX is not meant to appear in PLISTs.");
2395 $line->explain_warning( 2395 $line->explain_warning(
2396"This is the result of a print-PLIST call that has _not_ been checked", 2396"This is the result of a print-PLIST call that has _not_ been checked",
2397"thoroughly by the developer. Please replace the IMAKE_MANNEWSUFFIX with", 2397"thoroughly by the developer. Please replace the IMAKE_MANNEWSUFFIX with",
2398"", 2398"",
2399"\tIMAKE_MAN_SUFFIX for programs,", 2399"\tIMAKE_MAN_SUFFIX for programs,",
2400"\tIMAKE_LIBMAN_SUFFIX for library functions,", 2400"\tIMAKE_LIBMAN_SUFFIX for library functions,",
2401"\tIMAKE_FILEMAN_SUFFIX for file formats,", 2401"\tIMAKE_FILEMAN_SUFFIX for file formats,",
2402"\tIMAKE_GAMEMAN_SUFFIX for games,", 2402"\tIMAKE_GAMEMAN_SUFFIX for games,",
2403"\tIMAKE_MISCMAN_SUFFIX for other man pages."); 2403"\tIMAKE_MISCMAN_SUFFIX for other man pages.");
2404} 2404}
2405 2405
2406# 2406#
2407# Subroutines to check part of a single line. 2407# Subroutines to check part of a single line.
2408# 2408#
2409 2409
2410sub checkword_absolute_pathname($$) { 2410sub checkword_absolute_pathname($$) {
2411 my ($line, $word) = @_; 2411 my ($line, $word) = @_;
2412 2412
2413 $opt_debug_trace and $line->log_debug("checkword_absolute_pathname(\"${word}\")"); 2413 $opt_debug_trace and $line->log_debug("checkword_absolute_pathname(\"${word}\")");
2414 2414
2415 if ($word =~ m"^/dev/(?:null|tty|zero)$") { 2415 if ($word =~ m"^/dev/(?:null|tty|zero)$") {
2416 # These are defined by POSIX. 2416 # These are defined by POSIX.
2417 2417
2418 } elsif ($word eq "/bin/sh") { 2418 } elsif ($word eq "/bin/sh") {
2419 # This is usually correct, although on Solaris, it's pretty 2419 # This is usually correct, although on Solaris, it's pretty
2420 # feature-crippled. 2420 # feature-crippled.
2421 2421
2422 } elsif ($word !~ m"/(?:[a-z]|\$[({])") { 2422 } elsif ($word !~ m"/(?:[a-z]|\$[({])") {
2423 # Assume that all pathnames start with a lowercase letter. 2423 # Assume that all pathnames start with a lowercase letter.
2424 2424
2425 } else { 2425 } else {
2426 $line->log_warning("Found absolute pathname: ${word}"); 2426 $line->log_warning("Found absolute pathname: ${word}");
2427 $line->explain_warning( 2427 $line->explain_warning(
2428"Absolute pathnames are often an indicator for unportable code. As", 2428"Absolute pathnames are often an indicator for unportable code. As",
2429"pkgsrc aims to be a portable system, absolute pathnames should be", 2429"pkgsrc aims to be a portable system, absolute pathnames should be",
2430"avoided whenever possible.", 2430"avoided whenever possible.",
2431"", 2431"",
2432"A special variable in this context is \${DESTDIR}, which is used in GNU", 2432"A special variable in this context is \${DESTDIR}, which is used in GNU",
2433"projects to specify a different directory for installation than what", 2433"projects to specify a different directory for installation than what",
2434"the programs see later when they are executed. Usually it is empty, so", 2434"the programs see later when they are executed. Usually it is empty, so",
2435"if anything after that variable starts with a slash, it is considered", 2435"if anything after that variable starts with a slash, it is considered",
2436"an absolute pathname."); 2436"an absolute pathname.");
2437 } 2437 }
2438} 2438}
2439 2439
2440sub checkpackage_possible_downgrade() { 2440sub checkpackage_possible_downgrade() {
2441 2441
2442 $opt_debug_trace and log_debug(NO_FILE, NO_LINES, "checkpackage_possible_downgrade"); 2442 $opt_debug_trace and log_debug(NO_FILE, NO_LINES, "checkpackage_possible_downgrade");
2443 2443
2444 return unless defined $effective_pkgname; 2444 return unless defined $effective_pkgname;
2445 return unless $effective_pkgname =~ regex_pkgname; 2445 return unless $effective_pkgname =~ regex_pkgname;
2446 my ($pkgbase, $pkgversion) = ($1, $2); 2446 my ($pkgbase, $pkgversion) = ($1, $2);
2447 my $line = $effective_pkgname_line; 2447 my $line = $effective_pkgname_line;
2448 2448
2449 my @changes = get_doc_CHANGES($pkgpath); 2449 my @changes = get_doc_CHANGES($pkgpath);
2450 if (@changes == 0) { 2450 if (@changes == 0) {
2451 $opt_debug_misc and $line->log_debug("No changes have been recorded for package $pkgpath."); 2451 $opt_debug_misc and $line->log_debug("No changes have been recorded for package $pkgpath.");
2452 return; 2452 return;
2453 } 2453 }
2454 2454
2455 my $last_change = $changes[-1]; 2455 my $last_change = $changes[-1];
2456 return unless $last_change->action eq "Updated"; 2456 return unless $last_change->action eq "Updated";
2457 2457
2458 my $last_version = $last_change->version; 2458 my $last_version = $last_change->version;
2459 2459
2460 if (dewey_cmp($pkgversion, "<", $last_version)) { 2460 if (dewey_cmp($pkgversion, "<", $last_version)) {
2461 $line->log_warning("The package is being downgraded from $last_version to $pkgversion."); 2461 $line->log_warning("The package is being downgraded from $last_version to $pkgversion.");
2462 } 2462 }
2463} 2463}
2464 2464
2465# 2465#
2466# Subroutines to check a single line. 2466# Subroutines to check a single line.
2467# 2467#
2468 2468
2469sub checkline_length($$) { 2469sub checkline_length($$) {
2470 my ($line, $maxlength) = @_; 2470 my ($line, $maxlength) = @_;
2471 2471
2472 if (length($line->text) > $maxlength) { 2472 if (length($line->text) > $maxlength) {
2473 $line->log_warning("Line too long (should be no more than $maxlength characters)."); 2473 $line->log_warning("Line too long (should be no more than $maxlength characters).");
2474 $line->explain_warning( 2474 $line->explain_warning(
2475"Back in the old time, terminals with 80x25 characters were common.", 2475"Back in the old time, terminals with 80x25 characters were common.",
2476"And this is still the default size of many terminal emulators.", 2476"And this is still the default size of many terminal emulators.",
2477"Moderately short lines also make reading easier."); 2477"Moderately short lines also make reading easier.");
2478 } 2478 }
2479} 2479}
2480 2480
2481sub checkline_valid_characters($$) { 2481sub checkline_valid_characters($$) {
2482 my ($line, $re_validchars) = @_; 2482 my ($line, $re_validchars) = @_;
2483 my ($rest); 2483 my ($rest);
2484 2484
2485 ($rest = $line->text) =~ s/$re_validchars//g; 2485 ($rest = $line->text) =~ s/$re_validchars//g;
2486 if ($rest ne "") { 2486 if ($rest ne "") {
2487 my @chars = map { $_ = sprintf("0x%02x", ord($_)); } split(//, $rest); 2487 my @chars = map { $_ = sprintf("0x%02x", ord($_)); } split(//, $rest);
2488 $line->log_warning("Line contains invalid characters (" . join(", ", @chars) . ")."); 2488 $line->log_warning("Line contains invalid characters (" . join(", ", @chars) . ").");
2489 } 2489 }
2490} 2490}
2491 2491
2492sub checkline_valid_characters_in_variable($$) { 2492sub checkline_valid_characters_in_variable($$) {
2493 my ($line, $re_validchars) = @_; 2493 my ($line, $re_validchars) = @_;
2494 my ($varname, $rest); 2494 my ($varname, $rest);
2495 2495
2496 $varname = $line->get("varname"); 2496 $varname = $line->get("varname");
2497 $rest = $line->get("value"); 2497 $rest = $line->get("value");
2498 2498
2499 $rest =~ s/$re_validchars//g; 2499 $rest =~ s/$re_validchars//g;
2500 if ($rest ne "") { 2500 if ($rest ne "") {
2501 my @chars = map { $_ = sprintf("0x%02x", ord($_)); } split(//, $rest); 2501 my @chars = map { $_ = sprintf("0x%02x", ord($_)); } split(//, $rest);
2502 $line->log_warning("${varname} contains invalid characters (" . join(", ", @chars) . ")."); 2502 $line->log_warning("${varname} contains invalid characters (" . join(", ", @chars) . ").");
2503 } 2503 }
2504} 2504}
2505 2505
2506sub checkline_trailing_whitespace($) { 2506sub checkline_trailing_whitespace($) {
2507 my ($line) = @_; 2507 my ($line) = @_;
2508 2508
2509 $opt_debug_trace and $line->log_debug("checkline_trailing_whitespace()"); 2509 $opt_debug_trace and $line->log_debug("checkline_trailing_whitespace()");
2510 2510
2511 if ($line->text =~ /\s+$/) { 2511 if ($line->text =~ /\s+$/) {
2512 $line->log_note("Trailing white-space."); 2512 $line->log_note("Trailing white-space.");
2513 $line->explain_note( 2513 $line->explain_note(
2514"When a line ends with some white-space, that space is in most cases", 2514"When a line ends with some white-space, that space is in most cases",
2515"irrelevant and can be removed, leading to a \"normal form\" syntax.", 2515"irrelevant and can be removed, leading to a \"normal form\" syntax.",
2516"", 2516"",
2517"Note: This is mostly for aesthetic reasons."); 2517"Note: This is mostly for aesthetic reasons.");
2518 $line->replace_regex(qr"\s+\n$", "\n"); 2518 $line->replace_regex(qr"\s+\n$", "\n");
2519 } 2519 }
2520} 2520}
2521 2521
2522sub checkline_rcsid_regex($$$) { 2522sub checkline_rcsid_regex($$$) {
2523 my ($line, $prefix_regex, $prefix) = @_; 2523 my ($line, $prefix_regex, $prefix) = @_;
2524 my ($id) = ($opt_rcsidstring . ($is_wip ? "|Id" : "")); 2524 my ($id) = ($opt_rcsidstring . ($is_wip ? "|Id" : ""));
2525 2525
2526 $opt_debug_trace and $line->log_debug("checkline_rcsid_regex(${prefix_regex}, ${prefix})"); 2526 $opt_debug_trace and $line->log_debug("checkline_rcsid_regex(${prefix_regex}, ${prefix})");
2527 2527
2528 if ($line->text !~ m"^${prefix_regex}\$(${id})(?::[^\$]+|)\$$") { 2528 if ($line->text !~ m"^${prefix_regex}\$(${id})(?::[^\$]+|)\$$") {
2529 $line->log_error("\"${prefix}\$${opt_rcsidstring}\$\" expected."); 2529 $line->log_error("\"${prefix}\$${opt_rcsidstring}\$\" expected.");
 2530 $line->explain_error(
 2531"Several files in pkgsrc must contain the CVS Id, so that their current",
 2532"version can be traced back later from a binary package. This is to",
 2533"ensure reproducible builds, for example for finding bugs.",
 2534"",
 2535"Please insert the text from the above error message (without the quotes)",
 2536"at this position in the file.");
2530 return false; 2537 return false;
2531 } 2538 }
2532 return true; 2539 return true;
2533} 2540}
2534 2541
2535sub checkline_rcsid($$) { 2542sub checkline_rcsid($$) {
2536 my ($line, $prefix) = @_; 2543 my ($line, $prefix) = @_;
2537 2544
2538 checkline_rcsid_regex($line, quotemeta($prefix), $prefix); 2545 checkline_rcsid_regex($line, quotemeta($prefix), $prefix);
2539} 2546}
2540 2547
2541# Checks whether the line contains text that looks like absolute 2548# Checks whether the line contains text that looks like absolute
2542# pathnames, assuming that the file uses the common syntax with 2549# pathnames, assuming that the file uses the common syntax with
2543# single or double quotes to represent strings. 2550# single or double quotes to represent strings.
2544# 2551#
2545sub checkline_source_absolute_pathname($$) { 2552sub checkline_source_absolute_pathname($$) {
2546 my ($line, $text) = @_; 2553 my ($line, $text) = @_;
2547 my ($abspath); 2554 my ($abspath);
2548 2555
2549 $opt_debug_trace and $line->log_debug("checkline_source_absolute_pathname(${text})"); 2556 $opt_debug_trace and $line->log_debug("checkline_source_absolute_pathname(${text})");
2550 2557
2551 if ($text =~ m"(.*)([\"'])(/[^\"']*)\2") { 2558 if ($text =~ m"(.*)([\"'])(/[^\"']*)\2") {
2552 my ($before, $delim, $string) = ($1, $2, $3); 2559 my ($before, $delim, $string) = ($1, $2, $3);
2553 2560
2554 $opt_debug_misc and $line->log_debug("checkline_source_absolute_pathname(before=${before}, string=${string})"); 2561 $opt_debug_misc and $line->log_debug("checkline_source_absolute_pathname(before=${before}, string=${string})");
2555 if ($before =~ m"[A-Z_]+\s*$") { 2562 if ($before =~ m"[A-Z_]+\s*$") {
2556 # allowed: PREFIX "/bin/foo" 2563 # allowed: PREFIX "/bin/foo"
2557 2564
2558 } elsif ($string =~ m"^/[*/]") { 2565 } elsif ($string =~ m"^/[*/]") {
2559 # This is more likely to be a C or C++ comment. 2566 # This is more likely to be a C or C++ comment.
2560 2567
2561 } elsif ($string !~ m"^/\w") { 2568 } elsif ($string !~ m"^/\w") {
2562 # Assume that pathnames start with a letter or digit. 2569 # Assume that pathnames start with a letter or digit.
2563 2570
2564 } elsif ($before =~ m"\+\s*$") { 2571 } elsif ($before =~ m"\+\s*$") {
2565 # Something like foodir + '/lib' 2572 # Something like foodir + '/lib'
2566 2573
2567 } else { 2574 } else {
2568 $abspath = $string; 2575 $abspath = $string;
2569 } 2576 }
2570 } 2577 }
2571 2578
2572 if (defined($abspath)) { 2579 if (defined($abspath)) {
2573 checkword_absolute_pathname($line, $abspath); 2580 checkword_absolute_pathname($line, $abspath);
2574 } 2581 }
2575} 2582}
2576 2583
2577sub checkline_mk_absolute_pathname($$) { 2584sub checkline_mk_absolute_pathname($$) {
2578 my ($line, $text) = @_; 2585 my ($line, $text) = @_;
2579 my $abspath; 2586 my $abspath;
2580 2587
2581 $opt_debug_trace and $line->log_debug("checkline_mk_absolute_pathname(${text})"); 2588 $opt_debug_trace and $line->log_debug("checkline_mk_absolute_pathname(${text})");
2582 2589
2583 # In the GNU coding standards, DESTDIR is defined as a (usually 2590 # In the GNU coding standards, DESTDIR is defined as a (usually
2584 # empty) prefix that can be used to install files to a different 2591 # empty) prefix that can be used to install files to a different
2585 # location from what they have been built for. Therefore 2592 # location from what they have been built for. Therefore
2586 # everything following it is considered an absolute pathname. 2593 # everything following it is considered an absolute pathname.
2587 # Another commonly used context is in assignments like 2594 # Another commonly used context is in assignments like
2588 # "bindir=/bin". 2595 # "bindir=/bin".
2589 if ($text =~ m"(?:^|\$\{DESTDIR\}|\$\(DESTDIR\)|[\w_]+\s*=\s*)(/(?:[^\"'\`\s]|\"[^\"*]\"|'[^']*'|\`[^\`]*\`)*)") { 2596 if ($text =~ m"(?:^|\$\{DESTDIR\}|\$\(DESTDIR\)|[\w_]+\s*=\s*)(/(?:[^\"'\`\s]|\"[^\"*]\"|'[^']*'|\`[^\`]*\`)*)") {
2590 my $path = $1; 2597 my $path = $1;
2591 2598
2592 if ($path =~ m"^/\w") { 2599 if ($path =~ m"^/\w") {
2593 $abspath = $path; 2600 $abspath = $path;
2594 } 2601 }
2595 } 2602 }
2596 2603
2597 if (defined($abspath)) { 2604 if (defined($abspath)) {
2598 checkword_absolute_pathname($line, $abspath); 2605 checkword_absolute_pathname($line, $abspath);
2599 } 2606 }
2600} 2607}
2601 2608
2602# Last resort if the file does not look like a Makefile or typical 2609# Last resort if the file does not look like a Makefile or typical
2603# source code. All strings that look like pathnames and start with 2610# source code. All strings that look like pathnames and start with
2604# one of the typical Unix prefixes are found. 2611# one of the typical Unix prefixes are found.
2605# 2612#
2606sub checkline_other_absolute_pathname($$) { 2613sub checkline_other_absolute_pathname($$) {
2607 my ($line, $text) = @_; 2614 my ($line, $text) = @_;
2608 2615
2609 $opt_debug_trace and $line->log_debug("checkline_other_absolute_pathname(\"${text}\")"); 2616 $opt_debug_trace and $line->log_debug("checkline_other_absolute_pathname(\"${text}\")");
2610 2617
2611 if ($text =~ m"^#[^!]") { 2618 if ($text =~ m"^#[^!]") {
2612 # Don't warn for absolute pathnames in comments, 2619 # Don't warn for absolute pathnames in comments,
2613 # except for shell interpreters. 2620 # except for shell interpreters.
2614 2621
2615 } elsif ($text =~ m"^(.*?)((?:/[\w.]+)*/(?:bin|dev|etc|home|lib|mnt|opt|proc|sbin|tmp|usr|var)\b[\w./\-]*)(.*)$") { 2622 } elsif ($text =~ m"^(.*?)((?:/[\w.]+)*/(?:bin|dev|etc|home|lib|mnt|opt|proc|sbin|tmp|usr|var)\b[\w./\-]*)(.*)$") {
2616 my ($before, $path, $after) = ($1, $2, $3); 2623 my ($before, $path, $after) = ($1, $2, $3);
2617 2624
2618 if ($before =~ m"\@$") { 2625 if ($before =~ m"\@$") {
2619 # Something like @PREFIX@/bin 2626 # Something like @PREFIX@/bin
2620 2627
2621 } elsif ($before =~ m"[)}]$") { 2628 } elsif ($before =~ m"[)}]$") {
2622 # Something like ${prefix}/bin or $(PREFIX)/bin 2629 # Something like ${prefix}/bin or $(PREFIX)/bin
2623 2630
2624 } elsif ($before =~ m"\+\s*[\"']$") { 2631 } elsif ($before =~ m"\+\s*[\"']$") {
2625 # Something like foodir + '/lib' 2632 # Something like foodir + '/lib'
2626 2633
2627 } elsif ($before =~ m"\w$") { 2634 } elsif ($before =~ m"\w$") {
2628 # Something like $dir/lib 2635 # Something like $dir/lib
2629 2636
2630 } elsif ($before =~ m"\.$") { 2637 } elsif ($before =~ m"\.$") {
2631 # ../foo is not an absolute pathname. 2638 # ../foo is not an absolute pathname.
2632 2639
2633 } else { 2640 } else {
2634 $opt_debug_misc and $line->log_debug("before=${before}"); 2641 $opt_debug_misc and $line->log_debug("before=${before}");
2635 checkword_absolute_pathname($line, $path); 2642 checkword_absolute_pathname($line, $path);
2636 } 2643 }
2637 } 2644 }
2638} 2645}
2639 2646
2640sub checkline_relative_path($$$) { 2647sub checkline_relative_path($$$) {
2641 my ($line, $path, $must_exist) = @_; 2648 my ($line, $path, $must_exist) = @_;
2642 my ($res_path); 2649 my ($res_path);
2643 2650
2644 if (!$is_wip && $path =~ m"/wip/") { 2651 if (!$is_wip && $path =~ m"/wip/") {
2645 $line->log_error("A pkgsrc package must not depend on any outside package."); 2652 $line->log_error("A pkgsrc package must not depend on any outside package.");
2646 } 2653 }
2647 $res_path = resolve_relative_path($path, true); 2654 $res_path = resolve_relative_path($path, true);
2648 if ($res_path =~ regex_unresolved) { 2655 if ($res_path =~ regex_unresolved) {
2649 $opt_debug_unchecked and $line->log_debug("Unchecked path: \"${path}\"."); 2656 $opt_debug_unchecked and $line->log_debug("Unchecked path: \"${path}\".");
2650 } elsif (!-e ((($res_path =~ m"^/") ? "" : "${current_dir}/") . $res_path)) { 2657 } elsif (!-e ((($res_path =~ m"^/") ? "" : "${current_dir}/") . $res_path)) {
2651 $must_exist and $line->log_error("\"${res_path}\" does not exist."); 2658 $must_exist and $line->log_error("\"${res_path}\" does not exist.");
2652 } elsif ($path =~ m"^\.\./\.\./([^/]+)/([^/]+)(.*)") { 2659 } elsif ($path =~ m"^\.\./\.\./([^/]+)/([^/]+)(.*)") {
2653 my ($cat, $pkg, $rest) = ($1, $2, $3); 2660 my ($cat, $pkg, $rest) = ($1, $2, $3);
2654 } elsif ($path =~ m"^\.\./\.\./mk/") { 2661 } elsif ($path =~ m"^\.\./\.\./mk/") {
2655 # There need not be two directory levels for mk/ files. 2662 # There need not be two directory levels for mk/ files.
2656 } elsif ($path =~ m"^\.\./mk/" && $cur_pkgsrcdir eq "..") { 2663 } elsif ($path =~ m"^\.\./mk/" && $cur_pkgsrcdir eq "..") {
2657 # That's fine for category Makefiles. 2664 # That's fine for category Makefiles.
2658 } elsif ($path =~ m"^\.\.") { 2665 } elsif ($path =~ m"^\.\.") {
2659 $line->log_warning("Invalid relative path \"${path}\"."); 2666 $line->log_warning("Invalid relative path \"${path}\".");
2660 } 2667 }
2661} 2668}
2662 2669
2663sub checkline_relative_pkgdir($$) { 2670sub checkline_relative_pkgdir($$) {
2664 my ($line, $path) = @_; 2671 my ($line, $path) = @_;
2665 2672
2666 checkline_relative_path($line, $path, true); 2673 checkline_relative_path($line, $path, true);
2667 $path = resolve_relative_path($path, false); 2674 $path = resolve_relative_path($path, false);
2668 2675
2669 if ($path =~ m"^(?:\./)?\.\./\.\./([^/]+/[^/]+)$") { 2676 if ($path =~ m"^(?:\./)?\.\./\.\./([^/]+/[^/]+)$") {
2670 my $otherpkgpath = $1; 2677 my $otherpkgpath = $1;
2671 if (! -f "$cwd_pkgsrcdir/$otherpkgpath/Makefile") { 2678 if (! -f "$cwd_pkgsrcdir/$otherpkgpath/Makefile") {
2672 $line->log_error("There is no package in $otherpkgpath."); 2679 $line->log_error("There is no package in $otherpkgpath.");
2673 } 2680 }
2674 2681
2675 } else { 2682 } else {
2676 $line->log_warning("\"${path}\" is not a valid relative package directory."); 2683 $line->log_warning("\"${path}\" is not a valid relative package directory.");
2677 $line->explain_warning( 2684 $line->explain_warning(
2678"A relative pathname always starts with \"../../\", followed", 2685"A relative pathname always starts with \"../../\", followed",
2679"by a category, a slash and a the directory name of the package.", 2686"by a category, a slash and a the directory name of the package.",
2680"For example, \"../../misc/screen\" is a valid relative pathname."); 2687"For example, \"../../misc/screen\" is a valid relative pathname.");
2681 } 2688 }
2682} 2689}
2683 2690
2684sub checkline_spellcheck($) { 2691sub checkline_spellcheck($) {
2685 my ($line) = @_; 2692 my ($line) = @_;
2686 2693
2687 if ($line->text =~ m"existant") { 2694 if ($line->text =~ m"existant") {
2688 $line->log_warning("The word \"existant\" is nonexistent in the m-w dictionary."); 2695 $line->log_warning("The word \"existant\" is nonexistent in the m-w dictionary.");
2689 $line->explain_warning("Please use \"existent\" instead."); 2696 $line->explain_warning("Please use \"existent\" instead.");
2690 } 2697 }
2691} 2698}
2692 2699
2693sub checkline_cpp_macro_names($$) { 2700sub checkline_cpp_macro_names($$) {
2694 my ($line, $text) = @_; 2701 my ($line, $text) = @_;
2695 my ($rest); 2702 my ($rest);
2696 2703
2697 use constant good_macros => PkgLint::Util::array_to_hash(qw( 2704 use constant good_macros => PkgLint::Util::array_to_hash(qw(
2698 __STDC__ 2705 __STDC__
2699 2706
2700 __GNUC__ __GNUC_MINOR__ 2707 __GNUC__ __GNUC_MINOR__
2701 __SUNPRO_C 2708 __SUNPRO_C
2702 2709
2703 __i386 2710 __i386
2704 __mips 2711 __mips
2705 __sparc 2712 __sparc
2706 2713
2707 __APPLE__ 2714 __APPLE__
2708 __bsdi__ 2715 __bsdi__
2709 __CYGWIN__ 2716 __CYGWIN__
2710 __DragonFly__ 2717 __DragonFly__
2711 __FreeBSD__ __FreeBSD_version 2718 __FreeBSD__ __FreeBSD_version
2712 __INTERIX 2719 __INTERIX
2713 __linux__ 2720 __linux__
2714 __MINGW32__ 2721 __MINGW32__
2715 __NetBSD__ __NetBSD_Version__ 2722 __NetBSD__ __NetBSD_Version__
2716 __OpenBSD__ 2723 __OpenBSD__
2717 __SVR4 2724 __SVR4
2718 __sgi 2725 __sgi
2719 __sun 2726 __sun
2720 2727
2721 __GLIBC__ 2728 __GLIBC__
2722 )); 2729 ));
2723 use constant bad_macros => { 2730 use constant bad_macros => {
2724 "__sgi__" => "__sgi", 2731 "__sgi__" => "__sgi",
2725 "__sparc__" => "__sparc", 2732 "__sparc__" => "__sparc",
2726 "__sparc_v9__" => "__sparcv9", 2733 "__sparc_v9__" => "__sparcv9",
2727 "__sun__" => "__sun", 2734 "__sun__" => "__sun",
2728 "__svr4__" => "__SVR4", 2735 "__svr4__" => "__SVR4",
2729 }; 2736 };
2730 2737
2731 $rest = $text; 2738 $rest = $text;
2732 while ($rest =~ s/defined\((__[\w_]+)\)// || $rest =~ s/\b(_\w+)\(//) { 2739 while ($rest =~ s/defined\((__[\w_]+)\)// || $rest =~ s/\b(_\w+)\(//) {
2733 my ($macro) = ($1); 2740 my ($macro) = ($1);
2734 2741
2735 if (exists(good_macros->{$macro})) { 2742 if (exists(good_macros->{$macro})) {
2736 $opt_debug_misc and $line->log_debug("Found good macro \"${macro}\"."); 2743 $opt_debug_misc and $line->log_debug("Found good macro \"${macro}\".");
2737 } elsif (exists(bad_macros->{$macro})) { 2744 } elsif (exists(bad_macros->{$macro})) {
2738 $line->log_warning("The macro \"${macro}\" is not portable enough. Please use \"".bad_macros->{$macro}."\" instead."); 2745 $line->log_warning("The macro \"${macro}\" is not portable enough. Please use \"".bad_macros->{$macro}."\" instead.");
2739 $line->explain_warning("See the pkgsrc guide, section \"CPP defines\" for details."); 2746 $line->explain_warning("See the pkgsrc guide, section \"CPP defines\" for details.");
2740 2747
2741 } elsif ($macro eq "__NetBSD_Prereq__") { 2748 } elsif ($macro eq "__NetBSD_Prereq__") {
2742 $line->log_warning("Please use __NetBSD_Version__ instead of __NetBSD_Prereq__."); 2749 $line->log_warning("Please use __NetBSD_Version__ instead of __NetBSD_Prereq__.");
2743 $line->explain_warning( 2750 $line->explain_warning(
2744"The __NetBSD_Prereq__ macro is pretty new. It was born in NetBSD", 2751"The __NetBSD_Prereq__ macro is pretty new. It was born in NetBSD",
2745"4.99.3, and maybe it won't survive for long. A better (and compatible)", 2752"4.99.3, and maybe it won't survive for long. A better (and compatible)",
2746"way is to compare __NetBSD_Version__ directly to the required version", 2753"way is to compare __NetBSD_Version__ directly to the required version",
2747"number."); 2754"number.");
2748 2755
2749 } elsif ($macro =~ m"^_+NetBSD_+Version_+$"i && $macro ne "__NetBSD_Version__") { 2756 } elsif ($macro =~ m"^_+NetBSD_+Version_+$"i && $macro ne "__NetBSD_Version__") {
2750 $line->log_warning("Misspelled variant \"${macro}\" of \"__NetBSD_Version__\"."); 2757 $line->log_warning("Misspelled variant \"${macro}\" of \"__NetBSD_Version__\".");
2751 2758
2752 } else { 2759 } else {
2753 $opt_debug_unchecked and $line->log_debug("Unchecked macro \"${macro}\"."); 2760 $opt_debug_unchecked and $line->log_debug("Unchecked macro \"${macro}\".");
2754 } 2761 }
2755 } 2762 }
2756} 2763}
2757 2764
2758sub checkline_mk_varuse($$$$) { 2765sub checkline_mk_varuse($$$$) {
2759 my ($line, $varname, $mod, $context) = @_; 2766 my ($line, $varname, $mod, $context) = @_;
2760 2767
2761 assert(defined($varname), "The varname parameter must be defined"); 2768 assert(defined($varname), "The varname parameter must be defined");
2762 assert(defined($context), "The context parameter must be defined"); 2769 assert(defined($context), "The context parameter must be defined");
2763 $opt_debug_trace and $line->log_debug("checkline_mk_varuse(\"${varname}\", \"${mod}\", ".$context->to_string().")"); 2770 $opt_debug_trace and $line->log_debug("checkline_mk_varuse(\"${varname}\", \"${mod}\", ".$context->to_string().")");
2764 2771
2765 # Check for spelling mistakes. 2772 # Check for spelling mistakes.
2766 my $type = get_variable_type($line, $varname); 2773 my $type = get_variable_type($line, $varname);
2767 if (defined($type) && !($type->is_guessed)) { 2774 if (defined($type) && !($type->is_guessed)) {
2768 # Great. 2775 # Great.
2769 2776
2770 } elsif (var_is_used($varname)) { 2777 } elsif (var_is_used($varname)) {
2771 # Fine. 2778 # Fine.
2772 2779
2773 } elsif (defined($mkctx_for_variables) && exists($mkctx_for_variables->{$varname})) { 2780 } elsif (defined($mkctx_for_variables) && exists($mkctx_for_variables->{$varname})) {
2774 # Variables defined in .for loops are also ok. 2781 # Variables defined in .for loops are also ok.
2775 2782
2776 } else { 2783 } else {
2777 $opt_warn_extra and $line->log_warning("${varname} is used but not defined. Spelling mistake?"); 2784 $opt_warn_extra and $line->log_warning("${varname} is used but not defined. Spelling mistake?");
2778 } 2785 }
2779 2786
2780 if ($opt_warn_perm) { 2787 if ($opt_warn_perm) {
2781 my $perms = get_variable_perms($line, $varname); 2788 my $perms = get_variable_perms($line, $varname);
2782 my $is_load_time; # Will the variable be used at load time? 2789 my $is_load_time; # Will the variable be used at load time?
2783 my $is_indirect; # Might the variable be used indirectly at load time, 2790 my $is_indirect; # Might the variable be used indirectly at load time,
2784 # for example by assigning it to another variable 2791 # for example by assigning it to another variable
2785 # which then gets evaluated? 2792 # which then gets evaluated?
2786 2793
2787 # Don't warn about variables that are not recorded in the 2794 # Don't warn about variables that are not recorded in the
2788 # pkglint variable definition. 2795 # pkglint variable definition.
2789 if (defined($context->type) && $context->type->is_guessed()) { 2796 if (defined($context->type) && $context->type->is_guessed()) {
2790 $is_load_time = false; 2797 $is_load_time = false;
2791 2798
2792 } elsif ($context->time == VUC_TIME_LOAD && $perms !~ m"p") { 2799 } elsif ($context->time == VUC_TIME_LOAD && $perms !~ m"p") {
2793 $is_load_time = true; 2800 $is_load_time = true;
2794 $is_indirect = false; 2801 $is_indirect = false;
2795 2802
2796 } elsif (defined($context->type) && $context->type->perms_union() =~ m"p" && $perms !~ m"p") { 2803 } elsif (defined($context->type) && $context->type->perms_union() =~ m"p" && $perms !~ m"p") {
2797 $is_load_time = true; 2804 $is_load_time = true;
2798 $is_indirect = true; 2805 $is_indirect = true;
2799 2806
2800 } else { 2807 } else {
2801 $is_load_time = false; 2808 $is_load_time = false;
2802 } 2809 }
2803 2810
2804 if ($is_load_time && !$is_indirect) { 2811 if ($is_load_time && !$is_indirect) {
2805 $line->log_warning("${varname} should not be evaluated at load time."); 2812 $line->log_warning("${varname} should not be evaluated at load time.");
2806 $line->explain_warning( 2813 $line->explain_warning(
2807"Many variables, especially lists of something, get their values", 2814"Many variables, especially lists of something, get their values",
2808"incrementally. Therefore it is generally unsafe to rely on their value", 2815"incrementally. Therefore it is generally unsafe to rely on their value",
2809"until it is clear that it will never change again. This point is", 2816"until it is clear that it will never change again. This point is",
2810"reached when the whole package Makefile is loaded and execution of the", 2817"reached when the whole package Makefile is loaded and execution of the",
2811"shell commands starts, in some cases earlier.", 2818"shell commands starts, in some cases earlier.",
2812"", 2819"",
2813"Additionally, when using the \":=\" operator, each \$\$ is replaced", 2820"Additionally, when using the \":=\" operator, each \$\$ is replaced",
2814"with a single \$, so variables that have references to shell variables", 2821"with a single \$, so variables that have references to shell variables",
2815"or regular expressions are modified in a subtle way."); 2822"or regular expressions are modified in a subtle way.");
2816 } 2823 }
2817 if ($is_load_time && $is_indirect) { 2824 if ($is_load_time && $is_indirect) {
2818 $line->log_warning("${varname} should not be evaluated indirectly at load time."); 2825 $line->log_warning("${varname} should not be evaluated indirectly at load time.");
2819 $line->explain_warning( 2826 $line->explain_warning(
2820"The variable on the left-hand side may be evaluated at load time, but", 2827"The variable on the left-hand side may be evaluated at load time, but",
2821"the variable on the right-hand side may not. Due to this assignment, it", 2828"the variable on the right-hand side may not. Due to this assignment, it",
2822"might be used indirectly at load-time, when it is not guaranteed to be", 2829"might be used indirectly at load-time, when it is not guaranteed to be",
2823"properly defined."); 2830"properly defined.");
2824 } 2831 }
2825 2832
2826 if ($perms !~ m"p" && $perms !~ m"u") { 2833 if ($perms !~ m"p" && $perms !~ m"u") {
2827 $line->log_warning("${varname} may not be used in this file."); 2834 $line->log_warning("${varname} may not be used in this file.");
2828 } 2835 }
2829 } 2836 }
2830 2837
2831 if ($varname eq "LOCALBASE" && !$is_internal) { 2838 if ($varname eq "LOCALBASE" && !$is_internal) {
2832 $line->log_warning("The LOCALBASE variable should not be used by packages."); 2839 $line->log_warning("The LOCALBASE variable should not be used by packages.");
2833 $line->explain_warning( 2840 $line->explain_warning(
2834# from jlam via private mail. 2841# from jlam via private mail.
2835"Currently, LOCALBASE is typically used in these cases:", 2842"Currently, LOCALBASE is typically used in these cases:",
2836"", 2843"",
2837"(1) To locate a file or directory from another package.", 2844"(1) To locate a file or directory from another package.",
2838"(2) To refer to own files after installation.", 2845"(2) To refer to own files after installation.",
2839"", 2846"",
2840"In the first case, the example is:", 2847"In the first case, the example is:",
2841"", 2848"",
2842" STRLIST= \${LOCALBASE}/bin/strlist", 2849" STRLIST= \${LOCALBASE}/bin/strlist",
2843" do-build:", 2850" do-build:",
2844" cd \${WRKSRC} && \${STRLIST} *.str", 2851" cd \${WRKSRC} && \${STRLIST} *.str",
2845"", 2852"",
2846"This should really be:", 2853"This should really be:",
2847"", 2854"",
2848" EVAL_PREFIX= STRLIST_PREFIX=strlist", 2855" EVAL_PREFIX= STRLIST_PREFIX=strlist",
2849" STRLIST= \${STRLIST_PREFIX}/bin/strlist", 2856" STRLIST= \${STRLIST_PREFIX}/bin/strlist",
2850" do-build:", 2857" do-build:",
2851" cd \${WRKSRC} && \${STRLIST} *.str", 2858" cd \${WRKSRC} && \${STRLIST} *.str",
2852"", 2859"",
2853"In the second case, the example is:", 2860"In the second case, the example is:",
2854"", 2861"",
2855" CONFIGURE_ENV+= --with-datafiles=\${LOCALBASE}/share/battalion", 2862" CONFIGURE_ENV+= --with-datafiles=\${LOCALBASE}/share/battalion",
2856"", 2863"",
2857"This should really be:", 2864"This should really be:",
2858"", 2865"",
2859" CONFIGURE_ENV+= --with-datafiles=\${PREFIX}/share/battalion"); 2866" CONFIGURE_ENV+= --with-datafiles=\${PREFIX}/share/battalion");
2860 } 2867 }
2861 2868
2862 my $needs_quoting = variable_needs_quoting($line, $varname, $context); 2869 my $needs_quoting = variable_needs_quoting($line, $varname, $context);
2863 2870
2864 if ($context->shellword == VUC_SHELLWORD_FOR) { 2871 if ($context->shellword == VUC_SHELLWORD_FOR) {
2865 if (!defined($type)) { 2872 if (!defined($type)) {
2866 # Cannot check anything here. 2873 # Cannot check anything here.
2867 2874
2868 } elsif ($type->kind_of_list == LK_INTERNAL) { 2875 } elsif ($type->kind_of_list == LK_INTERNAL) {
2869 # Fine. 2876 # Fine.
2870 2877
2871 } elsif ($needs_quoting == doesnt_matter || $needs_quoting == false) { 2878 } elsif ($needs_quoting == doesnt_matter || $needs_quoting == false) {
2872 # Fine, these variables are assumed to not 2879 # Fine, these variables are assumed to not
2873 # contain special characters. 2880 # contain special characters.
2874 2881
2875 } else { 2882 } else {
2876 $line->log_warning("The variable ${varname} should not be used in .for loops."); 2883 $line->log_warning("The variable ${varname} should not be used in .for loops.");
2877 $line->explain_warning( 2884 $line->explain_warning(
2878"The .for loop splits its argument at sequences of white-space, as", 2885"The .for loop splits its argument at sequences of white-space, as",
2879"opposed to all other places in make(1), which act like the shell.", 2886"opposed to all other places in make(1), which act like the shell.",
2880"Therefore only variables that are specifically designed to match this", 2887"Therefore only variables that are specifically designed to match this",
2881"requirement should be used here."); 2888"requirement should be used here.");
2882 } 2889 }
2883 } 2890 }
2884 2891
2885 if ($opt_warn_quoting and $context->shellword != VUC_SHELLWORD_UNKNOWN && $needs_quoting != dont_know) { 2892 if ($opt_warn_quoting and $context->shellword != VUC_SHELLWORD_UNKNOWN && $needs_quoting != dont_know) {
2886 2893
2887 # In GNU configure scripts, a few variables need to be 2894 # In GNU configure scripts, a few variables need to be
2888 # passed through the :M* operator before they reach the 2895 # passed through the :M* operator before they reach the
2889 # configure scripts. 2896 # configure scripts.
2890 my $need_mstar = false; 2897 my $need_mstar = false;
2891 if ($varname =~ regex_gnu_configure_volatile_vars) { 2898 if ($varname =~ regex_gnu_configure_volatile_vars) {
2892 # When we are not checking a package, but some other file, 2899 # When we are not checking a package, but some other file,
2893 # the :M* operator is needed for safety. 2900 # the :M* operator is needed for safety.
2894 if (!defined($pkgctx_vardef) || exists($pkgctx_vardef->{"GNU_CONFIGURE"})) { 2901 if (!defined($pkgctx_vardef) || exists($pkgctx_vardef->{"GNU_CONFIGURE"})) {
2895 $need_mstar = true; 2902 $need_mstar = true;
2896 } 2903 }
2897 } 2904 }
2898 2905
2899 my $stripped_mod = ($mod =~ m"(.*?)(?::M\*)?(?::Q)?$") ? $1 : $mod; 2906 my $stripped_mod = ($mod =~ m"(.*?)(?::M\*)?(?::Q)?$") ? $1 : $mod;
2900 my $correct_mod = $stripped_mod . ($need_mstar ? ":M*:Q" : ":Q"); 2907 my $correct_mod = $stripped_mod . ($need_mstar ? ":M*:Q" : ":Q");
2901 2908
2902 if ($mod eq ":M*:Q" && !$need_mstar) { 2909 if ($mod eq ":M*:Q" && !$need_mstar) {
2903 $line->log_note("The :M* modifier is not needed here."); 2910 $line->log_note("The :M* modifier is not needed here.");
2904 2911
2905 } elsif ($mod ne $correct_mod && $needs_quoting == true) { 2912 } elsif ($mod ne $correct_mod && $needs_quoting == true) {
2906 if ($context->shellword == VUC_SHELLWORD_PLAIN) { 2913 if ($context->shellword == VUC_SHELLWORD_PLAIN) {
2907 $line->log_warning("Please use \${${varname}${correct_mod}} instead of \${${varname}${mod}}."); 2914 $line->log_warning("Please use \${${varname}${correct_mod}} instead of \${${varname}${mod}}.");
2908 #$line->replace("\${${varname}}", "\${${varname}:Q}"); 2915 #$line->replace("\${${varname}}", "\${${varname}:Q}");
2909 } else { 2916 } else {
2910 $line->log_warning("Please use \${${varname}${correct_mod}} instead of \${${varname}${mod}} and make sure the variable appears outside of any quoting characters."); 2917 $line->log_warning("Please use \${${varname}${correct_mod}} instead of \${${varname}${mod}} and make sure the variable appears outside of any quoting characters.");
2911 } 2918 }
2912 $line->explain_warning("See the pkgsrc guide, section \"quoting guideline\", for details."); 2919 $line->explain_warning("See the pkgsrc guide, section \"quoting guideline\", for details.");
2913 } 2920 }
2914 2921
2915 if ($mod =~ m":Q$") { 2922 if ($mod =~ m":Q$") {
2916 my @expl = ( 2923 my @expl = (
2917"Many variables in pkgsrc do not need the :Q operator, since they", 2924"Many variables in pkgsrc do not need the :Q operator, since they",
2918"are not expected to contain white-space or other evil characters.", 2925"are not expected to contain white-space or other evil characters.",
2919"", 2926"",
2920"Another case is when a variable of type ShellWord appears in a context", 2927"Another case is when a variable of type ShellWord appears in a context",
2921"that expects a shell word, it does not need to have a :Q operator. Even", 2928"that expects a shell word, it does not need to have a :Q operator. Even",
2922"when it is concatenated with another variable, it still stays _one_ word.", 2929"when it is concatenated with another variable, it still stays _one_ word.",
2923"", 2930"",
2924"Example:", 2931"Example:",
2925"\tWORD1= Have\\ fun # 1 word", 2932"\tWORD1= Have\\ fun # 1 word",
2926"\tWORD2= \"with BSD Make\" # 1 word, too", 2933"\tWORD2= \"with BSD Make\" # 1 word, too",
2927"", 2934"",
2928"\tdemo:", 2935"\tdemo:",
2929"\t\techo \${WORD1}\${WORD2} # still 1 word"); 2936"\t\techo \${WORD1}\${WORD2} # still 1 word");
2930 2937
2931 if ($needs_quoting == false) { 2938 if ($needs_quoting == false) {
2932 $line->log_warning("The :Q operator should not be used for \${${varname}} here."); 2939 $line->log_warning("The :Q operator should not be used for \${${varname}} here.");
2933 $line->explain_warning(@expl); 2940 $line->explain_warning(@expl);
2934 } elsif ($needs_quoting == doesnt_matter) { 2941 } elsif ($needs_quoting == doesnt_matter) {
2935 $line->log_note("The :Q operator isn't necessary for \${${varname}} here."); 2942 $line->log_note("The :Q operator isn't necessary for \${${varname}} here.");
2936 $line->explain_note(@expl); 2943 $line->explain_note(@expl);
2937 } 2944 }
2938 } 2945 }
2939 } 2946 }
2940 2947
2941 assert(defined($mkctx_build_defs), "The build_defs variable must be defined here."); 2948 assert(defined($mkctx_build_defs), "The build_defs variable must be defined here.");
2942 if (exists(get_userdefined_variables()->{$varname}) && !exists(get_system_build_defs()->{$varname}) && !exists($mkctx_build_defs->{$varname})) { 2949 if (exists(get_userdefined_variables()->{$varname}) && !exists(get_system_build_defs()->{$varname}) && !exists($mkctx_build_defs->{$varname})) {
2943 $line->log_warning("The user-defined variable ${varname} is used but not added to BUILD_DEFS."); 2950 $line->log_warning("The user-defined variable ${varname} is used but not added to BUILD_DEFS.");
2944 $line->explain_warning( 2951 $line->explain_warning(
2945"When a pkgsrc package is built, many things can be configured by the", 2952"When a pkgsrc package is built, many things can be configured by the",
2946"pkgsrc user in the mk.conf file. All these configurations should be", 2953"pkgsrc user in the mk.conf file. All these configurations should be",
2947"recorded in the binary package, so the package can be reliably rebuilt.", 2954"recorded in the binary package, so the package can be reliably rebuilt.",
2948"The BUILD_DEFS variable contains a list of all these user-settable", 2955"The BUILD_DEFS variable contains a list of all these user-settable",
2949"variables, so please add your variable to it, too."); 2956"variables, so please add your variable to it, too.");
2950 } 2957 }
2951} 2958}
2952 2959
2953sub checkline_mk_text($$) { 2960sub checkline_mk_text($$) {
2954 my ($line, $text) = @_; 2961 my ($line, $text) = @_;
2955 my ($rest, $state, $vartools, $depr_map); 2962 my ($rest, $state, $vartools, $depr_map);
2956 2963
2957 if ($text =~ m"^(?:[^#]*[^\$])?\$(\w+)") { 2964 if ($text =~ m"^(?:[^#]*[^\$])?\$(\w+)") {
2958 my ($varname) = ($1); 2965 my ($varname) = ($1);
2959 $line->log_warning("\$$varname is ambiguous. Use \${$varname} if you mean a Makefile variable or \$\$$varname if you mean a shell variable."); 2966 $line->log_warning("\$$varname is ambiguous. Use \${$varname} if you mean a Makefile variable or \$\$$varname if you mean a shell variable.");
2960 } 2967 }
2961 2968
2962 if ($line->lines eq "1") { 2969 if ($line->lines eq "1") {
2963 checkline_rcsid_regex($line, qr"#\s+", "# "); 2970 checkline_rcsid_regex($line, qr"#\s+", "# ");
2964 } 2971 }
2965 2972
2966 if ($text =~ m"\$\{WRKSRC\}/\.\./") { 2973 if ($text =~ m"\$\{WRKSRC\}/\.\./") {
2967 $line->log_warning("Using \"\${WRKSRC}/..\" is conceptually wrong. Please use a combination of WRKSRC, CONFIGURE_DIRS and BUILD_DIRS instead."); 2974 $line->log_warning("Using \"\${WRKSRC}/..\" is conceptually wrong. Please use a combination of WRKSRC, CONFIGURE_DIRS and BUILD_DIRS instead.");
2968 $line->explain_warning( 2975 $line->explain_warning(
2969"You should define WRKSRC such that all of CONFIGURE_DIRS, BUILD_DIRS", 2976"You should define WRKSRC such that all of CONFIGURE_DIRS, BUILD_DIRS",
2970"and INSTALL_DIRS are subdirectories of it."); 2977"and INSTALL_DIRS are subdirectories of it.");
2971 } 2978 }
2972 2979
2973 if ($text =~ m"\b(-Wl,--rpath,|-Wl,-rpath-link,|-Wl,-rpath,|-Wl,-R)\b") { 2980 if ($text =~ m"\b(-Wl,--rpath,|-Wl,-rpath-link,|-Wl,-rpath,|-Wl,-R)\b") {
2974 $line->log_warning("Please use \${COMPILER_RPATH_FLAG} instead of $1."); 2981 $line->log_warning("Please use \${COMPILER_RPATH_FLAG} instead of $1.");
2975 } 2982 }
2976 # Note: A simple -R is not detected, as the rate of false 2983 # Note: A simple -R is not detected, as the rate of false
2977 # positives is too high. 2984 # positives is too high.
2978 2985
2979 $rest = $text; 2986 $rest = $text;
2980 $depr_map = get_deprecated_map(); 2987 $depr_map = get_deprecated_map();
2981 while ($rest =~ s/(?:^|[^\$])\$\{([-A-Z0-9a-z_]+)(\.[\-0-9A-Z_a-z]+)?(?::[^\}]+)?\}//) { 2988 while ($rest =~ s/(?:^|[^\$])\$\{([-A-Z0-9a-z_]+)(\.[\-0-9A-Z_a-z]+)?(?::[^\}]+)?\}//) {
2982 my ($varbase, $varext) = ($1, $2); 2989 my ($varbase, $varext) = ($1, $2);
2983 my $varname = $varbase . (defined($varext) ? $varext : ""); 2990 my $varname = $varbase . (defined($varext) ? $varext : "");
2984 my $varcanon = varname_canon($varname); 2991 my $varcanon = varname_canon($varname);
2985 my $instead = 2992 my $instead =
2986 (exists($depr_map->{$varname})) ? $depr_map->{$varname} 2993 (exists($depr_map->{$varname})) ? $depr_map->{$varname}
2987 : (exists($depr_map->{$varcanon})) ? $depr_map->{$varcanon} 2994 : (exists($depr_map->{$varcanon})) ? $depr_map->{$varcanon}
2988 : undef; 2995 : undef;
2989 2996
2990 if (defined($instead)) { 2997 if (defined($instead)) {
2991 $line->log_warning("Use of ${varname} is deprecated. ${instead}"); 2998 $line->log_warning("Use of ${varname} is deprecated. ${instead}");
2992 } 2999 }
2993 } 3000 }
2994 3001
2995 # Don't enforce purely aesthetic changes before more correct behaviour is implemented: 3002 # Don't enforce purely aesthetic changes before more correct behaviour is implemented:
2996 # $rest = $text; 3003 # $rest = $text;
2997 # while ($rest =~ s/(?:^|[^\$])\$\(([-A-Z0-9a-z_]+)(?::[^\}]+)?\)//) { 3004 # while ($rest =~ s/(?:^|[^\$])\$\(([-A-Z0-9a-z_]+)(?::[^\}]+)?\)//) {
2998 # my ($varname) = ($1); 3005 # my ($varname) = ($1);
2999 3006
3000 # $line->log_warning("Please use \${${varname}\} instead of \$(${varname})."); 3007 # $line->log_warning("Please use \${${varname}\} instead of \$(${varname}).");
3001 # } 3008 # }
3002 3009
3003} 3010}
3004 3011
3005sub checkline_mk_shellword($$$) { 3012sub checkline_mk_shellword($$$) {
3006 my ($line, $shellword, $check_quoting) = @_; 3013 my ($line, $shellword, $check_quoting) = @_;
3007 my ($rest, $state, $value); 3014 my ($rest, $state, $value);
3008 3015
3009 $opt_debug_trace and $line->log_debug("checkline_mk_shellword(\"${shellword}\", ${check_quoting})."); 3016 $opt_debug_trace and $line->log_debug("checkline_mk_shellword(\"${shellword}\", ${check_quoting}).");
3010 use constant shellcommand_context_type => PkgLint::Type->new( 3017 use constant shellcommand_context_type => PkgLint::Type->new(
3011 LK_NONE, "ShellCommand", [[ qr".*", "adsu" ]], NOT_GUESSED 3018 LK_NONE, "ShellCommand", [[ qr".*", "adsu" ]], NOT_GUESSED
3012 ); 3019 );
3013 use constant shellword_vuc => PkgLint::VarUseContext->new( 3020 use constant shellword_vuc => PkgLint::VarUseContext->new(
3014 VUC_TIME_UNKNOWN, 3021 VUC_TIME_UNKNOWN,
3015 shellcommand_context_type, 3022 shellcommand_context_type,
3016 VUC_SHELLWORD_PLAIN, 3023 VUC_SHELLWORD_PLAIN,
3017 VUC_EXTENT_WORD 3024 VUC_EXTENT_WORD
3018 ); 3025 );
3019 3026
3020 if ($shellword =~ m"^\$\{(${regex_varname})(:[^{}]+)?\}$") { 3027 if ($shellword =~ m"^\$\{(${regex_varname})(:[^{}]+)?\}$") {
3021 my ($varname, $mod) = ($1, $2); 3028 my ($varname, $mod) = ($1, $2);
3022 3029
3023 checkline_mk_varuse($line, $varname, defined($mod) ? $mod : "", shellword_vuc); 3030 checkline_mk_varuse($line, $varname, defined($mod) ? $mod : "", shellword_vuc);
3024 return; 3031 return;
3025 } 3032 }
3026 3033
3027 if ($shellword =~ m"\$\{PREFIX\}/man(?:$|/)") { 3034 if ($shellword =~ m"\$\{PREFIX\}/man(?:$|/)") {
3028 $line->log_warning("Please use \${PKGMANDIR} instead of \"man\"."); 3035 $line->log_warning("Please use \${PKGMANDIR} instead of \"man\".");
3029 } 3036 }
3030 3037
3031 if ($shellword =~ m"etc/rc\.d") { 3038 if ($shellword =~ m"etc/rc\.d") {
3032 $line->log_warning("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to \${RCD_SCRIPTS_EXAMPLEDIR}."); 3039 $line->log_warning("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to \${RCD_SCRIPTS_EXAMPLEDIR}.");
3033 } 3040 }
3034 3041
3035 # Note: SWST means [S]hell[W]ord [ST]ate 3042 # Note: SWST means [S]hell[W]ord [ST]ate
3036 use enum qw(:SWST_ PLAIN SQUOT DQUOT DQUOT_BACKT BACKT); 3043 use enum qw(:SWST_ PLAIN SQUOT DQUOT DQUOT_BACKT BACKT);
3037 use constant statename => [ 3044 use constant statename => [
3038 "SWST_PLAIN", "SWST_SQUOT", "SWST_DQUOT", 3045 "SWST_PLAIN", "SWST_SQUOT", "SWST_DQUOT",
3039 "SWST_DQUOT_BACKT", "SWST_BACKT", 3046 "SWST_DQUOT_BACKT", "SWST_BACKT",
3040 ]; 3047 ];
3041 use constant user_statename => [ 3048 use constant user_statename => [
3042 "unquoted string", "single quoted string", 3049 "unquoted string", "single quoted string",
3043 "double quoted string", "backticks inside double quoted string", 3050 "double quoted string", "backticks inside double quoted string",
3044 "backticks", 3051 "backticks",
3045 ]; 3052 ];
3046 3053
3047 $rest = ($shellword =~ m"^#") ? "" : $shellword; 3054 $rest = ($shellword =~ m"^#") ? "" : $shellword;
3048 $state = SWST_PLAIN; 3055 $state = SWST_PLAIN;
3049 while ($rest ne "") { 3056 while ($rest ne "") {
3050 3057
3051 $opt_debug_shell and $line->log_debug(statename->[$state] . ": ${rest}"); 3058 $opt_debug_shell and $line->log_debug(statename->[$state] . ": ${rest}");
3052 3059
3053 # When we are parsing inside backticks, it is more 3060 # When we are parsing inside backticks, it is more
3054 # reasonable to check the whole shell command 3061 # reasonable to check the whole shell command
3055 # recursively, instead of splitting off the first 3062 # recursively, instead of splitting off the first
3056 # make(1) variable (see the elsif below). 3063 # make(1) variable (see the elsif below).
3057 if ($state == SWST_BACKT || $state == SWST_DQUOT_BACKT) { 3064 if ($state == SWST_BACKT || $state == SWST_DQUOT_BACKT) {
3058 3065
3059 # Scan for the end of the backticks, checking 3066 # Scan for the end of the backticks, checking
3060 # for single backslashes and removing one level 3067 # for single backslashes and removing one level
3061 # of backslashes. Backslashes are only removed 3068 # of backslashes. Backslashes are only removed
3062 # before a dollar, a backslash or a backtick. 3069 # before a dollar, a backslash or a backtick.
3063 # 3070 #
3064 # References: 3071 # References:
3065 # * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03 3072 # * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03
3066 my $stripped = ""; 3073 my $stripped = "";
3067 while ($rest ne "") { 3074 while ($rest ne "") {
3068 if ($rest =~ s/^\`//) { 3075 if ($rest =~ s/^\`//) {
3069 $state = ($state == SWST_BACKT) ? SWST_PLAIN : SWST_DQUOT; 3076 $state = ($state == SWST_BACKT) ? SWST_PLAIN : SWST_DQUOT;
3070 goto end_of_backquotes; 3077 goto end_of_backquotes;
3071 } elsif ($rest =~ s/^\\([\\\`\$])//) { 3078 } elsif ($rest =~ s/^\\([\\\`\$])//) {
3072 $stripped .= $1; 3079 $stripped .= $1;
3073 } elsif ($rest =~ s/^(\\)//) { 3080 } elsif ($rest =~ s/^(\\)//) {
3074 $line->log_warning("Backslashes should be doubled inside backticks."); 3081 $line->log_warning("Backslashes should be doubled inside backticks.");
3075 $stripped .= $1; 3082 $stripped .= $1;
3076 } elsif ($state == SWST_DQUOT_BACKT && $rest =~ s/^"//) { 3083 } elsif ($state == SWST_DQUOT_BACKT && $rest =~ s/^"//) {
3077 $line->log_warning("Double quotes inside backticks inside double quotes are error prone."); 3084 $line->log_warning("Double quotes inside backticks inside double quotes are error prone.");
3078 $line->explain_warning( 3085 $line->explain_warning(
3079"According to the SUSv3, they produce undefined results.", 3086"According to the SUSv3, they produce undefined results.",
3080"", 3087"",
3081"See the paragraph starting \"Within the backquoted ...\" in", 3088"See the paragraph starting \"Within the backquoted ...\" in",
3082"http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html"); 3089"http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html");
3083 } elsif ($rest =~ s/^([^\\\`]+)//) { 3090 } elsif ($rest =~ s/^([^\\\`]+)//) {
3084 $stripped .= $1; 3091 $stripped .= $1;
3085 } else { 3092 } else {
3086 assert(false, "rest=$rest"); 3093 assert(false, "rest=$rest");
3087 } 3094 }
3088 } 3095 }
3089 $line->log_error("Unfinished backquotes: rest=$rest"); 3096 $line->log_error("Unfinished backquotes: rest=$rest");
3090 3097
3091 end_of_backquotes: 3098 end_of_backquotes:
3092 # Check the resulting command. 3099 # Check the resulting command.
3093 checkline_mk_shelltext($line, $stripped); 3100 checkline_mk_shelltext($line, $stripped);
3094 3101
3095 # make(1) variables have the same syntax, no matter in 3102 # make(1) variables have the same syntax, no matter in
3096 # which state we are currently. 3103 # which state we are currently.
3097 } elsif ($rest =~ s/^\$\{(${regex_varname}|[\@])(:[^\{]+)?\}// 3104 } elsif ($rest =~ s/^\$\{(${regex_varname}|[\@])(:[^\{]+)?\}//
3098 || $rest =~ s/^\$\((${regex_varname}|[\@])(:[^\)]+)?\)// 3105 || $rest =~ s/^\$\((${regex_varname}|[\@])(:[^\)]+)?\)//
3099 || $rest =~ s/^\$([\w\@])//) { 3106 || $rest =~ s/^\$([\w\@])//) {
3100 my ($varname, $mod) = ($1, $2); 3107 my ($varname, $mod) = ($1, $2);
3101 3108
3102 if ($varname eq "\@") { 3109 if ($varname eq "\@") {
3103 $line->log_warning("Please use \"\${.TARGET}\" instead of \"\$\@\"."); 3110 $line->log_warning("Please use \"\${.TARGET}\" instead of \"\$\@\".");
3104 $line->explain_warning( 3111 $line->explain_warning(
3105"The variable \$\@ can easily be confused with the shell variable of the", 3112"The variable \$\@ can easily be confused with the shell variable of the",
3106"same name, which has a completely different meaning."); 3113"same name, which has a completely different meaning.");
3107 $varname = ".TARGET"; 3114 $varname = ".TARGET";
3108 } 3115 }
3109 3116
3110 if ($state == SWST_PLAIN && defined($mod) && $mod =~ m":Q$") { 3117 if ($state == SWST_PLAIN && defined($mod) && $mod =~ m":Q$") {
3111 # Fine. 3118 # Fine.
3112 3119
3113 } elsif ($state == SWST_BACKT) { 3120 } elsif ($state == SWST_BACKT) {
3114 # Don't check here, to avoid false positives 3121 # Don't check here, to avoid false positives
3115 # for tool names. 3122 # for tool names.
3116 3123
3117 } elsif (($state == SWST_SQUOT || $state == SWST_DQUOT) && $varname =~ m"^(?:.*DIR|.*FILE|.*PATH|.*_VAR|PREFIX|.*BASE|PKGNAME)$") { 3124 } elsif (($state == SWST_SQUOT || $state == SWST_DQUOT) && $varname =~ m"^(?:.*DIR|.*FILE|.*PATH|.*_VAR|PREFIX|.*BASE|PKGNAME)$") {
3118 # This is ok if we don't allow these 3125 # This is ok if we don't allow these
3119 # variables to have embedded [\$\\\"\'\`]. 3126 # variables to have embedded [\$\\\"\'\`].
3120 3127
3121 } elsif ($state == SWST_DQUOT && defined($mod) && $mod =~ m":Q$") { 3128 } elsif ($state == SWST_DQUOT && defined($mod) && $mod =~ m":Q$") {
3122 $line->log_warning("Please don't use the :Q operator in double quotes."); 3129 $line->log_warning("Please don't use the :Q operator in double quotes.");
3123 $line->explain_warning( 3130 $line->explain_warning(
3124"Either remove the :Q or the double quotes. In most cases, it is more", 3131"Either remove the :Q or the double quotes. In most cases, it is more",
3125"appropriate to remove the double quotes."); 3132"appropriate to remove the double quotes.");
3126 3133
3127 } 3134 }
3128 3135
3129 my $ctx = PkgLint::VarUseContext->new_from_pool( 3136 my $ctx = PkgLint::VarUseContext->new_from_pool(
3130 VUC_TIME_UNKNOWN, 3137 VUC_TIME_UNKNOWN,
3131 shellcommand_context_type, 3138 shellcommand_context_type,
3132 ($state == SWST_PLAIN) ? VUC_SHELLWORD_PLAIN 3139 ($state == SWST_PLAIN) ? VUC_SHELLWORD_PLAIN
3133 : ($state == SWST_DQUOT) ? VUC_SHELLWORD_DQUOT 3140 : ($state == SWST_DQUOT) ? VUC_SHELLWORD_DQUOT
3134 : ($state == SWST_SQUOT) ? VUC_SHELLWORD_SQUOT 3141 : ($state == SWST_SQUOT) ? VUC_SHELLWORD_SQUOT
3135 : ($state == SWST_BACKT) ? VUC_SHELLWORD_BACKT 3142 : ($state == SWST_BACKT) ? VUC_SHELLWORD_BACKT
3136 : VUC_SHELLWORD_UNKNOWN, 3143 : VUC_SHELLWORD_UNKNOWN,
3137 VUC_EXTENT_WORD_PART 3144 VUC_EXTENT_WORD_PART
3138 ); 3145 );
3139 if ($varname ne "\@") { 3146 if ($varname ne "\@") {
3140 checkline_mk_varuse($line, $varname, defined($mod) ? $mod : "", $ctx); 3147 checkline_mk_varuse($line, $varname, defined($mod) ? $mod : "", $ctx);
3141 } 3148 }
3142 3149
3143 # The syntax of the variable modifiers can get quite 3150 # The syntax of the variable modifiers can get quite
3144 # hairy. In lack of motivation, we just skip anything 3151 # hairy. In lack of motivation, we just skip anything
3145 # complicated, hoping that at least the braces are 3152 # complicated, hoping that at least the braces are
3146 # balanced. 3153 # balanced.
3147 } elsif ($rest =~ s/^\$\{//) { 3154 } elsif ($rest =~ s/^\$\{//) {
3148 my $braces = 1; 3155 my $braces = 1;
3149 while ($rest ne "" && $braces > 0) { 3156 while ($rest ne "" && $braces > 0) {
3150 if ($rest =~ s/^\}//) { 3157 if ($rest =~ s/^\}//) {
3151 $braces--; 3158 $braces--;
3152 } elsif ($rest =~ s/^\{//) { 3159 } elsif ($rest =~ s/^\{//) {
3153 $braces++; 3160 $braces++;
3154 } elsif ($rest =~ s/^[^{}]+//) { 3161 } elsif ($rest =~ s/^[^{}]+//) {
3155 # Nothing to do here. 3162 # Nothing to do here.
3156 } else { 3163 } else {
3157 last; 3164 last;
3158 } 3165 }
3159 } 3166 }
3160 3167
3161 } elsif ($state == SWST_PLAIN) { 3168 } elsif ($state == SWST_PLAIN) {
3162 3169
3163 # XXX: This is only true for the "first" word in a 3170 # XXX: This is only true for the "first" word in a
3164 # shell command, not for every word. For example, 3171 # shell command, not for every word. For example,
3165 # FOO_ENV+= VAR=`command` may be underquoted. 3172 # FOO_ENV+= VAR=`command` may be underquoted.
3166 if (false && $rest =~ m"([\w_]+)=\"\`") { 3173 if (false && $rest =~ m"([\w_]+)=\"\`") {
3167 $line->log_note("In the assignment to \"$1\", you don't need double quotes around backticks."); 3174 $line->log_note("In the assignment to \"$1\", you don't need double quotes around backticks.");
3168 $line->explain_note( 3175 $line->explain_note(
3169"Assignments are a special context, where no double quotes are needed", 3176"Assignments are a special context, where no double quotes are needed",
3170"around backticks. In other contexts, the double quotes are necessary."); 3177"around backticks. In other contexts, the double quotes are necessary.");
3171 } 3178 }
3172 3179
3173 if ($rest =~ s/^[!#\%&\(\)*+,\-.\/0-9:;<=>?\@A-Z\[\]^_a-z{|}~]+//) { 3180 if ($rest =~ s/^[!#\%&\(\)*+,\-.\/0-9:;<=>?\@A-Z\[\]^_a-z{|}~]+//) {
3174 } elsif ($rest =~ s/^\'//) { 3181 } elsif ($rest =~ s/^\'//) {
3175 $state = SWST_SQUOT; 3182 $state = SWST_SQUOT;
3176 } elsif ($rest =~ s/^\"//) { 3183 } elsif ($rest =~ s/^\"//) {
3177 $state = SWST_DQUOT; 3184 $state = SWST_DQUOT;
3178 } elsif ($rest =~ s/^\`//) { 3185 } elsif ($rest =~ s/^\`//) {
3179 $state = SWST_BACKT; 3186 $state = SWST_BACKT;
3180 } elsif ($rest =~ s/^\\(?:[ !"#'\(\)*;?\\^{|}]|\$\$)//) { 3187 } elsif ($rest =~ s/^\\(?:[ !"#'\(\)*;?\\^{|}]|\$\$)//) {
3181 } elsif ($rest =~ s/^\$\$([0-9A-Z_a-z]+|\#)// 3188 } elsif ($rest =~ s/^\$\$([0-9A-Z_a-z]+|\#)//
3182 || $rest =~ s/^\$\$\{([0-9A-Z_a-z]+|\#)\}// 3189 || $rest =~ s/^\$\$\{([0-9A-Z_a-z]+|\#)\}//
3183 || $rest =~ s/^\$\$(\$)\$//) { 3190 || $rest =~ s/^\$\$(\$)\$//) {
3184 my ($shvarname) = ($1); 3191 my ($shvarname) = ($1);
3185 if ($opt_warn_quoting && $check_quoting) { 3192 if ($opt_warn_quoting && $check_quoting) {
3186 $line->log_warning("Unquoted shell variable \"${shvarname}\"."); 3193 $line->log_warning("Unquoted shell variable \"${shvarname}\".");
3187 $line->explain_warning( 3194 $line->explain_warning(
3188"When a shell variable contains white-space, it is expanded (split into",  3195"When a shell variable contains white-space, it is expanded (split into",
3189"multiple words) when it is written as \$variable in a shell script.", 3196"multiple words) when it is written as \$variable in a shell script.",
3190"If that is not intended, you should add quotation marks around it,", 3197"If that is not intended, you should add quotation marks around it,",
3191"like \"\$variable\". Then, the variable will always expand to a single", 3198"like \"\$variable\". Then, the variable will always expand to a single",
3192"word, preserving all white-space and other special characters.", 3199"word, preserving all white-space and other special characters.",
3193"", 3200"",
3194"Example:", 3201"Example:",
3195"\tfname=\"Curriculum vitae.doc\"", 3202"\tfname=\"Curriculum vitae.doc\"",
3196"\tcp \$fname /tmp", 3203"\tcp \$fname /tmp",
3197"\t# tries to copy the two files \"Curriculum\" and \"Vitae.doc\"", 3204"\t# tries to copy the two files \"Curriculum\" and \"Vitae.doc\"",
3198"\tcp \"\$fname\" /tmp", 3205"\tcp \"\$fname\" /tmp",
3199"\t# copies one file, as intended"); 3206"\t# copies one file, as intended");
3200 } 3207 }
3201 3208
3202 } elsif ($rest =~ s/^\$\@//) { 3209 } elsif ($rest =~ s/^\$\@//) {
3203 $line->log_warning("Please use \"\${.TARGET}\" instead of \"\$@\"."); 3210 $line->log_warning("Please use \"\${.TARGET}\" instead of \"\$@\".");
3204 $line->explain_warning( 3211 $line->explain_warning(
3205"It is more readable and prevents confusion with the shell variable of", 3212"It is more readable and prevents confusion with the shell variable of",
3206"the same name."); 3213"the same name.");
3207 3214
3208 } elsif ($rest =~ s/^\$\$\@//) { 3215 } elsif ($rest =~ s/^\$\$\@//) {
3209 $line->log_warning("The \$@ shell variable should only be used in double quotes."); 3216 $line->log_warning("The \$@ shell variable should only be used in double quotes.");
3210 3217
3211 } elsif ($rest =~ s/^\$\$\?//) { 3218 } elsif ($rest =~ s/^\$\$\?//) {
3212 $line->log_warning("The \$? shell variable is often not available in \"set -e\" mode."); 3219 $line->log_warning("The \$? shell variable is often not available in \"set -e\" mode.");
3213 3220
3214 } elsif ($rest =~ s/^\$\$\(/(/) { 3221 } elsif ($rest =~ s/^\$\$\(/(/) {
3215 $line->log_warning("Invoking subshells via \$(...) is not portable enough."); 3222 $line->log_warning("Invoking subshells via \$(...) is not portable enough.");
3216 $line->explain_warning( 3223 $line->explain_warning(
3217"The Solaris /bin/sh does not know this way to execute a command in a", 3224"The Solaris /bin/sh does not know this way to execute a command in a",
3218"subshell. Please use backticks (\`...\`) as a replacement."); 3225"subshell. Please use backticks (\`...\`) as a replacement.");
3219 3226
3220 } else { 3227 } else {
3221 last; 3228 last;
3222 } 3229 }
3223 3230
3224 } elsif ($state == SWST_SQUOT) { 3231 } elsif ($state == SWST_SQUOT) {
3225 if ($rest =~ s/^\'//) { 3232 if ($rest =~ s/^\'//) {
3226 $state = SWST_PLAIN; 3233 $state = SWST_PLAIN;
3227 } elsif ($rest =~ s/^[^\$\']+//) { 3234 } elsif ($rest =~ s/^[^\$\']+//) {
3228 } elsif ($rest =~ s/^\$\$//) { 3235 } elsif ($rest =~ s/^\$\$//) {
3229 } else { 3236 } else {
3230 last; 3237 last;
3231 } 3238 }
3232 3239
3233 } elsif ($state == SWST_DQUOT) { 3240 } elsif ($state == SWST_DQUOT) {
3234 if ($rest =~ s/^\"//) { 3241 if ($rest =~ s/^\"//) {
3235 $state = SWST_PLAIN; 3242 $state = SWST_PLAIN;
3236 } elsif ($rest =~ s/^\`//) { 3243 } elsif ($rest =~ s/^\`//) {
3237 $state = SWST_DQUOT_BACKT; 3244 $state = SWST_DQUOT_BACKT;
3238 } elsif ($rest =~ s/^[^\$"\\\`]+//) { 3245 } elsif ($rest =~ s/^[^\$"\\\`]+//) {
3239 } elsif ($rest =~ s/^\\(?:[\\\"\`]|\$\$)//) { 3246 } elsif ($rest =~ s/^\\(?:[\\\"\`]|\$\$)//) {
3240 } elsif ($rest =~ s/^\$\$\{([0-9A-Za-z_]+)\}// 3247 } elsif ($rest =~ s/^\$\$\{([0-9A-Za-z_]+)\}//
3241 || $rest =~ s/^\$\$([0-9A-Z_a-z]+|[!#?\@]|\$\$)//) { 3248 || $rest =~ s/^\$\$([0-9A-Z_a-z]+|[!#?\@]|\$\$)//) {
3242 my ($shvarname) = ($1); 3249 my ($shvarname) = ($1);
3243 $opt_debug_shell and $line->log_debug("[checkline_mk_shellword] Found double-quoted variable ${shvarname}."); 3250 $opt_debug_shell and $line->log_debug("[checkline_mk_shellword] Found double-quoted variable ${shvarname}.");
3244 } elsif ($rest =~ s/^\$\$//) { 3251 } elsif ($rest =~ s/^\$\$//) {
3245 $line->log_warning("Unquoted \$ or strange shell variable found."); 3252 $line->log_warning("Unquoted \$ or strange shell variable found.");
3246 } elsif ($rest =~ s/^\\(.)//) { 3253 } elsif ($rest =~ s/^\\(.)//) {
3247 my ($char) = ($1); 3254 my ($char) = ($1);
3248 $line->log_warning("Please use \"\\\\${char}\" instead of \"\\${char}\"."); 3255 $line->log_warning("Please use \"\\\\${char}\" instead of \"\\${char}\".");
3249 $line->explain_warning( 3256 $line->explain_warning(
3250"Although the current code may work, it is not good style to rely on", 3257"Although the current code may work, it is not good style to rely on",
3251"the shell passing \"\\${char}\" exactly as is, and not discarding the", 3258"the shell passing \"\\${char}\" exactly as is, and not discarding the",
3252"backslash. Alternatively you can use single quotes instead of double", 3259"backslash. Alternatively you can use single quotes instead of double",
3253"quotes."); 3260"quotes.");
3254 } else { 3261 } else {
3255 last; 3262 last;
3256 } 3263 }
3257 3264
3258 } else { 3265 } else {
3259 last; 3266 last;
3260 } 3267 }
3261 } 3268 }
3262 if ($rest !~ m"^\s*$") { 3269 if ($rest !~ m"^\s*$") {
3263 $line->log_error("Internal pkglint error: " . statename->[$state] . ": rest=${rest}"); 3270 $line->log_error("Internal pkglint error: " . statename->[$state] . ": rest=${rest}");
3264 } 3271 }
3265} 3272}
3266 3273
3267# Some shell commands should not be used in the install phase. 3274# Some shell commands should not be used in the install phase.
3268# 3275#
3269sub checkline_mk_shellcmd_use($$) { 3276sub checkline_mk_shellcmd_use($$) {
3270 my ($line, $shellcmd) = @_; 3277 my ($line, $shellcmd) = @_;
3271 3278
3272 use constant allowed_install_commands => array_to_hash(qw( 3279 use constant allowed_install_commands => array_to_hash(qw(
3273 ${INSTALL} 3280 ${INSTALL}
3274 ${INSTALL_DATA} ${INSTALL_DATA_DIR} 3281 ${INSTALL_DATA} ${INSTALL_DATA_DIR}
3275 ${INSTALL_LIB} ${INSTALL_LIB_DIR} 3282 ${INSTALL_LIB} ${INSTALL_LIB_DIR}
3276 ${INSTALL_MAN} ${INSTALL_MAN_DIR} 3283 ${INSTALL_MAN} ${INSTALL_MAN_DIR}
3277 ${INSTALL_PROGRAM} ${INSTALL_PROGRAM_DIR} 3284 ${INSTALL_PROGRAM} ${INSTALL_PROGRAM_DIR}
3278 ${INSTALL_SCRIPT} 3285 ${INSTALL_SCRIPT}
3279 ${LIBTOOL} 3286 ${LIBTOOL}
3280 ${LN} 3287 ${LN}
3281 ${PAX} 3288 ${PAX}
3282 )); 3289 ));
3283 use constant discouraged_install_commands => array_to_hash(qw( 3290 use constant discouraged_install_commands => array_to_hash(qw(
3284 sed ${SED} 3291 sed ${SED}
3285 tr ${TR} 3292 tr ${TR}
3286 )); 3293 ));
3287 3294
3288 if (defined($mkctx_target) && $mkctx_target =~ m"^(?:pre|do|post)-install") { 3295 if (defined($mkctx_target) && $mkctx_target =~ m"^(?:pre|do|post)-install") {
3289 3296
3290 if (exists(allowed_install_commands->{$shellcmd})) { 3297 if (exists(allowed_install_commands->{$shellcmd})) {
3291 # Fine. 3298 # Fine.
3292 3299
3293 } elsif (exists(discouraged_install_commands->{$shellcmd})) { 3300 } elsif (exists(discouraged_install_commands->{$shellcmd})) {
3294 $line->log_warning("The shell command \"${shellcmd}\" should not be used in the install phase."); 3301 $line->log_warning("The shell command \"${shellcmd}\" should not be used in the install phase.");
3295 $line->explain_warning( 3302 $line->explain_warning(
3296"In the install phase, the only thing that should be done is to install", 3303"In the install phase, the only thing that should be done is to install",
3297"the prepared files to their final location. The file's contents should", 3304"the prepared files to their final location. The file's contents should",
3298"not be changed anymore."); 3305"not be changed anymore.");
3299 3306
3300 } elsif ($shellcmd eq "\${CP}") { 3307 } elsif ($shellcmd eq "\${CP}") {
3301 $line->log_warning("\${CP} should not be used to install files."); 3308 $line->log_warning("\${CP} should not be used to install files.");
3302 $line->explain_warning( 3309 $line->explain_warning(
3303"The \${CP} command is highly platform dependent and cannot overwrite", 3310"The \${CP} command is highly platform dependent and cannot overwrite",
3304"files that don't have write permission. Please use \${PAX} instead.", 3311"files that don't have write permission. Please use \${PAX} instead.",
3305"", 3312"",
3306"For example, instead of", 3313"For example, instead of",
3307"\t\${CP} -R \${WRKSRC}/* \${PREFIX}/foodir", 3314"\t\${CP} -R \${WRKSRC}/* \${PREFIX}/foodir",
3308"you should use", 3315"you should use",
3309"\tcd \${WRKSRC} && \${PAX} -wr * \${PREFIX}/foodir"); 3316"\tcd \${WRKSRC} && \${PAX} -wr * \${PREFIX}/foodir");
3310 3317
3311 } else { 3318 } else {
3312 $opt_debug_misc and $line->log_debug("May \"${shellcmd}\" be used in the install phase?"); 3319 $opt_debug_misc and $line->log_debug("May \"${shellcmd}\" be used in the install phase?");
3313 } 3320 }
3314 } 3321 }
3315} 3322}
3316 3323
3317sub checkline_mk_shelltext($$) { 3324sub checkline_mk_shelltext($$) {
3318 my ($line, $text) = @_; 3325 my ($line, $text) = @_;
3319 my ($vartools, $state, $rest, $set_e_mode); 3326 my ($vartools, $state, $rest, $set_e_mode);
3320 3327
3321 $opt_debug_trace and $line->log_debug("checkline_mk_shelltext(\"$text\")"); 3328 $opt_debug_trace and $line->log_debug("checkline_mk_shelltext(\"$text\")");
3322 3329
3323 # Note: SCST is the abbreviation for [S]hell [C]ommand [ST]ate. 3330 # Note: SCST is the abbreviation for [S]hell [C]ommand [ST]ate.
3324 use constant scst => qw( 3331 use constant scst => qw(
3325 START CONT 3332 START CONT
3326 INSTALL INSTALL_D 3333 INSTALL INSTALL_D
3327 MKDIR 3334 MKDIR
3328 PAX PAX_S 3335 PAX PAX_S
3329 SED SED_E 3336 SED SED_E
3330 SET SET_CONT 3337 SET SET_CONT
3331 COND COND_CONT 3338 COND COND_CONT
3332 CASE CASE_IN CASE_LABEL CASE_LABEL_CONT CASE_PAREN 3339 CASE CASE_IN CASE_LABEL CASE_LABEL_CONT CASE_PAREN
3333 FOR FOR_IN FOR_CONT 3340 FOR FOR_IN FOR_CONT
3334 ECHO 3341 ECHO
3335 INSTALL_DIR INSTALL_DIR2 3342 INSTALL_DIR INSTALL_DIR2
3336 ); 3343 );
3337 use enum (":SCST_", scst); 3344 use enum (":SCST_", scst);
3338 use constant scst_statename => [ map { $_ = "SCST_$_"; } scst ]; 3345 use constant scst_statename => [ map { $_ = "SCST_$_"; } scst ];
3339 3346
3340 use constant forbidden_commands => array_to_hash(qw( 3347 use constant forbidden_commands => array_to_hash(qw(
3341 ktrace 3348 ktrace
3342 mktexlsr 3349 mktexlsr
3343 strace 3350 strace
3344 texconfig truss 3351 texconfig truss
3345 )); 3352 ));
3346 3353
3347 if ($text =~ m"\$\{SED\}" && $text =~ m"\$\{MV\}") { 3354 if ($text =~ m"\$\{SED\}" && $text =~ m"\$\{MV\}") {
3348 $line->log_note("Please use the SUBST framework instead of \${SED} and \${MV}."); 3355 $line->log_note("Please use the SUBST framework instead of \${SED} and \${MV}.");
3349 $line->explain_note( 3356 $line->explain_note(
3350"When converting things, pay attention to \"#\" characters. In shell", 3357"When converting things, pay attention to \"#\" characters. In shell",
3351"commands make(1) does not interpret them as comment character, but", 3358"commands make(1) does not interpret them as comment character, but",
3352"in other lines it does. Therefore, instead of the shell command", 3359"in other lines it does. Therefore, instead of the shell command",
3353"", 3360"",
3354"\tsed -e 's,#define foo,,'", 3361"\tsed -e 's,#define foo,,'",
3355"", 3362"",
3356"you need to write", 3363"you need to write",
3357"", 3364"",
3358"\tSUBST_SED.foo+=\t's,\\#define foo,,'"); 3365"\tSUBST_SED.foo+=\t's,\\#define foo,,'");
3359 } 3366 }
3360 3367
3361 if ($text =~ m"^\@*-(.*(MKDIR|INSTALL.*-d|INSTALL_.*_DIR).*)") { 3368 if ($text =~ m"^\@*-(.*(MKDIR|INSTALL.*-d|INSTALL_.*_DIR).*)") {
3362 my ($mkdir_cmd) = ($1); 3369 my ($mkdir_cmd) = ($1);
3363 3370
3364 $line->log_note("You don't need to use \"-\" before ${mkdir_cmd}."); 3371 $line->log_note("You don't need to use \"-\" before ${mkdir_cmd}.");
3365 } 3372 }
3366 3373
3367 $vartools = get_vartool_names(); 3374 $vartools = get_vartool_names();
3368 $rest = $text; 3375 $rest = $text;
3369 3376
3370 use constant hidden_shell_commands => array_to_hash(qw( 3377 use constant hidden_shell_commands => array_to_hash(qw(
3371 ${DELAYED_ERROR_MSG} ${DELAYED_WARNING_MSG} 3378 ${DELAYED_ERROR_MSG} ${DELAYED_WARNING_MSG}
3372 ${DO_NADA} 3379 ${DO_NADA}
3373 ${ECHO} ${ECHO_MSG} ${ECHO_N} ${ERROR_CAT} ${ERROR_MSG} 3380 ${ECHO} ${ECHO_MSG} ${ECHO_N} ${ERROR_CAT} ${ERROR_MSG}
3374 ${FAIL_MSG} 3381 ${FAIL_MSG}
3375 ${PHASE_MSG} ${PRINTF} 3382 ${PHASE_MSG} ${PRINTF}
3376 ${SHCOMMENT} ${STEP_MSG} 3383 ${SHCOMMENT} ${STEP_MSG}
3377 ${WARNING_CAT} ${WARNING_MSG} 3384 ${WARNING_CAT} ${WARNING_MSG}
3378 )); 3385 ));
3379 3386
3380 $set_e_mode = false; 3387 $set_e_mode = false;
3381 3388
3382 if ($rest =~ s/^\s*([-@]*)(\$\{_PKG_SILENT\}\$\{_PKG_DEBUG\}|\$\{RUN\}|)//) { 3389 if ($rest =~ s/^\s*([-@]*)(\$\{_PKG_SILENT\}\$\{_PKG_DEBUG\}|\$\{RUN\}|)//) {
3383 my ($hidden, $macro) = ($1, $2); 3390 my ($hidden, $macro) = ($1, $2);
3384 3391
3385 if ($hidden !~ m"\@") { 3392 if ($hidden !~ m"\@") {
3386 # Nothing is hidden at all. 3393 # Nothing is hidden at all.
3387 3394
3388 } elsif (defined($mkctx_target) && $mkctx_target =~ m"^(?:show-.*|.*-message)$") { 3395 } elsif (defined($mkctx_target) && $mkctx_target =~ m"^(?:show-.*|.*-message)$") {
3389 # In some targets commands may be hidden. 3396 # In some targets commands may be hidden.
3390 3397
3391 } elsif ($rest =~ m"^#") { 3398 } elsif ($rest =~ m"^#") {
3392 # Shell comments may be hidden, as they have no side effects 3399 # Shell comments may be hidden, as they have no side effects
3393 3400
3394 } elsif ($rest =~ $regex_shellword) { 3401 } elsif ($rest =~ $regex_shellword) {
3395 my ($cmd) = ($1); 3402 my ($cmd) = ($1);
3396 3403
3397 if (!exists(hidden_shell_commands->{$cmd})) { 3404 if (!exists(hidden_shell_commands->{$cmd})) {
3398 $line->log_warning("The shell command \"${cmd}\" should not be hidden."); 3405 $line->log_warning("The shell command \"${cmd}\" should not be hidden.");
3399 $line->explain_warning( 3406 $line->explain_warning(
3400"Hidden shell commands do not appear on the terminal or in the log file", 3407"Hidden shell commands do not appear on the terminal or in the log file",
3401"when they are executed. When they fail, the error message cannot be", 3408"when they are executed. When they fail, the error message cannot be",
3402"assigned to the command, which is very difficult to debug."); 3409"assigned to the command, which is very difficult to debug.");
3403 } 3410 }
3404 } 3411 }
3405 3412
3406 if ($hidden =~ m"-") { 3413 if ($hidden =~ m"-") {
3407 $line->log_warning("The use of a leading \"-\" to suppress errors is deprecated."); 3414 $line->log_warning("The use of a leading \"-\" to suppress errors is deprecated.");
3408 $line->explain_warning( 3415 $line->explain_warning(
3409"If you really want to ignore any errors from this command (including", 3416"If you really want to ignore any errors from this command (including",
3410"all errors you never thought of), append \"|| \${TRUE}\" to the", 3417"all errors you never thought of), append \"|| \${TRUE}\" to the",
3411"command."); 3418"command.");
3412 } 3419 }
3413 3420
3414 if ($macro eq "\${RUN}") { 3421 if ($macro eq "\${RUN}") {
3415 $set_e_mode = true; 3422 $set_e_mode = true;
3416 } 3423 }
3417 } 3424 }
3418 3425
3419 $state = SCST_START; 3426 $state = SCST_START;
3420 while ($rest =~ s/^$regex_shellword//) { 3427 while ($rest =~ s/^$regex_shellword//) {
3421 my ($shellword) = ($1); 3428 my ($shellword) = ($1);
3422 3429
3423 $opt_debug_shell and $line->log_debug(scst_statename->[$state] . ": ${shellword}"); 3430 $opt_debug_shell and $line->log_debug(scst_statename->[$state] . ": ${shellword}");
3424 3431
3425 checkline_mk_shellword($line, $shellword, !( 3432 checkline_mk_shellword($line, $shellword, !(
3426 $state == SCST_CASE 3433 $state == SCST_CASE
3427 || $state == SCST_FOR_CONT 3434 || $state == SCST_FOR_CONT
3428 || $state == SCST_SET_CONT 3435 || $state == SCST_SET_CONT
3429 || ($state == SCST_START && $shellword =~ regex_sh_varassign))); 3436 || ($state == SCST_START && $shellword =~ regex_sh_varassign)));
3430 3437
3431 # 3438 #
3432 # Actions associated with the current state 3439 # Actions associated with the current state
3433 # and the symbol on the "input tape". 3440 # and the symbol on the "input tape".
3434 # 3441 #
3435 3442
3436 if ($state == SCST_START || $state == SCST_COND) { 3443 if ($state == SCST_START || $state == SCST_COND) {
3437 my ($type); 3444 my ($type);
3438 3445
3439 if ($shellword eq "\${RUN}") { 3446 if ($shellword eq "\${RUN}") {
3440 # Just skip this one. 3447 # Just skip this one.
3441 3448
3442 } elsif (exists(forbidden_commands->{basename($shellword)})) { 3449 } elsif (exists(forbidden_commands->{basename($shellword)})) {
3443 $line->log_error("${shellword} must not be used in Makefiles."); 3450 $line->log_error("${shellword} must not be used in Makefiles.");
3444 $line->explain_error( 3451 $line->explain_error(
3445"This command must appear in INSTALL scripts, not in the package", 3452"This command must appear in INSTALL scripts, not in the package",
3446"Makefile, so that the package also works if it is installed as a binary", 3453"Makefile, so that the package also works if it is installed as a binary",
3447"package via pkg_add."); 3454"package via pkg_add.");
3448 3455
3449 } elsif (exists(get_tool_names()->{$shellword})) { 3456 } elsif (exists(get_tool_names()->{$shellword})) {
3450 if (!exists($mkctx_tools->{$shellword}) && !exists($mkctx_tools->{"g$shellword"})) { 3457 if (!exists($mkctx_tools->{$shellword}) && !exists($mkctx_tools->{"g$shellword"})) {
3451 $line->log_warning("The \"${shellword}\" tool is used but not added to USE_TOOLS."); 3458 $line->log_warning("The \"${shellword}\" tool is used but not added to USE_TOOLS.");
3452 } 3459 }
3453 3460
3454 if (exists(get_required_vartools()->{$shellword})) { 3461 if (exists(get_required_vartools()->{$shellword})) {
3455 $line->log_warning("Please use \"\${" . get_vartool_names()->{$shellword} . "}\" instead of \"${shellword}\"."); 3462 $line->log_warning("Please use \"\${" . get_vartool_names()->{$shellword} . "}\" instead of \"${shellword}\".");
3456 } 3463 }
3457 3464
3458 checkline_mk_shellcmd_use($line, $shellword); 3465 checkline_mk_shellcmd_use($line, $shellword);
3459 3466
3460 } elsif ($shellword =~ m"^\$\{([\w_]+)\}$" && exists(get_varname_to_toolname()->{$1})) { 3467 } elsif ($shellword =~ m"^\$\{([\w_]+)\}$" && exists(get_varname_to_toolname()->{$1})) {
3461 my ($vartool) = ($1); 3468 my ($vartool) = ($1);
3462 my $plain_tool = get_varname_to_toolname()->{$vartool}; 3469 my $plain_tool = get_varname_to_toolname()->{$vartool};
3463 3470
3464 if (!exists($mkctx_tools->{$plain_tool})) { 3471 if (!exists($mkctx_tools->{$plain_tool})) {
3465 $line->log_warning("The \"${plain_tool}\" tool is used but not added to USE_TOOLS."); 3472 $line->log_warning("The \"${plain_tool}\" tool is used but not added to USE_TOOLS.");
3466 } 3473 }
3467 3474
3468 # Deactivated to allow package developers to write 3475 # Deactivated to allow package developers to write
3469 # consistent code that uses ${TOOL} in all places. 3476 # consistent code that uses ${TOOL} in all places.
3470 if (false && defined($mkctx_target) && $mkctx_target =~ m"^(?:pre|do|post)-(?:extract|patch|wrapper|configure|build|install|package|clean)$") { 3477 if (false && defined($mkctx_target) && $mkctx_target =~ m"^(?:pre|do|post)-(?:extract|patch|wrapper|configure|build|install|package|clean)$") {
3471 if (!exists(get_required_vartool_varnames()->{$vartool})) { 3478 if (!exists(get_required_vartool_varnames()->{$vartool})) {
3472 $opt_warn_extra and $line->log_note("You can write \"${plain_tool}\" instead of \"${shellword}\"."); 3479 $opt_warn_extra and $line->log_note("You can write \"${plain_tool}\" instead of \"${shellword}\".");
3473 $opt_warn_extra and $line->explain_note( 3480 $opt_warn_extra and $line->explain_note(
3474"The wrapper framework from pkgsrc takes care that a sufficiently", 3481"The wrapper framework from pkgsrc takes care that a sufficiently",
3475"capable implementation of that tool will be selected.", 3482"capable implementation of that tool will be selected.",
3476"", 3483"",
3477"Calling the commands by their plain name instead of the macros is", 3484"Calling the commands by their plain name instead of the macros is",
3478"only available in the {pre,do,post}-* targets. For all other targets,", 3485"only available in the {pre,do,post}-* targets. For all other targets,",
3479"you should still use the macros."); 3486"you should still use the macros.");
3480 } 3487 }
3481 } 3488 }
3482 3489
3483 checkline_mk_shellcmd_use($line, $shellword); 3490 checkline_mk_shellcmd_use($line, $shellword);
3484 3491
3485 } elsif ($shellword =~ m"^\$\{([\w_]+)\}$" && defined($type = get_variable_type($line, $1)) && $type->basic_type eq "ShellCommand") { 3492 } elsif ($shellword =~ m"^\$\{([\w_]+)\}$" && defined($type = get_variable_type($line, $1)) && $type->basic_type eq "ShellCommand") {
3486 checkline_mk_shellcmd_use($line, $shellword); 3493 checkline_mk_shellcmd_use($line, $shellword);
3487 3494
3488 } elsif ($shellword =~ m"^\$\{(\w+)\}$" && defined($pkgctx_vardef) && exists($pkgctx_vardef->{$1})) { 3495 } elsif ($shellword =~ m"^\$\{(\w+)\}$" && defined($pkgctx_vardef) && exists($pkgctx_vardef->{$1})) {
3489 # When the package author has explicitly 3496 # When the package author has explicitly
3490 # defined a command variable, assume it 3497 # defined a command variable, assume it
3491 # to be valid. 3498 # to be valid.
3492 3499
3493 } elsif ($shellword =~ m"^(?:\(|\)|:|;|;;|&&|\|\||\{|\}|break|case|cd|continue|do|done|elif|else|esac|eval|exec|exit|export|fi|for|if|read|set|shift|then|umask|unset|while)$") { 3500 } elsif ($shellword =~ m"^(?:\(|\)|:|;|;;|&&|\|\||\{|\}|break|case|cd|continue|do|done|elif|else|esac|eval|exec|exit|export|fi|for|if|read|set|shift|then|umask|unset|while)$") {
3494 # Shell builtins are fine. 3501 # Shell builtins are fine.
3495 3502
3496 } elsif ($shellword =~ m"^[\w_]+=.*$") { 3503 } elsif ($shellword =~ m"^[\w_]+=.*$") {
3497 # Variable assignment. 3504 # Variable assignment.
3498 3505
3499 } elsif ($shellword =~ m"^\./.*$") { 3506 } elsif ($shellword =~ m"^\./.*$") {
3500 # All commands from the current directory are fine. 3507 # All commands from the current directory are fine.
3501 3508
3502 } elsif ($shellword =~ m"^#") { 3509 } elsif ($shellword =~ m"^#") {
3503 my $semicolon = ($shellword =~ m";"); 3510 my $semicolon = ($shellword =~ m";");
3504 my $multiline = ($line->lines =~ m"--"); 3511 my $multiline = ($line->lines =~ m"--");
3505 3512
3506 if ($semicolon) { 3513 if ($semicolon) {
3507 $line->log_warning("A shell comment should not contain semicolons."); 3514 $line->log_warning("A shell comment should not contain semicolons.");
3508 } 3515 }
3509 if ($multiline) { 3516 if ($multiline) {
3510 $line->log_warning("A shell comment does not stop at the end of line."); 3517 $line->log_warning("A shell comment does not stop at the end of line.");
3511 } 3518 }
3512 3519
3513 if ($semicolon || $multiline) { 3520 if ($semicolon || $multiline) {
3514 $line->explain_warning( 3521 $line->explain_warning(
3515"When you split a shell command into multiple lines that are continued", 3522"When you split a shell command into multiple lines that are continued",
3516"with a backslash, they will nevertheless be converted to a single line", 3523"with a backslash, they will nevertheless be converted to a single line",
3517"before the shell sees them. That means that even if it _looks_ like that", 3524"before the shell sees them. That means that even if it _looks_ like that",
3518"the comment only spans one line in the Makefile, in fact it spans until", 3525"the comment only spans one line in the Makefile, in fact it spans until",
3519"the end of the whole shell command. To insert a comment into shell code,", 3526"the end of the whole shell command. To insert a comment into shell code,",
3520"you can pass it as an argument to the \${SHCOMMENT} macro, which expands", 3527"you can pass it as an argument to the \${SHCOMMENT} macro, which expands",
3521"to a command doing nothing. Note that any special characters are", 3528"to a command doing nothing. Note that any special characters are",
3522"nevertheless interpreted by the shell."); 3529"nevertheless interpreted by the shell.");
3523 } 3530 }
3524 3531
3525 } else { 3532 } else {
3526 $opt_warn_extra and $line->log_warning("Unknown shell command \"${shellword}\"."); 3533 $opt_warn_extra and $line->log_warning("Unknown shell command \"${shellword}\".");
3527 $opt_warn_extra and $line->explain_warning( 3534 $opt_warn_extra and $line->explain_warning(
3528"If you want your package to be portable to all platforms that pkgsrc", 3535"If you want your package to be portable to all platforms that pkgsrc",
3529"supports, you should only use shell commands that are covered by the", 3536"supports, you should only use shell commands that are covered by the",
3530"tools framework."); 3537"tools framework.");
3531 3538
3532 } 3539 }
3533 } 3540 }
3534 3541
3535 if ($state == SCST_COND && $shellword eq "cd") { 3542 if ($state == SCST_COND && $shellword eq "cd") {
3536 $line->log_error("The Solaris /bin/sh cannot handle \"cd\" inside conditionals."); 3543 $line->log_error("The Solaris /bin/sh cannot handle \"cd\" inside conditionals.");
3537 $line->explain_error( 3544 $line->explain_error(
3538"When the Solaris shell is in \"set -e\" mode and \"cd\" fails, the", 3545"When the Solaris shell is in \"set -e\" mode and \"cd\" fails, the",
3539"shell will exit, no matter if it is protected by an \"if\" or the", 3546"shell will exit, no matter if it is protected by an \"if\" or the",
3540"\"||\" operator."); 3547"\"||\" operator.");
3541 } 3548 }
3542 3549
3543 if (($state != SCST_PAX_S && $state != SCST_SED_E && $state != SCST_CASE_LABEL)) { 3550 if (($state != SCST_PAX_S && $state != SCST_SED_E && $state != SCST_CASE_LABEL)) {
3544 checkline_mk_absolute_pathname($line, $shellword); 3551 checkline_mk_absolute_pathname($line, $shellword);
3545 } 3552 }
3546 3553
3547 if (($state == SCST_INSTALL_D || $state == SCST_MKDIR) && $shellword =~ m"^(?:\$\{DESTDIR\})?\$\{PREFIX(?:|:Q)\}/") { 3554 if (($state == SCST_INSTALL_D || $state == SCST_MKDIR) && $shellword =~ m"^(?:\$\{DESTDIR\})?\$\{PREFIX(?:|:Q)\}/") {
3548 $line->log_warning("Please use AUTO_MKDIRS instead of " 3555 $line->log_warning("Please use AUTO_MKDIRS instead of "
3549 . (($state == SCST_MKDIR) ? "\${MKDIR}" : "\${INSTALL} -d") 3556 . (($state == SCST_MKDIR) ? "\${MKDIR}" : "\${INSTALL} -d")
3550 . "."); 3557 . ".");
3551 $line->explain_warning( 3558 $line->explain_warning(
3552"Setting AUTO_MKDIRS=yes automatically creates all directories that are", 3559"Setting AUTO_MKDIRS=yes automatically creates all directories that are",
3553"mentioned in the PLIST. If you need additional directories, specify", 3560"mentioned in the PLIST. If you need additional directories, specify",
3554"them in INSTALLATION_DIRS, which is a list of directories relative to", 3561"them in INSTALLATION_DIRS, which is a list of directories relative to",
3555"\${PREFIX}."); 3562"\${PREFIX}.");
3556 } 3563 }
3557 3564
3558 if (($state == SCST_INSTALL_DIR || $state == SCST_INSTALL_DIR2) && $shellword !~ regex_mk_shellvaruse && $shellword =~ m"^(?:\${DESTDIR\})?\$\{PREFIX(?:|:Q)\}/(.*)") { 3565 if (($state == SCST_INSTALL_DIR || $state == SCST_INSTALL_DIR2) && $shellword !~ regex_mk_shellvaruse && $shellword =~ m"^(?:\${DESTDIR\})?\$\{PREFIX(?:|:Q)\}/(.*)") {
3559 my ($dirname) = ($1); 3566 my ($dirname) = ($1);
3560 3567
3561 $line->log_note("You can use AUTO_MKDIRS=yes or INSTALLATION_DIRS+= ${dirname} instead of this command."); 3568 $line->log_note("You can use AUTO_MKDIRS=yes or INSTALLATION_DIRS+= ${dirname} instead of this command.");
3562 $line->explain_note( 3569 $line->explain_note(
3563"This saves you some typing. You also don't have to think about which of", 3570"This saves you some typing. You also don't have to think about which of",
3564"the many INSTALL_*_DIR macros is appropriate, since INSTALLATION_DIRS", 3571"the many INSTALL_*_DIR macros is appropriate, since INSTALLATION_DIRS",
3565"takes care of that.", 3572"takes care of that.",
3566"", 3573"",
3567"Note that you should only do this if the package creates _all_", 3574"Note that you should only do this if the package creates _all_",
3568"directories it needs before trying to install files into them.", 3575"directories it needs before trying to install files into them.",
3569"", 3576"",
3570"Many packages include a list of all needed directories in their PLIST", 3577"Many packages include a list of all needed directories in their PLIST",
3571"file. In that case, you can just set AUTO_MKDIRS=yes and be done."); 3578"file. In that case, you can just set AUTO_MKDIRS=yes and be done.");
3572 } 3579 }
3573 3580
3574 if ($state == SCST_INSTALL_DIR2 && $shellword =~ m"^\$") { 3581 if ($state == SCST_INSTALL_DIR2 && $shellword =~ m"^\$") {
3575 $line->log_warning("The INSTALL_*_DIR commands can only handle one directory at a time."); 3582 $line->log_warning("The INSTALL_*_DIR commands can only handle one directory at a time.");
3576 $line->explain_warning( 3583 $line->explain_warning(
3577"Many implementations of install(1) can handle more, but pkgsrc aims at", 3584"Many implementations of install(1) can handle more, but pkgsrc aims at",
3578"maximum portability."); 3585"maximum portability.");
3579 } 3586 }
3580 3587
3581 if ($state == SCST_PAX && $shellword eq "-pe") { 3588 if ($state == SCST_PAX && $shellword eq "-pe") {
3582 $line->log_warning("Please use the -pp option to pax(1) instead of -pe."); 3589 $line->log_warning("Please use the -pp option to pax(1) instead of -pe.");
3583 $line->explain_warning( 3590 $line->explain_warning(
3584"The -pe option tells pax to preserve the ownership of the files, which", 3591"The -pe option tells pax to preserve the ownership of the files, which",
3585"means that the installed files will belong to the user that has built", 3592"means that the installed files will belong to the user that has built",
3586"the package. That's a Bad Thing."); 3593"the package. That's a Bad Thing.");
3587 } 3594 }
3588 3595
3589 if ($state == SCST_PAX_S || $state == SCST_SED_E) { 3596 if ($state == SCST_PAX_S || $state == SCST_SED_E) {
3590 if (false && $shellword !~ m"^[\"\'].*[\"\']$") { 3597 if (false && $shellword !~ m"^[\"\'].*[\"\']$") {
3591 $line->log_warning("Substitution commands like \"${shellword}\" should always be quoted."); 3598 $line->log_warning("Substitution commands like \"${shellword}\" should always be quoted.");
3592 $line->explain_warning( 3599 $line->explain_warning(
3593"Usually these substitution commands contain characters like '*' or", 3600"Usually these substitution commands contain characters like '*' or",
3594"other shell metacharacters that might lead to lookup of matching", 3601"other shell metacharacters that might lead to lookup of matching",
3595"filenames and then expand to more than one word."); 3602"filenames and then expand to more than one word.");
3596 } 3603 }
3597 } 3604 }
3598 3605
3599 if ($state == SCST_ECHO && $shellword eq "-n") { 3606 if ($state == SCST_ECHO && $shellword eq "-n") {
3600 $line->log_warning("Please use \${ECHO_N} instead of \"echo -n\"."); 3607 $line->log_warning("Please use \${ECHO_N} instead of \"echo -n\".");
3601 } 3608 }
3602 3609
3603 if ($opt_warn_extra && $state != SCST_CASE_LABEL_CONT && $shellword eq "|") { 3610 if ($opt_warn_extra && $state != SCST_CASE_LABEL_CONT && $shellword eq "|") {
3604 $line->log_warning("The exitcode of the left-hand-side command of the pipe operator is ignored."); 3611 $line->log_warning("The exitcode of the left-hand-side command of the pipe operator is ignored.");
3605 $line->explain_warning( 3612 $line->explain_warning(
3606"If you need to detect the failure of the left-hand-side command, use", 3613"If you need to detect the failure of the left-hand-side command, use",
3607"temporary files to save the output of the command."); 3614"temporary files to save the output of the command.");
3608 } 3615 }
3609 3616
3610 if ($opt_warn_extra && $shellword eq ";" && $state != SCST_COND_CONT && $state != SCST_FOR_CONT && !$set_e_mode) { 3617 if ($opt_warn_extra && $shellword eq ";" && $state != SCST_COND_CONT && $state != SCST_FOR_CONT && !$set_e_mode) {
3611 $line->log_warning("Please switch to \"set -e\" mode before using a semicolon to separate commands."); 3618 $line->log_warning("Please switch to \"set -e\" mode before using a semicolon to separate commands.");
3612 $line->explain_warning( 3619 $line->explain_warning(
3613"Older versions of the NetBSD make(1) had run the shell commands using", 3620"Older versions of the NetBSD make(1) had run the shell commands using",
3614"the \"-e\" option of /bin/sh. In 2004, this behavior has been changed to", 3621"the \"-e\" option of /bin/sh. In 2004, this behavior has been changed to",
3615"follow the POSIX conventions, which is to not use the \"-e\" option.", 3622"follow the POSIX conventions, which is to not use the \"-e\" option.",
3616"The consequence of this change is that shell programs don't terminate", 3623"The consequence of this change is that shell programs don't terminate",
3617"as soon as an error occurs, but try to continue with the next command.", 3624"as soon as an error occurs, but try to continue with the next command.",
3618"Imagine what would happen for these commands:", 3625"Imagine what would happen for these commands:",
3619" cd \"\$HOME\"; cd /nonexistent; rm -rf *", 3626" cd \"\$HOME\"; cd /nonexistent; rm -rf *",
3620"To fix this warning, either insert \"set -e\" at the beginning of this", 3627"To fix this warning, either insert \"set -e\" at the beginning of this",
3621"line or use the \"&&\" operator instead of the semicolon."); 3628"line or use the \"&&\" operator instead of the semicolon.");
3622 } 3629 }
3623 3630
3624 # 3631 #
3625 # State transition. 3632 # State transition.
3626 # 3633 #
3627 3634
3628 if ($state == SCST_SET && $shellword =~ m"^-.*e") { 3635 if ($state == SCST_SET && $shellword =~ m"^-.*e") {
3629 $set_e_mode = true; 3636 $set_e_mode = true;
3630 } 3637 }
3631 if ($state == SCST_START && $shellword eq "\${RUN}") { 3638 if ($state == SCST_START && $shellword eq "\${RUN}") {
3632 $set_e_mode = true; 3639 $set_e_mode = true;
3633 } 3640 }
3634 3641
3635 $state = ($shellword eq ";;") ? SCST_CASE_LABEL 3642 $state = ($shellword eq ";;") ? SCST_CASE_LABEL
3636 # Note: The order of the following two lines is important. 3643 # Note: The order of the following two lines is important.
3637 : ($state == SCST_CASE_LABEL_CONT && $shellword eq "|") ? SCST_CASE_LABEL 3644 : ($state == SCST_CASE_LABEL_CONT && $shellword eq "|") ? SCST_CASE_LABEL
3638 : ($shellword =~ m"^[;&\|]+$") ? SCST_START 3645 : ($shellword =~ m"^[;&\|]+$") ? SCST_START
3639 : ($state == SCST_START) ? ( 3646 : ($state == SCST_START) ? (
3640 ($shellword eq "\${INSTALL}") ? SCST_INSTALL 3647 ($shellword eq "\${INSTALL}") ? SCST_INSTALL
3641 : ($shellword eq "\${MKDIR}") ? SCST_MKDIR 3648 : ($shellword eq "\${MKDIR}") ? SCST_MKDIR
3642 : ($shellword eq "\${PAX}") ? SCST_PAX 3649 : ($shellword eq "\${PAX}") ? SCST_PAX
3643 : ($shellword eq "\${SED}") ? SCST_SED 3650 : ($shellword eq "\${SED}") ? SCST_SED
3644 : ($shellword eq "\${ECHO}") ? SCST_ECHO 3651 : ($shellword eq "\${ECHO}") ? SCST_ECHO
3645 : ($shellword eq "\${RUN}") ? SCST_START 3652 : ($shellword eq "\${RUN}") ? SCST_START
3646 : ($shellword eq "echo") ? SCST_ECHO 3653 : ($shellword eq "echo") ? SCST_ECHO
3647 : ($shellword eq "set") ? SCST_SET 3654 : ($shellword eq "set") ? SCST_SET
3648 : ($shellword =~ m"^(?:if|elif|while)$") ? SCST_COND 3655 : ($shellword =~ m"^(?:if|elif|while)$") ? SCST_COND
3649 : ($shellword =~ m"^(?:then|else|do)$") ? SCST_START 3656 : ($shellword =~ m"^(?:then|else|do)$") ? SCST_START
3650 : ($shellword eq "case") ? SCST_CASE 3657 : ($shellword eq "case") ? SCST_CASE
3651 : ($shellword eq "for") ? SCST_FOR 3658 : ($shellword eq "for") ? SCST_FOR
3652 : ($shellword eq "(") ? SCST_START 3659 : ($shellword eq "(") ? SCST_START
3653 : ($shellword =~ m"^\$\{INSTALL_[A-Z]+_DIR\}$") ? SCST_INSTALL_DIR 3660 : ($shellword =~ m"^\$\{INSTALL_[A-Z]+_DIR\}$") ? SCST_INSTALL_DIR
3654 : ($shellword =~ regex_sh_varassign) ? SCST_START 3661 : ($shellword =~ regex_sh_varassign) ? SCST_START
3655 : SCST_CONT) 3662 : SCST_CONT)
3656 : ($state == SCST_MKDIR) ? SCST_MKDIR 3663 : ($state == SCST_MKDIR) ? SCST_MKDIR
3657 : ($state == SCST_INSTALL && $shellword eq "-d") ? SCST_INSTALL_D 3664 : ($state == SCST_INSTALL && $shellword eq "-d") ? SCST_INSTALL_D
3658 : ($state == SCST_INSTALL || $state == SCST_INSTALL_D) ? ( 3665 : ($state == SCST_INSTALL || $state == SCST_INSTALL_D) ? (
3659 ($shellword =~ m"^-[ogm]$") ? SCST_CONT 3666 ($shellword =~ m"^-[ogm]$") ? SCST_CONT
3660 : $state) 3667 : $state)
3661 : ($state == SCST_INSTALL_DIR) ? ( 3668 : ($state == SCST_INSTALL_DIR) ? (
3662 ($shellword =~ m"^-") ? SCST_CONT 3669 ($shellword =~ m"^-") ? SCST_CONT
3663 : ($shellword =~ m"^\$") ? SCST_INSTALL_DIR2 3670 : ($shellword =~ m"^\$") ? SCST_INSTALL_DIR2
3664 : $state) 3671 : $state)
3665 : ($state == SCST_INSTALL_DIR2) ? $state 3672 : ($state == SCST_INSTALL_DIR2) ? $state
3666 : ($state == SCST_PAX) ? ( 3673 : ($state == SCST_PAX) ? (
3667 ($shellword eq "-s") ? SCST_PAX_S 3674 ($shellword eq "-s") ? SCST_PAX_S
3668 : ($shellword =~ m"^-") ? SCST_PAX 3675 : ($shellword =~ m"^-") ? SCST_PAX
3669 : SCST_CONT) 3676 : SCST_CONT)
3670 : ($state == SCST_PAX_S) ? SCST_PAX 3677 : ($state == SCST_PAX_S) ? SCST_PAX
3671 : ($state == SCST_SED) ? ( 3678 : ($state == SCST_SED) ? (
3672 ($shellword eq "-e") ? SCST_SED_E 3679 ($shellword eq "-e") ? SCST_SED_E
3673 : ($shellword =~ m"^-") ? SCST_SED 3680 : ($shellword =~ m"^-") ? SCST_SED
3674 : SCST_CONT) 3681 : SCST_CONT)
3675 : ($state == SCST_SED_E) ? SCST_SED 3682 : ($state == SCST_SED_E) ? SCST_SED
3676 : ($state == SCST_SET) ? SCST_SET_CONT 3683 : ($state == SCST_SET) ? SCST_SET_CONT
3677 : ($state == SCST_SET_CONT) ? SCST_SET_CONT 3684 : ($state == SCST_SET_CONT) ? SCST_SET_CONT
3678 : ($state == SCST_CASE) ? SCST_CASE_IN 3685 : ($state == SCST_CASE) ? SCST_CASE_IN
3679 : ($state == SCST_CASE_IN && $shellword eq "in") ? SCST_CASE_LABEL 3686 : ($state == SCST_CASE_IN && $shellword eq "in") ? SCST_CASE_LABEL
3680 : ($state == SCST_CASE_LABEL && $shellword eq "esac") ? SCST_CONT 3687 : ($state == SCST_CASE_LABEL && $shellword eq "esac") ? SCST_CONT
3681 : ($state == SCST_CASE_LABEL) ? SCST_CASE_LABEL_CONT 3688 : ($state == SCST_CASE_LABEL) ? SCST_CASE_LABEL_CONT
3682 : ($state == SCST_CASE_LABEL_CONT && $shellword eq ")") ? SCST_START 3689 : ($state == SCST_CASE_LABEL_CONT && $shellword eq ")") ? SCST_START
3683 : ($state == SCST_CONT) ? SCST_CONT 3690 : ($state == SCST_CONT) ? SCST_CONT
3684 : ($state == SCST_COND) ? SCST_COND_CONT 3691 : ($state == SCST_COND) ? SCST_COND_CONT
3685 : ($state == SCST_COND_CONT) ? SCST_COND_CONT 3692 : ($state == SCST_COND_CONT) ? SCST_COND_CONT
3686 : ($state == SCST_FOR) ? SCST_FOR_IN 3693 : ($state == SCST_FOR) ? SCST_FOR_IN
3687 : ($state == SCST_FOR_IN && $shellword eq "in") ? SCST_FOR_CONT 3694 : ($state == SCST_FOR_IN && $shellword eq "in") ? SCST_FOR_CONT
3688 : ($state == SCST_FOR_CONT) ? SCST_FOR_CONT 3695 : ($state == SCST_FOR_CONT) ? SCST_FOR_CONT
3689 : ($state == SCST_ECHO) ? SCST_CONT 3696 : ($state == SCST_ECHO) ? SCST_CONT
3690 : do { 3697 : do {
3691 $line->log_warning("[" . scst_statename->[$state] . " ${shellword}] Keeping the current state."); 3698 $line->log_warning("[" . scst_statename->[$state] . " ${shellword}] Keeping the current state.");
3692 $state; 3699 $state;
3693 }; 3700 };
3694 } 3701 }
3695 3702
3696 if ($rest !~ m"^\s*$") { 3703 if ($rest !~ m"^\s*$") {
3697 $line->log_error("Internal pkglint error: " . scst_statename->[$state] . ": rest=${rest}"); 3704 $line->log_error("Internal pkglint error: " . scst_statename->[$state] . ": rest=${rest}");
3698 } 3705 }
3699} 3706}
3700 3707
3701sub checkline_mk_shellcmd($$) { 3708sub checkline_mk_shellcmd($$) {
3702 my ($line, $shellcmd) = @_; 3709 my ($line, $shellcmd) = @_;
3703 3710
3704 checkline_mk_text($line, $shellcmd); 3711 checkline_mk_text($line, $shellcmd);
3705 checkline_mk_shelltext($line, $shellcmd); 3712 checkline_mk_shelltext($line, $shellcmd);
3706} 3713}
3707 3714
3708sub expand_permission($) { 3715sub expand_permission($) {
3709 my ($perm) = @_; 3716 my ($perm) = @_;
3710 my %fullperm = ( "a" => "append", "d" => "default", "p" => "preprocess", "s" => "set", "u" => "runtime", "?" => "unknown" ); 3717 my %fullperm = ( "a" => "append", "d" => "default", "p" => "preprocess", "s" => "set", "u" => "runtime", "?" => "unknown" );
3711 my $result = join(", ", map { $fullperm{$_} } split //, $perm); 3718 my $result = join(", ", map { $fullperm{$_} } split //, $perm);
3712 $result =~ s/, $//g; 3719 $result =~ s/, $//g;
3713 3720
3714 return $result; 3721 return $result;
3715} 3722}
3716 3723
3717sub checkline_mk_vardef($$$) { 3724sub checkline_mk_vardef($$$) {
3718 my ($line, $varname, $op) = @_; 3725 my ($line, $varname, $op) = @_;
3719 3726
3720 $opt_debug_trace and $line->log_debug("checkline_mk_vardef(${varname}, ${op})"); 3727 $opt_debug_trace and $line->log_debug("checkline_mk_vardef(${varname}, ${op})");
3721 3728
3722 # If we are checking a whole package, add it to the package-wide 3729 # If we are checking a whole package, add it to the package-wide
3723 # list of defined variables. 3730 # list of defined variables.
3724 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{$varname})) { 3731 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{$varname})) {
3725 $pkgctx_vardef->{$varname} = $line; 3732 $pkgctx_vardef->{$varname} = $line;
3726 } 3733 }
3727 3734
3728 # Add it to the file-wide list of defined variables. 3735 # Add it to the file-wide list of defined variables.
3729 if (!exists($mkctx_vardef->{$varname})) { 3736 if (!exists($mkctx_vardef->{$varname})) {
3730 $mkctx_vardef->{$varname} = $line; 3737 $mkctx_vardef->{$varname} = $line;
3731 } 3738 }
3732 3739
3733 return unless $opt_warn_perm; 3740 return unless $opt_warn_perm;
3734 3741
3735 my $perms = get_variable_perms($line, $varname); 3742 my $perms = get_variable_perms($line, $varname);
3736 my $needed = { "=" => "s", "!=" => "s", "?=" => "d", "+=" => "a", ":=" => "s" }->{$op}; 3743 my $needed = { "=" => "s", "!=" => "s", "?=" => "d", "+=" => "a", ":=" => "s" }->{$op};
3737 if (index($perms, $needed) == -1) { 3744 if (index($perms, $needed) == -1) {
3738 $line->log_warning("Permission [" . expand_permission($needed) . "] requested for ${varname}, but only [" . expand_permission($perms) . "] is allowed."); 3745 $line->log_warning("Permission [" . expand_permission($needed) . "] requested for ${varname}, but only [" . expand_permission($perms) . "] is allowed.");
3739 $line->explain_warning( 3746 $line->explain_warning(
3740"The available permissions are:", 3747"The available permissions are:",
3741"\tappend\t\tappend something using +=", 3748"\tappend\t\tappend something using +=",
3742"\tdefault\t\tset a default value using ?=", 3749"\tdefault\t\tset a default value using ?=",
3743"\tpreprocess\tuse a variable during preprocessing", 3750"\tpreprocess\tuse a variable during preprocessing",
3744"\truntime\t\tuse a variable at runtime", 3751"\truntime\t\tuse a variable at runtime",
3745"\tset\t\tset a variable using :=, =, !=", 3752"\tset\t\tset a variable using :=, =, !=",
3746"", 3753"",
3747"A \"?\" means that it is not yet clear which permissions are allowed", 3754"A \"?\" means that it is not yet clear which permissions are allowed",
3748"and which aren't."); 3755"and which aren't.");
3749 } 3756 }
3750} 3757}
3751 3758
3752# @param $op 3759# @param $op
3753# The operator that is used for reading or writing to the variable. 3760# The operator that is used for reading or writing to the variable.
3754# One of: "=", "+=", ":=", "!=", "?=", "use", "pp-use", "". 3761# One of: "=", "+=", ":=", "!=", "?=", "use", "pp-use", "".
3755# For some variables (like BuildlinkDepth or BuildlinkPackages), the 3762# For some variables (like BuildlinkDepth or BuildlinkPackages), the
3756# operator influences the valid values. 3763# operator influences the valid values.
3757# @param $comment 3764# @param $comment
3758# In assignments, a part of the line may be commented out. If there 3765# In assignments, a part of the line may be commented out. If there
3759# is no comment, pass C<undef>. 3766# is no comment, pass C<undef>.
3760# 3767#
3761sub checkline_mk_vartype_basic($$$$$$$$); 3768sub checkline_mk_vartype_basic($$$$$$$$);
3762sub checkline_mk_vartype_basic($$$$$$$$) { 3769sub checkline_mk_vartype_basic($$$$$$$$) {
3763 my ($line, $varname, $type, $op, $value, $comment, $list_context, $is_guessed) = @_; 3770 my ($line, $varname, $type, $op, $value, $comment, $list_context, $is_guessed) = @_;
3764 my ($value_novar); 3771 my ($value_novar);
3765 3772
3766 $opt_debug_trace and $line->log_debug(sprintf("checkline_mk_vartype_basic(%s, %s, %s, %s, %s, %s, %s)", 3773 $opt_debug_trace and $line->log_debug(sprintf("checkline_mk_vartype_basic(%s, %s, %s, %s, %s, %s, %s)",
3767 $varname, $type, $op, $value, defined($comment) ? $comment : "<undef>", $list_context, $is_guessed)); 3774 $varname, $type, $op, $value, defined($comment) ? $comment : "<undef>", $list_context, $is_guessed));
3768 3775
3769 $value_novar = $value; 3776 $value_novar = $value;
3770 while ($value_novar =~ s/\$\{([^{}]*)\}//g) { 3777 while ($value_novar =~ s/\$\{([^{}]*)\}//g) {
3771 my ($varuse) = ($1); 3778 my ($varuse) = ($1);
3772 if (!$list_context && $varuse =~ m":Q$") { 3779 if (!$list_context && $varuse =~ m":Q$") {
3773 $line->log_warning("The :Q operator should only be used in lists and shell commands."); 3780 $line->log_warning("The :Q operator should only be used in lists and shell commands.");
3774 } 3781 }
3775 } 3782 }
3776 3783
3777 my %type_dispatch = ( 3784 my %type_dispatch = (
3778 AwkCommand => sub { 3785 AwkCommand => sub {
3779 $opt_debug_unchecked and $line->log_debug("Unchecked AWK command: ${value}"); 3786 $opt_debug_unchecked and $line->log_debug("Unchecked AWK command: ${value}");
3780 }, 3787 },
3781 3788
3782 BrokenIn => sub { 3789 BrokenIn => sub {
3783 if ($value ne $value_novar) { 3790 if ($value ne $value_novar) {
3784 $line->log_error("${varname} must not refer to other variables."); 3791 $line->log_error("${varname} must not refer to other variables.");
3785 3792
3786 } elsif ($value =~ m"^pkgsrc-(\d\d\d\d)Q(\d)$") { 3793 } elsif ($value =~ m"^pkgsrc-(\d\d\d\d)Q(\d)$") {
3787 my ($year, $quarter) = ($1, $2); 3794 my ($year, $quarter) = ($1, $2);
3788 3795
3789 # Fine. 3796 # Fine.
3790 3797
3791 } else { 3798 } else {
3792 $line->log_warning("Invalid value \"${value}\" for ${varname}."); 3799 $line->log_warning("Invalid value \"${value}\" for ${varname}.");
3793 } 3800 }
3794 $line->log_note("Please remove this line if the package builds for you."); 3801 $line->log_note("Please remove this line if the package builds for you.");
3795 }, 3802 },
3796 3803
3797 BuildlinkDepmethod => sub { 3804 BuildlinkDepmethod => sub {
3798 # Note: this cannot be replaced with { build full } because 3805 # Note: this cannot be replaced with { build full } because
3799 # enumerations may not contain references to other variables. 3806 # enumerations may not contain references to other variables.
3800 if ($value ne $value_novar) { 3807 if ($value ne $value_novar) {
3801 # No checks yet. 3808 # No checks yet.
3802 } elsif ($value ne "build" && $value ne "full") { 3809 } elsif ($value ne "build" && $value ne "full") {
3803 $line->log_warning("Invalid dependency method \"${value}\". Valid methods are \"build\" or \"full\"."); 3810 $line->log_warning("Invalid dependency method \"${value}\". Valid methods are \"build\" or \"full\".");
3804 } 3811 }
3805 }, 3812 },
3806 3813
3807 BuildlinkDepth => sub { 3814 BuildlinkDepth => sub {
3808 if (!($op eq "use" && $value eq "+") 3815 if (!($op eq "use" && $value eq "+")
3809 && $value ne "\${BUILDLINK_DEPTH}+" 3816 && $value ne "\${BUILDLINK_DEPTH}+"
3810 && $value ne "\${BUILDLINK_DEPTH:S/+\$//}") { 3817 && $value ne "\${BUILDLINK_DEPTH:S/+\$//}") {
3811 $line->log_warning("Invalid value for ${varname}."); 3818 $line->log_warning("Invalid value for ${varname}.");
3812 } 3819 }
3813 }, 3820 },
3814 3821
3815 BuildlinkPackages => sub { 3822 BuildlinkPackages => sub {
3816 my $re_del = qr"\$\{BUILDLINK_PACKAGES:N(?:[+\-.0-9A-Z_a-z]|\$\{[^\}]+\})+\}"; 3823 my $re_del = qr"\$\{BUILDLINK_PACKAGES:N(?:[+\-.0-9A-Z_a-z]|\$\{[^\}]+\})+\}";
3817 my $re_add = qr"(?:[+\-.0-9A-Z_a-z]|\$\{[^\}]+\})+"; 3824 my $re_add = qr"(?:[+\-.0-9A-Z_a-z]|\$\{[^\}]+\})+";
3818 3825
3819 if (($op eq ":=" && $value =~ m"^${re_del}$") || 3826 if (($op eq ":=" && $value =~ m"^${re_del}$") ||
3820 ($op eq ":=" && $value =~ m"^${re_del}\s+${re_add}$") || 3827 ($op eq ":=" && $value =~ m"^${re_del}\s+${re_add}$") ||
3821 ($op eq "+=" && $value =~ m"^${re_add}$")) { 3828 ($op eq "+=" && $value =~ m"^${re_add}$")) {
3822 # Fine. 3829 # Fine.
3823 3830
3824 } else { 3831 } else {
3825 $line->log_warning("Invalid value for ${varname}."); 3832 $line->log_warning("Invalid value for ${varname}.");
3826 } 3833 }
3827 }, 3834 },
3828 3835
3829 Category => sub { 3836 Category => sub {
3830 my $allowed_categories = join("|", qw( 3837 my $allowed_categories = join("|", qw(
3831 archivers audio 3838 archivers audio
3832 benchmarks biology 3839 benchmarks biology
3833 cad chat chinese comms converters cross crosspkgtools 3840 cad chat chinese comms converters cross crosspkgtools
3834 databases devel 3841 databases devel
3835 editors emulators 3842 editors emulators
3836 filesystems finance fonts 3843 filesystems finance fonts
3837 games geography gnome gnustep graphics 3844 games geography gnome gnustep graphics
3838 ham 3845 ham
3839 inputmethod 3846 inputmethod
3840 japanese java 3847 japanese java
3841 kde korean 3848 kde korean
3842 lang linux local 3849 lang linux local
3843 mail math mbone meta-pkgs misc multimedia 3850 mail math mbone meta-pkgs misc multimedia
3844 net news 3851 net news
3845 packages parallel perl5 pkgtools plan9 print python 3852 packages parallel perl5 pkgtools plan9 print python
3846 ruby 3853 ruby
3847 scm security shells sysutils 3854 scm security shells sysutils
3848 tcl textproc time tk 3855 tcl textproc time tk
3849 windowmaker wm www 3856 windowmaker wm www
3850 x11 xmms 3857 x11 xmms
3851 )); 3858 ));
3852 if ($value !~ m"^(?:${allowed_categories})$") { 3859 if ($value !~ m"^(?:${allowed_categories})$") {
3853 $line->log_error("Invalid category \"${value}\"."); 3860 $line->log_error("Invalid category \"${value}\".");
3854 } 3861 }
3855 }, 3862 },
3856 3863
3857 CFlag => sub { 3864 CFlag => sub {
3858 if ($value =~ m"^-D([0-9A-Z_a-z]+)=(.*)") { 3865 if ($value =~ m"^-D([0-9A-Z_a-z]+)=(.*)") {
3859 my ($macname, $macval) = ($1, $2); 3866 my ($macname, $macval) = ($1, $2);
3860 3867
3861 # No checks needed, since the macro definitions 3868 # No checks needed, since the macro definitions
3862 # are usually directory names, which don't need 3869 # are usually directory names, which don't need
3863 # any quoting. 3870 # any quoting.
3864 3871
3865 } elsif ($value =~ m"^-[DU]([0-9A-Z_a-z]+)") { 3872 } elsif ($value =~ m"^-[DU]([0-9A-Z_a-z]+)") {
3866 my ($macname) = ($1); 3873 my ($macname) = ($1);
3867 3874
3868 $opt_debug_unchecked and $line->log_debug("Unchecked macro ${macname} in ${varname}."); 3875 $opt_debug_unchecked and $line->log_debug("Unchecked macro ${macname} in ${varname}.");
3869 3876
3870 } elsif ($value =~ m"^-I(.*)") { 3877 } elsif ($value =~ m"^-I(.*)") {
3871 my ($dirname) = ($1); 3878 my ($dirname) = ($1);
3872 3879
3873 $opt_debug_unchecked and $line->log_debug("Unchecked directory ${dirname} in ${varname}."); 3880 $opt_debug_unchecked and $line->log_debug("Unchecked directory ${dirname} in ${varname}.");
3874 3881
3875 } elsif ($value eq "-c99") { 3882 } elsif ($value eq "-c99") {
3876 # Only works on IRIX, but is usually enclosed with 3883 # Only works on IRIX, but is usually enclosed with
3877 # the proper preprocessor conditional. 3884 # the proper preprocessor conditional.
3878 3885
3879 } elsif ($value =~ m"^-[OWfgm]") { 3886 } elsif ($value =~ m"^-[OWfgm]") {
3880 $opt_debug_unchecked and $line->log_debug("Unchecked compiler flag ${value} in ${varname}."); 3887 $opt_debug_unchecked and $line->log_debug("Unchecked compiler flag ${value} in ${varname}.");
3881 3888
3882 } elsif ($value =~ m"^-.*") { 3889 } elsif ($value =~ m"^-.*") {
3883 $line->log_warning("Unknown compiler flag \"${value}\"."); 3890 $line->log_warning("Unknown compiler flag \"${value}\".");
3884 3891
3885 } elsif ($value =~ regex_unresolved) { 3892 } elsif ($value =~ regex_unresolved) {
3886 $opt_debug_unchecked and $line->log_debug("Unchecked CFLAG: ${value}"); 3893 $opt_debug_unchecked and $line->log_debug("Unchecked CFLAG: ${value}");
3887 3894
3888 } else { 3895 } else {
3889 $line->log_warning("Compiler flag \"${value}\" does not start with a dash."); 3896 $line->log_warning("Compiler flag \"${value}\" does not start with a dash.");
3890 } 3897 }
3891 }, 3898 },
3892 3899
3893 Comment => sub { 3900 Comment => sub {
3894 if ($value eq "SHORT_DESCRIPTION_OF_THE_PACKAGE") { 3901 if ($value eq "SHORT_DESCRIPTION_OF_THE_PACKAGE") {
3895 $line->log_error("COMMENT must be set."); 3902 $line->log_error("COMMENT must be set.");
3896 } 3903 }
3897 if ($value =~ m"^(a|an)\s+"i) { 3904 if ($value =~ m"^(a|an)\s+"i) {
3898 $line->log_warning("COMMENT should not begin with '$1'."); 3905 $line->log_warning("COMMENT should not begin with '$1'.");
3899 } 3906 }
3900 if ($value =~ m"^[a-z]") { 3907 if ($value =~ m"^[a-z]") {
3901 $line->log_warning("COMMENT should start with a capital letter."); 3908 $line->log_warning("COMMENT should start with a capital letter.");
3902 } 3909 }
3903 if ($value =~ m"\.$") { 3910 if ($value =~ m"\.$") {
3904 $line->log_warning("COMMENT should not end with a period."); 3911 $line->log_warning("COMMENT should not end with a period.");
3905 } 3912 }
3906 if (length($value) > 70) { 3913 if (length($value) > 70) {
3907 $line->log_warning("COMMENT should not be longer than 70 characters."); 3914 $line->log_warning("COMMENT should not be longer than 70 characters.");
3908 } 3915 }
3909 }, 3916 },
3910 3917
3911 Dependency => sub { 3918 Dependency => sub {
3912 if ($value =~ m"^(${regex_pkgbase})(<|=|>|<=|>=|!=)(${regex_pkgversion})$") { 3919 if ($value =~ m"^(${regex_pkgbase})(<|=|>|<=|>=|!=)(${regex_pkgversion})$") {
3913 my ($depbase, $depop, $depversion) = ($1, $2, $3); 3920 my ($depbase, $depop, $depversion) = ($1, $2, $3);
3914 3921
3915 } elsif ($value =~ m"^(${regex_pkgbase})-(?:\[(.*)\]\*|(\d+(?:\.\d+)*(?:\.\*)?)(\{,nb\*\}|\*|)|(.*))?$") { 3922 } elsif ($value =~ m"^(${regex_pkgbase})-(?:\[(.*)\]\*|(\d+(?:\.\d+)*(?:\.\*)?)(\{,nb\*\}|\*|)|(.*))?$") {
3916 my ($depbase, $bracket, $version, $version_wildcard, $other) = ($1, $2, $3, $4, $5); 3923 my ($depbase, $bracket, $version, $version_wildcard, $other) = ($1, $2, $3, $4, $5);
3917 3924
3918 if (defined($bracket)) { 3925 if (defined($bracket)) {
3919 if ($bracket ne "0-9") { 3926 if ($bracket ne "0-9") {
3920 $line->log_warning("Only [0-9]* is allowed in the numeric part of a dependency."); 3927 $line->log_warning("Only [0-9]* is allowed in the numeric part of a dependency.");
3921 } 3928 }
3922 3929
3923 } elsif (defined($version) && defined($version_wildcard) && $version_wildcard ne "") { 3930 } elsif (defined($version) && defined($version_wildcard) && $version_wildcard ne "") {
3924 # Great. 3931 # Great.
3925 3932
3926 } elsif (defined($version)) { 3933 } elsif (defined($version)) {
3927 $line->log_warning("Please append {,nb*} to the version number of this dependency."); 3934 $line->log_warning("Please append {,nb*} to the version number of this dependency.");
3928 $line->explain_warning( 3935 $line->explain_warning(
3929"Usually, a dependency should stay valid when the PKGREVISION is", 3936"Usually, a dependency should stay valid when the PKGREVISION is",
3930"increased, since those changes are most often editorial. In the", 3937"increased, since those changes are most often editorial. In the",
3931"current form, the dependency only matches if the PKGREVISION is", 3938"current form, the dependency only matches if the PKGREVISION is",
3932"undefined."); 3939"undefined.");
3933 3940
3934 } elsif ($other eq "*") { 3941 } elsif ($other eq "*") {
3935 $line->log_warning("Please use ${depbase}-[0-9]* instead of ${depbase}-*."); 3942 $line->log_warning("Please use ${depbase}-[0-9]* instead of ${depbase}-*.");
3936 $line->explain_warning( 3943 $line->explain_warning(
3937"If you use a * alone, the package specification may match other", 3944"If you use a * alone, the package specification may match other",
3938"packages that have the same prefix, but a longer name. For example,", 3945"packages that have the same prefix, but a longer name. For example,",
3939"foo-* matches foo-1.2, but also foo-client-1.2 and foo-server-1.2."); 3946"foo-* matches foo-1.2, but also foo-client-1.2 and foo-server-1.2.");
3940 3947
3941 } else { 3948 } else {
3942 $line->log_warning("Unknown dependency pattern \"${value}\"."); 3949 $line->log_warning("Unknown dependency pattern \"${value}\".");
3943 } 3950 }
3944 3951
3945 } elsif ($value =~ m"\{") { 3952 } elsif ($value =~ m"\{") {
3946 # Dependency patterns containing alternatives 3953 # Dependency patterns containing alternatives
3947 # are just too hard to check. 3954 # are just too hard to check.
3948 $opt_debug_unchecked and $line->log_debug("Unchecked dependency pattern: ${value}"); 3955 $opt_debug_unchecked and $line->log_debug("Unchecked dependency pattern: ${value}");
3949 3956
3950 } elsif ($value ne $value_novar) { 3957 } elsif ($value ne $value_novar) {
3951 $opt_debug_unchecked and $line->log_debug("Unchecked dependency: ${value}"); 3958 $opt_debug_unchecked and $line->log_debug("Unchecked dependency: ${value}");
3952 3959
3953 } else { 3960 } else {
3954 $line->log_warning("Unknown dependency format: ${value}"); 3961 $line->log_warning("Unknown dependency format: ${value}");
3955 $line->explain_warning( 3962 $line->explain_warning(
3956"Typical dependencies have the form \"package>=2.5\", \"package-[0-9]*\"", 3963"Typical dependencies have the form \"package>=2.5\", \"package-[0-9]*\"",
3957"or \"package-3.141\"."); 3964"or \"package-3.141\".");
3958 } 3965 }
3959 }, 3966 },
3960 3967
3961 DependencyWithPath => sub { 3968 DependencyWithPath => sub {
3962 if ($value =~ regex_unresolved) { 3969 if ($value =~ regex_unresolved) {
3963 # don't even try to check anything 3970 # don't even try to check anything
3964 } elsif ($value =~ m"(.*):(\.\./\.\./([^/]+)/([^/]+))$") { 3971 } elsif ($value =~ m"(.*):(\.\./\.\./([^/]+)/([^/]+))$") {
3965 my ($pattern, $relpath, $cat, $pkg) = ($1, $2, $3, $4); 3972 my ($pattern, $relpath, $cat, $pkg) = ($1, $2, $3, $4);
3966 3973
3967 checkline_relative_pkgdir($line, $relpath); 3974 checkline_relative_pkgdir($line, $relpath);
3968 3975
3969 if ($pkg eq "msgfmt" || $pkg eq "gettext") { 3976 if ($pkg eq "msgfmt" || $pkg eq "gettext") {
3970 $line->log_warning("Please use USE_TOOLS+=msgfmt instead of this dependency."); 3977 $line->log_warning("Please use USE_TOOLS+=msgfmt instead of this dependency.");
3971 3978
3972 } elsif ($pkg =~ m"^perl\d+") { 3979 } elsif ($pkg =~ m"^perl\d+") {
3973 $line->log_warning("Please use USE_TOOLS+=perl:run instead of this dependency."); 3980 $line->log_warning("Please use USE_TOOLS+=perl:run instead of this dependency.");
3974 3981
3975 } elsif ($pkg eq "gmake") { 3982 } elsif ($pkg eq "gmake") {
3976 $line->log_warning("Please use USE_TOOLS+=gmake instead of this dependency."); 3983 $line->log_warning("Please use USE_TOOLS+=gmake instead of this dependency.");
3977 3984
3978 } 3985 }
3979 3986
3980 if ($pattern =~ regex_dependency_gt) { 3987 if ($pattern =~ regex_dependency_gt) {
3981# ($abi_pkg, $abi_version) = ($1, $2); 3988# ($abi_pkg, $abi_version) = ($1, $2);
3982 } elsif ($pattern =~ regex_dependency_wildcard) { 3989 } elsif ($pattern =~ regex_dependency_wildcard) {
3983# ($abi_pkg) = ($1); 3990# ($abi_pkg) = ($1);
3984 } else { 3991 } else {
3985 $line->log_warning("Unknown dependency pattern \"${pattern}\"."); 3992 $line->log_warning("Unknown dependency pattern \"${pattern}\".");
3986 } 3993 }
3987 3994
3988 } elsif ($value =~ m":\.\./[^/]+$") { 3995 } elsif ($value =~ m":\.\./[^/]+$") {
3989 $line->log_warning("Dependencies should have the form \"../../category/package\"."); 3996 $line->log_warning("Dependencies should have the form \"../../category/package\".");
3990 $line->explain_warning(expl_relative_dirs); 3997 $line->explain_warning(expl_relative_dirs);
3991 3998
3992 } else { 3999 } else {
3993 $line->log_warning("Unknown dependency format."); 4000 $line->log_warning("Unknown dependency format.");
3994 $line->explain_warning( 4001 $line->explain_warning(
3995"Examples for valid dependencies are:", 4002"Examples for valid dependencies are:",
3996" package-[0-9]*:../../category/package", 4003" package-[0-9]*:../../category/package",
3997" package>=3.41:../../category/package", 4004" package>=3.41:../../category/package",
3998" package-2.718:../../category/package"); 4005" package-2.718:../../category/package");
3999 } 4006 }
4000 }, 4007 },
4001 4008
4002 DistSuffix => sub { 4009 DistSuffix => sub {
4003 if ($value eq ".tar.gz") { 4010 if ($value eq ".tar.gz") {
4004 $line->log_note("${varname} is \".tar.gz\" by default, so this definition may be redundant."); 4011 $line->log_note("${varname} is \".tar.gz\" by default, so this definition may be redundant.");
4005 } 4012 }
4006 }, 4013 },
4007 4014
4008 EmulPlatform => sub { 4015 EmulPlatform => sub {
4009 if ($value =~ m"^(\w+)-(\w+)$") { 4016 if ($value =~ m"^(\w+)-(\w+)$") {
4010 my ($opsys, $arch) = ($1, $2); 4017 my ($opsys, $arch) = ($1, $2);
4011 4018
4012 if ($opsys !~ m"^(?:bsdos|cygwin|darwin|dragonfly|freebsd|haiku|hpux|interix|irix|linux|netbsd|openbsd|osf1|sunos)$") { 4019 if ($opsys !~ m"^(?:bsdos|cygwin|darwin|dragonfly|freebsd|haiku|hpux|interix|irix|linux|netbsd|openbsd|osf1|sunos)$") {
4013 $line->log_warning("Unknown operating system: ${opsys}"); 4020 $line->log_warning("Unknown operating system: ${opsys}");
4014 } 4021 }
4015 # no check for $os_version 4022 # no check for $os_version
4016 if ($arch !~ m"^(?:i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$") { 4023 if ($arch !~ m"^(?:i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$") {
4017 $line->log_warning("Unknown hardware architecture: ${arch}"); 4024 $line->log_warning("Unknown hardware architecture: ${arch}");
4018 } 4025 }
4019 4026
4020 } else { 4027 } else {
4021 $line->log_warning("\"${value}\" is not a valid emulation platform."); 4028 $line->log_warning("\"${value}\" is not a valid emulation platform.");
4022 $line->explain_warning( 4029 $line->explain_warning(
4023"An emulation platform has the form <OPSYS>-<MACHINE_ARCH>.", 4030"An emulation platform has the form <OPSYS>-<MACHINE_ARCH>.",
4024"OPSYS is the lower-case name of the operating system, and MACHINE_ARCH", 4031"OPSYS is the lower-case name of the operating system, and MACHINE_ARCH",
4025"is the hardware architecture.", 4032"is the hardware architecture.",
4026"", 4033"",
4027"Examples: linux-i386, irix-mipsel."); 4034"Examples: linux-i386, irix-mipsel.");
4028 } 4035 }
4029 }, 4036 },
4030 4037
4031 4038
4032 4039
4033 Filename => sub { 4040 Filename => sub {
4034 if ($value_novar =~ m"/") { 4041 if ($value_novar =~ m"/") {
4035 $line->log_warning("A filename should not contain a slash."); 4042 $line->log_warning("A filename should not contain a slash.");
4036 4043
4037 } elsif ($value_novar !~ m"^[-0-9\@A-Za-z.,_~+%]*$") { 4044 } elsif ($value_novar !~ m"^[-0-9\@A-Za-z.,_~+%]*$") {
4038 $line->log_warning("\"${value}\" is not a valid filename."); 4045 $line->log_warning("\"${value}\" is not a valid filename.");
4039 } 4046 }
4040 }, 4047 },
4041 4048
4042 Filemask => sub { 4049 Filemask => sub {
4043 if ($value_novar !~ m"^[-0-9A-Za-z._~+%*?]*$") { 4050 if ($value_novar !~ m"^[-0-9A-Za-z._~+%*?]*$") {
4044 $line->log_warning("\"${value}\" is not a valid filename mask."); 4051 $line->log_warning("\"${value}\" is not a valid filename mask.");
4045 } 4052 }
4046 }, 4053 },
4047 4054
4048 FileMode => sub { 4055 FileMode => sub {
4049 if ($value ne "" && $value_novar eq "") { 4056 if ($value ne "" && $value_novar eq "") {
4050 # Fine. 4057 # Fine.
4051 } elsif ($value =~ m"^[0-7]{3,4}") { 4058 } elsif ($value =~ m"^[0-7]{3,4}") {
4052 # Fine. 4059 # Fine.
4053 } else { 4060 } else {
4054 $line->log_warning("Invalid file mode ${value}."); 4061 $line->log_warning("Invalid file mode ${value}.");
4055 } 4062 }
4056 }, 4063 },
4057 4064
4058 Identifier => sub { 4065 Identifier => sub {
4059 if ($value ne $value_novar) { 4066 if ($value ne $value_novar) {
4060 #$line->log_warning("Identifiers should be given directly."); 4067 #$line->log_warning("Identifiers should be given directly.");
4061 } 4068 }
4062 if ($value_novar =~ m"^[+\-.0-9A-Z_a-z]+$") { 4069 if ($value_novar =~ m"^[+\-.0-9A-Z_a-z]+$") {
4063 # Fine. 4070 # Fine.
4064 } elsif ($value ne "" && $value_novar eq "") { 4071 } elsif ($value ne "" && $value_novar eq "") {
4065 # Don't warn here. 4072 # Don't warn here.
4066 } else { 4073 } else {
4067 $line->log_warning("Invalid identifier \"${value}\"."); 4074 $line->log_warning("Invalid identifier \"${value}\".");
4068 } 4075 }
4069 }, 4076 },
4070 4077
4071 Integer => sub { 4078 Integer => sub {
4072 if ($value !~ m"^\d+$") { 4079 if ($value !~ m"^\d+$") {
4073 $line->log_warning("${varname} must be a valid integer."); 4080 $line->log_warning("${varname} must be a valid integer.");
4074 } 4081 }
4075 }, 4082 },
4076 4083
4077 LdFlag => sub { 4084 LdFlag => sub {
4078 if ($value =~ m"^-L(.*)") { 4085 if ($value =~ m"^-L(.*)") {
4079 my ($dirname) = ($1); 4086 my ($dirname) = ($1);
4080 4087
4081 $opt_debug_unchecked and $line->log_debug("Unchecked directory ${dirname} in ${varname}."); 4088 $opt_debug_unchecked and $line->log_debug("Unchecked directory ${dirname} in ${varname}.");
4082 4089
4083 } elsif ($value =~ m"^-l(.*)") { 4090 } elsif ($value =~ m"^-l(.*)") {
4084 my ($libname) = ($1); 4091 my ($libname) = ($1);
4085 4092
4086 $opt_debug_unchecked and $line->log_debug("Unchecked library name ${libname} in ${varname}."); 4093 $opt_debug_unchecked and $line->log_debug("Unchecked library name ${libname} in ${varname}.");
4087 4094
4088 } elsif ($value =~ m"^(?:-static)$") { 4095 } elsif ($value =~ m"^(?:-static)$") {
4089 # Assume that the wrapper framework catches these. 4096 # Assume that the wrapper framework catches these.
4090 4097
4091 } elsif ($value =~ m"^(-Wl,(?:-R|-rpath|--rpath))") { 4098 } elsif ($value =~ m"^(-Wl,(?:-R|-rpath|--rpath))") {
4092 my ($rpath_flag) = ($1); 4099 my ($rpath_flag) = ($1);
4093 $line->log_warning("Please use \${COMPILER_RPATH_FLAG} instead of ${rpath_flag}."); 4100 $line->log_warning("Please use \${COMPILER_RPATH_FLAG} instead of ${rpath_flag}.");
4094 4101
4095 } elsif ($value =~ m"^-.*") { 4102 } elsif ($value =~ m"^-.*") {
4096 $line->log_warning("Unknown linker flag \"${value}\"."); 4103 $line->log_warning("Unknown linker flag \"${value}\".");
4097 4104
4098 } elsif ($value =~ regex_unresolved) { 4105 } elsif ($value =~ regex_unresolved) {
4099 $opt_debug_unchecked and $line->log_debug("Unchecked LDFLAG: ${value}"); 4106 $opt_debug_unchecked and $line->log_debug("Unchecked LDFLAG: ${value}");
4100 4107
4101 } else { 4108 } else {
4102 $line->log_warning("Linker flag \"${value}\" does not start with a dash."); 4109 $line->log_warning("Linker flag \"${value}\" does not start with a dash.");
4103 } 4110 }
4104 }, 4111 },
4105 4112
4106 License => sub { 4113 License => sub {
4107 4114
4108 use constant deprecated_licenses => array_to_hash(qw( 4115 use constant deprecated_licenses => array_to_hash(qw(
4109 fee-based-commercial-use 4116 fee-based-commercial-use
4110 no-commercial-use no-profit no-redistribution 4117 no-commercial-use no-profit no-redistribution
4111 shareware 4118 shareware
4112 )); 4119 ));
4113 4120
4114 my $licenses = parse_licenses($value); 4121 my $licenses = parse_licenses($value);
4115 foreach my $license (@$licenses) { 4122 foreach my $license (@$licenses) {
4116 my $license_file = "${cwd_pkgsrcdir}/licenses/${license}"; 4123 my $license_file = "${cwd_pkgsrcdir}/licenses/${license}";
4117 if (defined($pkgctx_vardef) && exists($pkgctx_vardef->{"LICENSE_FILE"})) { 4124 if (defined($pkgctx_vardef) && exists($pkgctx_vardef->{"LICENSE_FILE"})) {
4118 my $license_file_line = $pkgctx_vardef->{"LICENSE_FILE"}; 4125 my $license_file_line = $pkgctx_vardef->{"LICENSE_FILE"};
4119 4126
4120 $license_file = "${current_dir}/" . resolve_relative_path($license_file_line->get("value"), false); 4127 $license_file = "${current_dir}/" . resolve_relative_path($license_file_line->get("value"), false);
4121 } 4128 }
4122 if (!-f $license_file) { 4129 if (!-f $license_file) {
4123 $line->log_warning("License file ".normalize_pathname($license_file)." does not exist."); 4130 $line->log_warning("License file ".normalize_pathname($license_file)." does not exist.");
4124 } 4131 }
4125 4132
4126 if (exists(deprecated_licenses->{$license})) { 4133 if (exists(deprecated_licenses->{$license})) {
4127 $line->log_warning("License ${license} is deprecated."); 4134 $line->log_warning("License ${license} is deprecated.");
4128 } 4135 }
4129 } 4136 }
4130 }, 4137 },
4131 4138
4132 Mail_Address => sub { 4139 Mail_Address => sub {
4133 if ($value =~ m"^([+\-.0-9A-Z_a-z]+)\@([-\w\d.]+)$") { 4140 if ($value =~ m"^([+\-.0-9A-Z_a-z]+)\@([-\w\d.]+)$") {
4134 my ($localpart, $domain) = ($1, $2); 4141 my ($localpart, $domain) = ($1, $2);
4135 if ($domain =~ m"^NetBSD.org"i && $domain ne "NetBSD.org") { 4142 if ($domain =~ m"^NetBSD.org"i && $domain ne "NetBSD.org") {
4136 $line->log_warning("Please write NetBSD.org instead of ${domain}."); 4143 $line->log_warning("Please write NetBSD.org instead of ${domain}.");
4137 } 4144 }
4138 if ("${localpart}\@${domain}" =~ m"^(tech-pkg|packages)\@NetBSD\.org$"i) { 4145 if ("${localpart}\@${domain}" =~ m"^(tech-pkg|packages)\@NetBSD\.org$"i) {
4139 $line->log_warning("${localpart}\@${domain} is deprecated. Use pkgsrc-users\@NetBSD.org instead."); 4146 $line->log_warning("${localpart}\@${domain} is deprecated. Use pkgsrc-users\@NetBSD.org instead.");
4140 } 4147 }
4141 4148
4142 } else { 4149 } else {
4143 $line->log_warning("\"${value}\" is not a valid mail address."); 4150 $line->log_warning("\"${value}\" is not a valid mail address.");
4144 } 4151 }
4145 }, 4152 },
4146 4153
4147 Message => sub { 4154 Message => sub {
4148 if ($value =~ m"^[\"'].*[\"']$") { 4155 if ($value =~ m"^[\"'].*[\"']$") {
4149 $line->log_warning("${varname} should not be quoted."); 4156 $line->log_warning("${varname} should not be quoted.");
4150 $line->explain_warning( 4157 $line->explain_warning(
4151"The quoting is only needed for variables which are interpreted as", 4158"The quoting is only needed for variables which are interpreted as",
4152"multiple words (or, generally speaking, a list of something). A single", 4159"multiple words (or, generally speaking, a list of something). A single",
4153"text message does not belong to this class, since it is only printed", 4160"text message does not belong to this class, since it is only printed",
4154"as a whole.", 4161"as a whole.",
4155"", 4162"",
4156"On the other hand, PKG_FAIL_REASON is a _list_ of text messages, so in", 4163"On the other hand, PKG_FAIL_REASON is a _list_ of text messages, so in",
4157"that case, the quoting has to be done."); 4164"that case, the quoting has to be done.");
4158 } 4165 }
4159 }, 4166 },
4160 4167
4161 Option => sub { 4168 Option => sub {
4162 if ($value ne $value_novar) { 4169 if ($value ne $value_novar) {
4163 $opt_debug_unchecked and $line->log_debug("Unchecked option name \"${value}\"."); 4170 $opt_debug_unchecked and $line->log_debug("Unchecked option name \"${value}\".");
4164 4171
4165 } elsif ($value_novar =~ m"^-?([a-z][-0-9a-z\+]*)$") { 4172 } elsif ($value_novar =~ m"^-?([a-z][-0-9a-z\+]*)$") {
4166 my ($optname) = ($1); 4173 my ($optname) = ($1);
4167 4174
4168 if (!exists(get_pkg_options()->{$optname})) { 4175 if (!exists(get_pkg_options()->{$optname})) {
4169 $line->log_warning("Unknown option \"${value}\"."); 4176 $line->log_warning("Unknown option \"${value}\".");
4170 $line->explain_warning( 4177 $line->explain_warning(
4171"This option is not documented in the mk/defaults/options.description", 4178"This option is not documented in the mk/defaults/options.description",
4172"file. If this is not a typo, please think of a brief but precise", 4179"file. If this is not a typo, please think of a brief but precise",
4173"description and either update that file yourself or ask on the", 4180"description and either update that file yourself or ask on the",
4174"tech-pkg\@NetBSD.org mailing list."); 4181"tech-pkg\@NetBSD.org mailing list.");
4175 } 4182 }
4176 4183
4177 } elsif ($value_novar =~ m"^-?([a-z][-0-9a-z_\+]*)$") { 4184 } elsif ($value_novar =~ m"^-?([a-z][-0-9a-z_\+]*)$") {
4178 my ($optname) = ($1); 4185 my ($optname) = ($1);
4179 4186
4180 $line->log_warning("Use of the underscore character in option names is deprecated."); 4187 $line->log_warning("Use of the underscore character in option names is deprecated.");
4181 4188
4182 } else { 4189 } else {
4183 $line->log_error("\"${value}\" is not a valid option name."); 4190 $line->log_error("\"${value}\" is not a valid option name.");
4184 } 4191 }
4185 }, 4192 },
4186 4193
4187 Pathlist => sub { 4194 Pathlist => sub {
4188 4195
4189 if ($value !~ m":" && $is_guessed) { 4196 if ($value !~ m":" && $is_guessed) {
4190 checkline_mk_vartype_basic($line, $varname, "Pathname", $op, $value, $comment, $list_context, $is_guessed); 4197 checkline_mk_vartype_basic($line, $varname, "Pathname", $op, $value, $comment, $list_context, $is_guessed);
4191 4198
4192 } else { 4199 } else {
4193 4200
4194 # XXX: The splitting will fail if $value contains any 4201 # XXX: The splitting will fail if $value contains any
4195 # variables with modifiers, for example :Q or :S/././. 4202 # variables with modifiers, for example :Q or :S/././.
4196 foreach my $p (split(qr":", $value)) { 4203 foreach my $p (split(qr":", $value)) {
4197 my $p_novar = remove_variables($p); 4204 my $p_novar = remove_variables($p);
4198 4205
4199 if ($p_novar !~ m"^[-0-9A-Za-z._~+%/]*$") { 4206 if ($p_novar !~ m"^[-0-9A-Za-z._~+%/]*$") {
4200 $line->log_warning("\"${p}\" is not a valid pathname."); 4207 $line->log_warning("\"${p}\" is not a valid pathname.");
4201 } 4208 }
4202 4209
4203 if ($p !~ m"^[\$/]") { 4210 if ($p !~ m"^[\$/]") {
4204 $line->log_warning("All components of ${varname} (in this case \"${p}\") should be an absolute path."); 4211 $line->log_warning("All components of ${varname} (in this case \"${p}\") should be an absolute path.");
4205 } 4212 }
4206 } 4213 }
4207 } 4214 }
4208 }, 4215 },
4209 4216
4210 Pathmask => sub { 4217 Pathmask => sub {
4211 if ($value_novar !~ m"^[#\-0-9A-Za-z._~+%*?/\[\]]*$") { 4218 if ($value_novar !~ m"^[#\-0-9A-Za-z._~+%*?/\[\]]*$") {
4212 $line->log_warning("\"${value}\" is not a valid pathname mask."); 4219 $line->log_warning("\"${value}\" is not a valid pathname mask.");
4213 } 4220 }
4214 checkline_mk_absolute_pathname($line, $value); 4221 checkline_mk_absolute_pathname($line, $value);
4215 }, 4222 },
4216 4223
4217 Pathname => sub { 4224 Pathname => sub {
4218 if ($value_novar !~ m"^[#\-0-9A-Za-z._~+%/]*$") { 4225 if ($value_novar !~ m"^[#\-0-9A-Za-z._~+%/]*$") {
4219 $line->log_warning("\"${value}\" is not a valid pathname."); 4226 $line->log_warning("\"${value}\" is not a valid pathname.");
4220 } 4227 }
4221 checkline_mk_absolute_pathname($line, $value); 4228 checkline_mk_absolute_pathname($line, $value);
4222 }, 4229 },
4223 4230
4224 Perl5Packlist => sub { 4231 Perl5Packlist => sub {
4225 if ($value ne $value_novar) { 4232 if ($value ne $value_novar) {
4226 $line->log_warning("${varname} should not depend on other variables."); 4233 $line->log_warning("${varname} should not depend on other variables.");
4227 } 4234 }
4228 }, 4235 },
4229 4236
4230 PkgName => sub { 4237 PkgName => sub {
4231 if ($value eq $value_novar && $value !~ regex_pkgname) { 4238 if ($value eq $value_novar && $value !~ regex_pkgname) {
4232 $line->log_warning("\"${value}\" is not a valid package name. A valid package name has the form packagename-version, where version consists only of digits, letters and dots."); 4239 $line->log_warning("\"${value}\" is not a valid package name. A valid package name has the form packagename-version, where version consists only of digits, letters and dots.");
4233 } 4240 }
4234 }, 4241 },
4235 4242
4236 PkgPath => sub { 4243 PkgPath => sub {
4237 checkline_relative_pkgdir($line, "$cur_pkgsrcdir/$value"); 4244 checkline_relative_pkgdir($line, "$cur_pkgsrcdir/$value");
4238 }, 4245 },
4239 4246
4240 PkgOptionsVar => sub { 4247 PkgOptionsVar => sub {
4241 checkline_mk_vartype_basic($line, $varname, "Varname", $op, $value, $comment, false, $is_guessed); 4248 checkline_mk_vartype_basic($line, $varname, "Varname", $op, $value, $comment, false, $is_guessed);
4242 if ($value =~ m"\$\{PKGBASE[:\}]") { 4249 if ($value =~ m"\$\{PKGBASE[:\}]") {
4243 $line->log_error("PKGBASE must not be used in PKG_OPTIONS_VAR."); 4250 $line->log_error("PKGBASE must not be used in PKG_OPTIONS_VAR.");
4244 $line->explain_error( 4251 $line->explain_error(
4245"PKGBASE is defined in bsd.pkg.mk, which is included as the", 4252"PKGBASE is defined in bsd.pkg.mk, which is included as the",
4246"very last file, but PKG_OPTIONS_VAR is evaluated earlier.", 4253"very last file, but PKG_OPTIONS_VAR is evaluated earlier.",
4247"Use \${PKGNAME:C/-[0-9].*//} instead."); 4254"Use \${PKGNAME:C/-[0-9].*//} instead.");
4248 } 4255 }
4249 }, 4256 },
4250 4257
4251 PkgRevision => sub { 4258 PkgRevision => sub {
4252 if ($value !~ m"^[1-9]\d*$") { 4259 if ($value !~ m"^[1-9]\d*$") {
4253 $line->log_warning("${varname} must be a positive integer number."); 4260 $line->log_warning("${varname} must be a positive integer number.");
4254 } 4261 }
4255 if ($line->fname !~ m"(?:^|/)Makefile$") { 4262 if ($line->fname !~ m"(?:^|/)Makefile$") {
4256 $line->log_error("${varname} only makes sense directly in the package Makefile."); 4263 $line->log_error("${varname} only makes sense directly in the package Makefile.");
4257 $line->explain_error( 4264 $line->explain_error(
4258"Usually, different packages using the same Makefile.common have", 4265"Usually, different packages using the same Makefile.common have",
4259"different dependencies and will be bumped at different times (e.g. for", 4266"different dependencies and will be bumped at different times (e.g. for",
4260"shlib major bumps) and thus the PKGREVISIONs must be in the separate", 4267"shlib major bumps) and thus the PKGREVISIONs must be in the separate",
4261"Makefiles. There is no practical way of having this information in a", 4268"Makefiles. There is no practical way of having this information in a",
4262"commonly used Makefile."); 4269"commonly used Makefile.");
4263 } 4270 }
4264 }, 4271 },
4265 4272
4266 PlatformTriple => sub { 4273 PlatformTriple => sub {
4267 my $part = qr"(?:\[[^\]]+\]|[^-\[])+"; 4274 my $part = qr"(?:\[[^\]]+\]|[^-\[])+";
4268 if ($value =~ m"^(${part})-(${part})-(${part})$") { 4275 if ($value =~ m"^(${part})-(${part})-(${part})$") {
4269 my ($opsys, $os_version, $arch) = ($1, $2, $3); 4276 my ($opsys, $os_version, $arch) = ($1, $2, $3);
4270 4277
4271 if ($opsys !~ m"^(?:\*|BSDOS|Cygwin|Darwin|DragonFly|FreeBSD|Haiku|HPUX|Interix|IRIX|Linux|NetBSD|OpenBSD|OSF1|SunOS)$") { 4278 if ($opsys !~ m"^(?:\*|BSDOS|Cygwin|Darwin|DragonFly|FreeBSD|Haiku|HPUX|Interix|IRIX|Linux|NetBSD|OpenBSD|OSF1|SunOS)$") {
4272 $line->log_warning("Unknown operating system: ${opsys}"); 4279 $line->log_warning("Unknown operating system: ${opsys}");
4273 } 4280 }
4274 # no check for $os_version 4281 # no check for $os_version
4275 if ($arch !~ m"^(?:\*|i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$") { 4282 if ($arch !~ m"^(?:\*|i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$") {
4276 $line->log_warning("Unknown hardware architecture: ${arch}"); 4283 $line->log_warning("Unknown hardware architecture: ${arch}");
4277 } 4284 }
4278 4285
4279 } else { 4286 } else {
4280 $line->log_warning("\"${value}\" is not a valid platform triple."); 4287 $line->log_warning("\"${value}\" is not a valid platform triple.");
4281 $line->explain_warning( 4288 $line->explain_warning(
4282"A platform triple has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.", 4289"A platform triple has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.",
4283"Each of these components may be a shell globbing expression.", 4290"Each of these components may be a shell globbing expression.",
4284"Examples: NetBSD-*-i386, *-*-*, Linux-*-*."); 4291"Examples: NetBSD-*-i386, *-*-*, Linux-*-*.");
4285 } 4292 }
4286 }, 4293 },
4287 4294
4288 PrefixPathname => sub { 4295 PrefixPathname => sub {
4289 if ($value =~ m"^man/(.*)") { 4296 if ($value =~ m"^man/(.*)") {
4290 my ($mansubdir) = ($1); 4297 my ($mansubdir) = ($1);
4291 4298
4292 $line->log_warning("Please use \"\${PKGMANDIR}/${mansubdir}\" instead of \"${value}\"."); 4299 $line->log_warning("Please use \"\${PKGMANDIR}/${mansubdir}\" instead of \"${value}\".");
4293 } 4300 }
4294 }, 4301 },
4295 4302
4296 RelativePkgDir => sub { 4303 RelativePkgDir => sub {
4297 checkline_relative_pkgdir($line, $value); 4304 checkline_relative_pkgdir($line, $value);
4298 }, 4305 },
4299 4306
4300 RelativePkgPath => sub { 4307 RelativePkgPath => sub {
4301 checkline_relative_path($line, $value, true); 4308 checkline_relative_path($line, $value, true);
4302 }, 4309 },
4303 4310
4304 Restricted => sub { 4311 Restricted => sub {
4305 if ($value ne "\${RESTRICTED}") { 4312 if ($value ne "\${RESTRICTED}") {
4306 $line->log_warning("The only valid value for ${varname} is \${RESTRICTED}."); 4313 $line->log_warning("The only valid value for ${varname} is \${RESTRICTED}.");
4307 $line->explain_warning( 4314 $line->explain_warning(
4308"These variables are used to control which files may be mirrored on FTP", 4315"These variables are used to control which files may be mirrored on FTP",
4309"servers or CD-ROM collections. They are not intended to mark packages", 4316"servers or CD-ROM collections. They are not intended to mark packages",
4310"whose only MASTER_SITES are on ftp.NetBSD.org."); 4317"whose only MASTER_SITES are on ftp.NetBSD.org.");
4311 } 4318 }
4312 }, 4319 },
4313 4320
4314 SVR4PkgName => sub { 4321 SVR4PkgName => sub {
4315 if ($value =~ regex_unresolved) { 4322 if ($value =~ regex_unresolved) {
4316 $line->log_error("SVR4_PKGNAME must not contain references to other variables."); 4323 $line->log_error("SVR4_PKGNAME must not contain references to other variables.");
4317 } elsif (length($value) > 5) { 4324 } elsif (length($value) > 5) {
4318 $line->log_error("SVR4_PKGNAME must not be longer than 5 characters."); 4325 $line->log_error("SVR4_PKGNAME must not be longer than 5 characters.");
4319 } 4326 }
4320 }, 4327 },
4321 4328
4322 SedCommand => sub { 4329 SedCommand => sub {
4323 }, 4330 },
4324 4331
4325 SedCommands => sub { 4332 SedCommands => sub {
4326 my $words = shell_split($value); 4333 my $words = shell_split($value);
4327 if (!$words) { 4334 if (!$words) {
4328 $line->log_error("Invalid shell words in sed commands."); 4335 $line->log_error("Invalid shell words in sed commands.");
4329 $line->explain_error( 4336 $line->explain_error(
4330"If your sed commands have embedded \"#\" characters, you need to escape", 4337"If your sed commands have embedded \"#\" characters, you need to escape",
4331"them with a backslash, otherwise make(1) will interpret them as a", 4338"them with a backslash, otherwise make(1) will interpret them as a",
4332"comment, no matter if they occur in single or double quotes or", 4339"comment, no matter if they occur in single or double quotes or",
4333"whatever."); 4340"whatever.");
4334 4341
4335 } else { 4342 } else {
4336 my $nwords = scalar(@{$words}); 4343 my $nwords = scalar(@{$words});
4337 my $ncommands = 0; 4344 my $ncommands = 0;
4338 4345
4339 for (my $i = 0; $i < $nwords; $i++) { 4346 for (my $i = 0; $i < $nwords; $i++) {
4340 my $word = $words->[$i]; 4347 my $word = $words->[$i];
4341 checkline_mk_shellword($line, $word, true); 4348 checkline_mk_shellword($line, $word, true);
4342 4349
4343 if ($word eq "-e") { 4350 if ($word eq "-e") {
4344 if ($i + 1 < $nwords) { 4351 if ($i + 1 < $nwords) {
4345 # Check the real sed command here. 4352 # Check the real sed command here.
4346 $i++; 4353 $i++;
4347 $ncommands++; 4354 $ncommands++;
4348 if ($ncommands > 1) { 4355 if ($ncommands > 1) {
4349 $line->log_warning("Each sed command should appear in an assignment of its own."); 4356 $line->log_warning("Each sed command should appear in an assignment of its own.");
4350 $line->explain_warning( 4357 $line->explain_warning(
4351"For example, instead of", 4358"For example, instead of",
4352" SUBST_SED.foo+= -e s,command1,, -e s,command2,,", 4359" SUBST_SED.foo+= -e s,command1,, -e s,command2,,",
4353"use", 4360"use",
4354" SUBST_SED.foo+= -e s,command1,,", 4361" SUBST_SED.foo+= -e s,command1,,",
4355" SUBST_SED.foo+= -e s,command2,,", 4362" SUBST_SED.foo+= -e s,command2,,",
4356"", 4363"",
4357"This way, short sed commands cannot be hidden at the end of a line."); 4364"This way, short sed commands cannot be hidden at the end of a line.");
4358 } 4365 }
4359 checkline_mk_shellword($line, $words->[$i - 1], true); 4366 checkline_mk_shellword($line, $words->[$i - 1], true);
4360 checkline_mk_shellword($line, $words->[$i], true); 4367 checkline_mk_shellword($line, $words->[$i], true);
4361 checkline_mk_vartype_basic($line, $varname, "SedCommand", $op, $words->[$i], $comment, $list_context, $is_guessed); 4368 checkline_mk_vartype_basic($line, $varname, "SedCommand", $op, $words->[$i], $comment, $list_context, $is_guessed);
4362 } else { 4369 } else {
4363 $line->log_error("The -e option to sed requires an argument."); 4370 $line->log_error("The -e option to sed requires an argument.");
4364 } 4371 }
4365 } elsif ($word eq "-E") { 4372 } elsif ($word eq "-E") {
4366 # Switch to extended regular expressions mode. 4373 # Switch to extended regular expressions mode.
4367 4374
4368 } elsif ($word eq "-n") { 4375 } elsif ($word eq "-n") {
4369 # Don't print lines per default. 4376 # Don't print lines per default.
4370 4377
4371 } elsif ($i == 0 && $word =~ m"^([\"']?)(?:\d*|/.*/)s(.).*\2g?\1$") { 4378 } elsif ($i == 0 && $word =~ m"^([\"']?)(?:\d*|/.*/)s(.).*\2g?\1$") {
4372 $line->log_warning("Please always use \"-e\" in sed commands, even if there is only one substitution."); 4379 $line->log_warning("Please always use \"-e\" in sed commands, even if there is only one substitution.");
4373 4380
4374 } else { 4381 } else {
4375 $line->log_warning("Unknown sed command ${word}."); 4382 $line->log_warning("Unknown sed command ${word}.");
4376 } 4383 }
4377 } 4384 }
4378 } 4385 }
4379 }, 4386 },
4380 4387
4381 ShellCommand => sub { 4388 ShellCommand => sub {
4382 checkline_mk_shelltext($line, $value); 4389 checkline_mk_shelltext($line, $value);
4383 }, 4390 },
4384 4391
4385 ShellWord => sub { 4392 ShellWord => sub {
4386 if (!$list_context) { 4393 if (!$list_context) {
4387 checkline_mk_shellword($line, $value, true); 4394 checkline_mk_shellword($line, $value, true);
4388 } 4395 }
4389 }, 4396 },
4390 4397
4391 Stage => sub { 4398 Stage => sub {
4392 if ($value !~ m"^(?:pre|do|post)-(?:extract|patch|configure|build|install)$") { 4399 if ($value !~ m"^(?:pre|do|post)-(?:extract|patch|configure|build|install)$") {
4393 $line->log_warning("Invalid stage name. Use one of {pre,do,post}-{extract,patch,configure,build,install}."); 4400 $line->log_warning("Invalid stage name. Use one of {pre,do,post}-{extract,patch,configure,build,install}.");
4394 } 4401 }
4395 }, 4402 },
4396 4403
4397 String => sub { 4404 String => sub {
4398 # No further checks possible. 4405 # No further checks possible.
4399 }, 4406 },
4400 4407
4401 Tool => sub { 4408 Tool => sub {
4402 if ($value =~ m"^([-\w]+|\[)(?::(\w+))?$") { 4409 if ($varname eq "TOOLS_NOOP" && $op eq "+=") {
 4410 # no warning for package-defined tool definitions
 4411
 4412 } elsif ($value =~ m"^([-\w]+|\[)(?::(\w+))?$") {
4403 my ($toolname, $tooldep) = ($1, $2); 4413 my ($toolname, $tooldep) = ($1, $2);
4404 if (!exists(get_tool_names()->{$toolname})) { 4414 if (!exists(get_tool_names()->{$toolname})) {
4405 $line->log_error("Unknown tool \"${toolname}\"."); 4415 $line->log_error("Unknown tool \"${toolname}\".");
4406 } 4416 }
4407 if (defined($tooldep) && $tooldep !~ m"^(?:bootstrap|build|pkgsrc|run)$") { 4417 if (defined($tooldep) && $tooldep !~ m"^(?:bootstrap|build|pkgsrc|run)$") {
4408 $line->log_error("Unknown tool dependency \"${tooldep}\". Use one of \"build\", \"pkgsrc\" or \"run\"."); 4418 $line->log_error("Unknown tool dependency \"${tooldep}\". Use one of \"build\", \"pkgsrc\" or \"run\".");
4409 } 4419 }
4410 } else { 4420 } else {
4411 $line->log_error("Invalid tool syntax: \"${value}\"."); 4421 $line->log_error("Invalid tool syntax: \"${value}\".");
4412 } 4422 }
4413 }, 4423 },
4414 4424
4415 Unchecked => sub { 4425 Unchecked => sub {
4416 # Do nothing, as the name says. 4426 # Do nothing, as the name says.
4417 }, 4427 },
4418 4428
4419 URL => sub { 4429 URL => sub {
4420 if ($value eq "" && defined($comment) && $comment =~ m"^#") { 4430 if ($value eq "" && defined($comment) && $comment =~ m"^#") {
4421 # Ok 4431 # Ok
4422 4432
4423 } elsif ($value =~ m"\$\{(MASTER_SITE_[^:]*).*:=(.*)\}$") { 4433 } elsif ($value =~ m"\$\{(MASTER_SITE_[^:]*).*:=(.*)\}$") {
4424 my ($name, $subdir) = ($1, $2); 4434 my ($name, $subdir) = ($1, $2);
4425 4435
4426 if (!exists(get_dist_sites_names()->{$name})) { 4436 if (!exists(get_dist_sites_names()->{$name})) {
4427 $line->log_error("${name} does not exist."); 4437 $line->log_error("${name} does not exist.");
4428 } 4438 }
4429 if ($subdir !~ m"/$") { 4439 if ($subdir !~ m"/$") {
4430 $line->log_error("The subdirectory in ${name} must end with a slash."); 4440 $line->log_error("The subdirectory in ${name} must end with a slash.");
4431 } 4441 }
4432 4442
4433 } elsif ($value =~ regex_unresolved) { 4443 } elsif ($value =~ regex_unresolved) {
4434 # No further checks 4444 # No further checks
4435 4445
4436 } elsif ($value =~ m"^(https?|ftp|gopher)://([-0-9A-Za-z.]+)(?::(\d+))?/([-%&+,./0-9:=?\@A-Z_a-z~]|#)*$") { 4446 } elsif ($value =~ m"^(https?|ftp|gopher)://([-0-9A-Za-z.]+)(?::(\d+))?/([-%&+,./0-9:=?\@A-Z_a-z~]|#)*$") {
4437 my ($proto, $host, $port, $path) = ($1, $2, $3, $4); 4447 my ($proto, $host, $port, $path) = ($1, $2, $3, $4);
4438 my $sites = get_dist_sites(); 4448 my $sites = get_dist_sites();
4439 4449
4440 if ($host =~ m"\.NetBSD\.org$"i && $host !~ m"\.NetBSD\.org$") { 4450 if ($host =~ m"\.NetBSD\.org$"i && $host !~ m"\.NetBSD\.org$") {
4441 $line->log_warning("Please write NetBSD.org instead of ${host}."); 4451 $line->log_warning("Please write NetBSD.org instead of ${host}.");
4442 } 4452 }
4443 4453
4444 foreach my $site (keys(%{$sites})) { 4454 foreach my $site (keys(%{$sites})) {
4445 if (index($value, $site) == 0) { 4455 if (index($value, $site) == 0) {
4446 my $subdir = substr($value, length($site)); 4456 my $subdir = substr($value, length($site));
4447 $line->log_warning(sprintf("Please use \${%s:=%s} instead of \"%s\".", $sites->{$site}, $subdir, $value)); 4457 $line->log_warning(sprintf("Please use \${%s:=%s} instead of \"%s\".", $sites->{$site}, $subdir, $value));
4448 last; 4458 last;
4449 } 4459 }
4450 } 4460 }
4451 4461
4452 } elsif ($value =~ m"^([0-9A-Za-z]+)://([^/]+)(.*)$") { 4462 } elsif ($value =~ m"^([0-9A-Za-z]+)://([^/]+)(.*)$") {
4453 my ($scheme, $host, $abs_path) = ($1, $2, $3); 4463 my ($scheme, $host, $abs_path) = ($1, $2, $3);
4454 4464
4455 if ($scheme ne "ftp" && $scheme ne "http" && $scheme ne "gopher") { 4465 if ($scheme ne "ftp" && $scheme ne "http" && $scheme ne "gopher") {
4456 $line->log_warning("\"${value}\" is not a valid URL. Only http, ftp and gopher URLs are allowed here."); 4466 $line->log_warning("\"${value}\" is not a valid URL. Only http, ftp and gopher URLs are allowed here.");
4457 4467
4458 } elsif ($abs_path eq "") { 4468 } elsif ($abs_path eq "") {
4459 $line->log_note("For consistency, please add a trailing slash to \"${value}\"."); 4469 $line->log_note("For consistency, please add a trailing slash to \"${value}\".");
4460 4470
4461 } else { 4471 } else {
4462 $line->log_warning("\"${value}\" is not a valid URL."); 4472 $line->log_warning("\"${value}\" is not a valid URL.");
4463 } 4473 }
4464 4474
4465 } else { 4475 } else {
4466 $line->log_warning("\"${value}\" is not a valid URL."); 4476 $line->log_warning("\"${value}\" is not a valid URL.");
4467 } 4477 }
4468 }, 4478 },
4469 4479
4470 UserGroupName => sub { 4480 UserGroupName => sub {
4471 if ($value ne $value_novar) { 4481 if ($value ne $value_novar) {
4472 # No checks for now. 4482 # No checks for now.
4473 } elsif ($value !~ m"^[0-9_a-z]+$") { 4483 } elsif ($value !~ m"^[0-9_a-z]+$") {
4474 $line->log_warning("Invalid user or group name \"${value}\"."); 4484 $line->log_warning("Invalid user or group name \"${value}\".");
4475 } 4485 }
4476 }, 4486 },
4477 4487
4478 Varname => sub { 4488 Varname => sub {
4479 if ($value ne "" && $value_novar eq "") { 4489 if ($value ne "" && $value_novar eq "") {
4480 # The value of another variable 4490 # The value of another variable
4481 4491
4482 } elsif ($value_novar !~ m"^[A-Z_][0-9A-Z_]*(?:[.].*)?$") { 4492 } elsif ($value_novar !~ m"^[A-Z_][0-9A-Z_]*(?:[.].*)?$") {
4483 $line->log_warning("\"${value}\" is not a valid variable name."); 4493 $line->log_warning("\"${value}\" is not a valid variable name.");
4484 } 4494 }
4485 }, 4495 },
4486 4496
4487 Version => sub { 4497 Version => sub {
4488 if ($value !~ m"^([\d.])+$") { 4498 if ($value !~ m"^([\d.])+$") {
4489 $line->log_warning("Invalid version number \"${value}\"."); 4499 $line->log_warning("Invalid version number \"${value}\".");
4490 } 4500 }
4491 }, 4501 },
4492 4502
4493 WrapperReorder => sub { 4503 WrapperReorder => sub {
4494 if ($value =~ m"^reorder:l:([\w\-]+):([\w\-]+)$") { 4504 if ($value =~ m"^reorder:l:([\w\-]+):([\w\-]+)$") {
4495 my ($lib1, $lib2) = ($1, $2); 4505 my ($lib1, $lib2) = ($1, $2);
4496 # Fine. 4506 # Fine.
4497 } else { 4507 } else {
4498 $line->log_warning("Unknown wrapper reorder command \"${value}\"."); 4508 $line->log_warning("Unknown wrapper reorder command \"${value}\".");
4499 } 4509 }
4500 }, 4510 },
4501 4511
4502 WrapperTransform => sub { 4512 WrapperTransform => sub {
4503 if ($value =~ m"^rm:(?:-[DILOUWflm].*|-std=.*)$") { 4513 if ($value =~ m"^rm:(?:-[DILOUWflm].*|-std=.*)$") {
4504 # Fine. 4514 # Fine.
4505 4515
4506 } elsif ($value =~ m"^l:([^:]+):(.+)$") { 4516 } elsif ($value =~ m"^l:([^:]+):(.+)$") {
4507 my ($lib, $replacement_libs) = ($1, $2); 4517 my ($lib, $replacement_libs) = ($1, $2);
4508 # Fine. 4518 # Fine.
4509 4519
4510 } elsif ($value =~ m"^'?(?:opt|rename|rm-optarg|rmdir):.*$") { 4520 } elsif ($value =~ m"^'?(?:opt|rename|rm-optarg|rmdir):.*$") {
4511 # FIXME: This is cheated. 4521 # FIXME: This is cheated.
4512 # Fine. 4522 # Fine.
4513 4523
4514 } elsif ($value eq "-e" || $value =~ m"^\"?'?s[|:,]") { 4524 } elsif ($value eq "-e" || $value =~ m"^\"?'?s[|:,]") {
4515 # FIXME: This is cheated. 4525 # FIXME: This is cheated.
4516 # Fine. 4526 # Fine.
4517 4527
4518 } else { 4528 } else {
4519 $line->log_warning("Unknown wrapper transform command \"${value}\"."); 4529 $line->log_warning("Unknown wrapper transform command \"${value}\".");
4520 } 4530 }
4521 }, 4531 },
4522 4532
4523 WrkdirSubdirectory => sub { 4533 WrkdirSubdirectory => sub {
4524 checkline_mk_vartype_basic($line, $varname, "Pathname", $op, $value, $comment, $list_context, $is_guessed); 4534 checkline_mk_vartype_basic($line, $varname, "Pathname", $op, $value, $comment, $list_context, $is_guessed);
4525 if ($value eq "\${WRKDIR}") { 4535 if ($value eq "\${WRKDIR}") {
4526 # Fine. 4536 # Fine.
4527 } else { 4537 } else {
4528 $opt_debug_unchecked and $line->log_debug("Unchecked subdirectory \"${value}\" of \${WRKDIR}."); 4538 $opt_debug_unchecked and $line->log_debug("Unchecked subdirectory \"${value}\" of \${WRKDIR}.");
4529 } 4539 }
4530 }, 4540 },
4531 4541
4532 WrksrcSubdirectory => sub { 4542 WrksrcSubdirectory => sub {
4533 if ($value =~ m"^(\$\{WRKSRC\})(?:/(.*))?") { 4543 if ($value =~ m"^(\$\{WRKSRC\})(?:/(.*))?") {
4534 my ($prefix, $rest) = ($1, $2); 4544 my ($prefix, $rest) = ($1, $2);
4535 $line->log_note("You can use \"" . (defined($rest) ? $rest : ".") . "\" instead of \"${value}\"."); 4545 $line->log_note("You can use \"" . (defined($rest) ? $rest : ".") . "\" instead of \"${value}\".");
4536 4546
4537 } elsif ($value ne "" && $value_novar eq "") { 4547 } elsif ($value ne "" && $value_novar eq "") {
4538 # The value of another variable 4548 # The value of another variable
4539 4549
4540 } elsif ($value_novar !~ m"^(?:\.|[0-9A-Za-z_\@][-0-9A-Za-z_\@./+]*)$") { 4550 } elsif ($value_novar !~ m"^(?:\.|[0-9A-Za-z_\@][-0-9A-Za-z_\@./+]*)$") {
4541 $line->log_warning("\"${value}\" is not a valid subdirectory of \${WRKSRC}."); 4551 $line->log_warning("\"${value}\" is not a valid subdirectory of \${WRKSRC}.");
4542 } 4552 }
4543 }, 4553 },
4544 4554
4545 Yes => sub { 4555 Yes => sub {
4546 if ($value !~ m"^(?:YES|yes)(?:\s+#.*)?$") { 4556 if ($value !~ m"^(?:YES|yes)(?:\s+#.*)?$") {
4547 $line->log_warning("${varname} should be set to YES or yes."); 4557 $line->log_warning("${varname} should be set to YES or yes.");
4548 $line->explain_warning( 4558 $line->explain_warning(
4549"This variable means \"yes\" if it is defined, and \"no\" if it is", 4559"This variable means \"yes\" if it is defined, and \"no\" if it is",
4550"undefined. Even when it has the value \"no\", this means \"yes\".", 4560"undefined. Even when it has the value \"no\", this means \"yes\".",
4551"Therefore when it is defined, its value should correspond to its", 4561"Therefore when it is defined, its value should correspond to its",
4552"meaning."); 4562"meaning.");
4553 } 4563 }
4554 }, 4564 },
4555 4565
4556 YesNo => sub { 4566 YesNo => sub {
4557 if ($value !~ m"^(?:YES|yes|NO|no)(?:\s+#.*)?$") { 4567 if ($value !~ m"^(?:YES|yes|NO|no)(?:\s+#.*)?$") {
4558 $line->log_warning("${varname} should be set to YES, yes, NO, or no."); 4568 $line->log_warning("${varname} should be set to YES, yes, NO, or no.");
4559 } 4569 }
4560 }, 4570 },
4561 4571
4562 YesNo_Indirectly => sub { 4572 YesNo_Indirectly => sub {
4563 if ($value_novar ne "" && $value !~ m"^(?:YES|yes|NO|no)(?:\s+#.*)?$") { 4573 if ($value_novar ne "" && $value !~ m"^(?:YES|yes|NO|no)(?:\s+#.*)?$") {
4564 $line->log_warning("${varname} should be set to YES, yes, NO, or no."); 4574 $line->log_warning("${varname} should be set to YES, yes, NO, or no.");
4565 } 4575 }
4566 }, 4576 },
4567 ); 4577 );
4568 4578
4569 if (ref($type) eq "HASH") { 4579 if (ref($type) eq "HASH") {
4570 if (!exists($type->{$value})) { 4580 if (!exists($type->{$value})) {
4571 $line->log_warning("\"${value}\" is not valid for ${varname}. Use one of { ".join(" ", sort(keys(%{$type})))." } instead."); 4581 $line->log_warning("\"${value}\" is not valid for ${varname}. Use one of { ".join(" ", sort(keys(%{$type})))." } instead.");
4572 } 4582 }
4573 4583
4574 } elsif (defined $type_dispatch{$type}) { 4584 } elsif (defined $type_dispatch{$type}) {
4575 $type_dispatch{$type}->(); 4585 $type_dispatch{$type}->();
4576 4586
4577 } else { 4587 } else {
4578 $line->log_fatal("Type ${type} unknown."); 4588 $line->log_fatal("Type ${type} unknown.");
4579 } 4589 }
4580} 4590}
4581 4591
4582# Checks whether the list of version numbers that are given as the 4592# Checks whether the list of version numbers that are given as the
4583# C<value> of the variable C<varname> are in decreasing order. 4593# C<value> of the variable C<varname> are in decreasing order.
4584sub checkline_decreasing_order($$$) { 4594sub checkline_decreasing_order($$$) {
4585 my ($line, $varname, $value) = @_; 4595 my ($line, $varname, $value) = @_;
4586 4596
4587 my @pyver = split(qr"\s+", $value); 4597 my @pyver = split(qr"\s+", $value);
4588 if (!@pyver) { 4598 if (!@pyver) {
4589 $line->log_error("There must be at least one value for ${varname}."); 4599 $line->log_error("There must be at least one value for ${varname}.");
4590 return; 4600 return;
4591 } 4601 }
4592 4602
4593 my $ver = shift(@pyver); 4603 my $ver = shift(@pyver);
4594 if ($ver !~ m"^\d+$") { 4604 if ($ver !~ m"^\d+$") {
4595 $line->log_error("All values for ${varname} must be numeric."); 4605 $line->log_error("All values for ${varname} must be numeric.");
4596 return; 4606 return;
4597 } 4607 }
4598 4608
4599 while (@pyver) { 4609 while (@pyver) {
4600 my $nextver = shift(@pyver); 4610 my $nextver = shift(@pyver);
4601 if ($nextver !~ m"^\d+$") { 4611 if ($nextver !~ m"^\d+$") {
4602 $line->log_error("All values for ${varname} must be numeric."); 4612 $line->log_error("All values for ${varname} must be numeric.");
4603 return; 4613 return;
4604 } 4614 }
4605 4615
4606 if ($nextver >= $ver) { 4616 if ($nextver >= $ver) {
4607 $line->log_warning("The values for ${varname} should be in decreasing order."); 4617 $line->log_warning("The values for ${varname} should be in decreasing order.");
4608 $line->explain_warning( 4618 $line->explain_warning(
4609"If they aren't, it may be possible that needless versions of packages", 4619"If they aren't, it may be possible that needless versions of packages",
4610"are installed."); 4620"are installed.");
4611 } 4621 }
4612 $ver = $nextver; 4622 $ver = $nextver;
4613 } 4623 }
4614} 4624}
4615 4625
4616sub checkline_mk_vartype($$$$$) { 4626sub checkline_mk_vartype($$$$$) {
4617 my ($line, $varname, $op, $value, $comment) = @_; 4627 my ($line, $varname, $op, $value, $comment) = @_;
4618 4628
4619 return unless $opt_warn_types; 4629 return unless $opt_warn_types;
4620 4630
4621 my $vartypes = get_vartypes_map(); 4631 my $vartypes = get_vartypes_map();
4622 my $varbase = varname_base($varname); 4632 my $varbase = varname_base($varname);
4623 my $varcanon = varname_canon($varname); 4633 my $varcanon = varname_canon($varname);
4624 4634
4625 my $type = get_variable_type($line, $varname); 4635 my $type = get_variable_type($line, $varname);
4626 4636
4627 if ($op eq "+=") { 4637 if ($op eq "+=") {
4628 if (defined($type)) { 4638 if (defined($type)) {
4629 if (!$type->may_use_plus_eq()) { 4639 if (!$type->may_use_plus_eq()) {
4630 $line->log_warning("The \"+=\" operator should only be used with lists."); 4640 $line->log_warning("The \"+=\" operator should only be used with lists.");
4631 } 4641 }
4632 } elsif ($varbase !~ m"^_" && $varbase !~ get_regex_plurals()) { 4642 } elsif ($varbase !~ m"^_" && $varbase !~ get_regex_plurals()) {
4633 $line->log_warning("As ${varname} is modified using \"+=\", its name should indicate plural."); 4643 $line->log_warning("As ${varname} is modified using \"+=\", its name should indicate plural.");
4634 } 4644 }
4635 } 4645 }
4636 4646
4637 if (!defined($type)) { 4647 if (!defined($type)) {
4638 # Cannot check anything if the type is not known. 4648 # Cannot check anything if the type is not known.
4639 $opt_debug_unchecked and $line->log_debug("Unchecked variable assignment for ${varname}."); 4649 $opt_debug_unchecked and $line->log_debug("Unchecked variable assignment for ${varname}.");
4640 4650
4641 } elsif ($op eq "!=") { 4651 } elsif ($op eq "!=") {
4642 $opt_debug_misc and $line->log_debug("Use of !=: ${value}"); 4652 $opt_debug_misc and $line->log_debug("Use of !=: ${value}");
4643 4653
4644 } elsif ($type->kind_of_list != LK_NONE) { 4654 } elsif ($type->kind_of_list != LK_NONE) {
4645 my (@words, $rest); 4655 my (@words, $rest);
4646 4656
4647 if ($type->kind_of_list == LK_INTERNAL) { 4657 if ($type->kind_of_list == LK_INTERNAL) {
4648 @words = split(qr"\s+", $value); 4658 @words = split(qr"\s+", $value);
4649 $rest = ""; 4659 $rest = "";
4650 } else { 4660 } else {
4651 @words = (); 4661 @words = ();
4652 $rest = $value; 4662 $rest = $value;
4653 while ($rest =~ s/^$regex_shellword//) { 4663 while ($rest =~ s/^$regex_shellword//) {
4654 my ($word) = ($1); 4664 my ($word) = ($1);
4655 last if ($word =~ m"^#"); 4665 last if ($word =~ m"^#");
4656 push(@words, $1); 4666 push(@words, $1);
4657 } 4667 }
4658 } 4668 }
4659 4669
4660 foreach my $word (@words) { 4670 foreach my $word (@words) {
4661 checkline_mk_vartype_basic($line, $varname, $type->basic_type, $op, $word, $comment, true, $type->is_guessed); 4671 checkline_mk_vartype_basic($line, $varname, $type->basic_type, $op, $word, $comment, true, $type->is_guessed);
4662 if ($type->kind_of_list != LK_INTERNAL) { 4672 if ($type->kind_of_list != LK_INTERNAL) {
4663 checkline_mk_shellword($line, $word, true); 4673 checkline_mk_shellword($line, $word, true);
4664 } 4674 }
4665 } 4675 }
4666 4676
4667 if ($rest !~ m"^\s*$") { 4677 if ($rest !~ m"^\s*$") {
4668 $line->log_error("Internal pkglint error: rest=${rest}"); 4678 $line->log_error("Internal pkglint error: rest=${rest}");
4669 } 4679 }
4670 4680
4671 } else { 4681 } else {
4672 checkline_mk_vartype_basic($line, $varname, $type->basic_type, $op, $value, $comment, $type->is_practically_a_list(), $type->is_guessed); 4682 checkline_mk_vartype_basic($line, $varname, $type->basic_type, $op, $value, $comment, $type->is_practically_a_list(), $type->is_guessed);
4673 } 4683 }
4674} 4684}
4675 4685
4676sub checkline_mk_varassign($$$$$) { 4686sub checkline_mk_varassign($$$$$) {
4677 my ($line, $varname, $op, $value, $comment) = @_; 4687 my ($line, $varname, $op, $value, $comment) = @_;
4678 my ($used_vars); 4688 my ($used_vars);
4679 my $varbase = varname_base($varname); 4689 my $varbase = varname_base($varname);
4680 my $varcanon = varname_canon($varname); 4690 my $varcanon = varname_canon($varname);
4681 4691
4682 $opt_debug_trace and $line->log_debug("checkline_mk_varassign($varname, $op, $value)"); 4692 $opt_debug_trace and $line->log_debug("checkline_mk_varassign($varname, $op, $value)");
4683 4693
4684 checkline_mk_vardef($line, $varname, $op); 4694 checkline_mk_vardef($line, $varname, $op);
4685 4695
4686 if ($op eq "?=" && defined($seen_bsd_prefs_mk) && !$seen_bsd_prefs_mk) { 4696 if ($op eq "?=" && defined($seen_bsd_prefs_mk) && !$seen_bsd_prefs_mk) {
4687 if ($varbase eq "BUILDLINK_PKGSRCDIR" 4697 if ($varbase eq "BUILDLINK_PKGSRCDIR"
4688 || $varbase eq "BUILDLINK_DEPMETHOD" 4698 || $varbase eq "BUILDLINK_DEPMETHOD"
4689 || $varbase eq "BUILDLINK_ABI_DEPENDS") { 4699 || $varbase eq "BUILDLINK_ABI_DEPENDS") {
4690 # FIXME: What about these ones? They occur quite often. 4700 # FIXME: What about these ones? They occur quite often.
4691 } else { 4701 } else {
4692 $opt_warn_extra and $line->log_warning("Please include \"../../mk/bsd.prefs.mk\" before using \"?=\"."); 4702 $opt_warn_extra and $line->log_warning("Please include \"../../mk/bsd.prefs.mk\" before using \"?=\".");
4693 $opt_warn_extra and $line->explain_warning( 4703 $opt_warn_extra and $line->explain_warning(
4694"The ?= operator is used to provide a default value to a variable. In", 4704"The ?= operator is used to provide a default value to a variable. In",
4695"pkgsrc, many variables can be set by the pkgsrc user in the mk.conf", 4705"pkgsrc, many variables can be set by the pkgsrc user in the mk.conf",
4696"file. This file must be included explicitly. If a ?= operator appears", 4706"file. This file must be included explicitly. If a ?= operator appears",
4697"before mk.conf has been included, it will not care about the user's", 4707"before mk.conf has been included, it will not care about the user's",
4698"preferences, which can result in unexpected behavior. The easiest way", 4708"preferences, which can result in unexpected behavior. The easiest way",
4699"to include the mk.conf file is by including the bsd.prefs.mk file,", 4709"to include the mk.conf file is by including the bsd.prefs.mk file,",
4700"which will take care of everything."); 4710"which will take care of everything.");
4701 } 4711 }
4702 } 4712 }
4703 4713
4704 checkline_mk_text($line, $value); 4714 checkline_mk_text($line, $value);
4705 checkline_mk_vartype($line, $varname, $op, $value, $comment); 4715 checkline_mk_vartype($line, $varname, $op, $value, $comment);
4706 4716
4707 # If the variable is not used and is untyped, it may be a 4717 # If the variable is not used and is untyped, it may be a
4708 # spelling mistake. 4718 # spelling mistake.
4709 if ($op eq ":=" && $varname eq lc($varname)) { 4719 if ($op eq ":=" && $varname eq lc($varname)) {
4710 $opt_debug_unchecked and $line->log_debug("${varname} might be unused unless it is an argument to a procedure file."); 4720 $opt_debug_unchecked and $line->log_debug("${varname} might be unused unless it is an argument to a procedure file.");
4711 # TODO: check $varname against the list of "procedure files". 4721 # TODO: check $varname against the list of "procedure files".
4712 4722
4713 } elsif (!var_is_used($varname)) { 4723 } elsif (!var_is_used($varname)) {
4714 my $vartypes = get_vartypes_map(); 4724 my $vartypes = get_vartypes_map();
4715 my $deprecated = get_deprecated_map(); 4725 my $deprecated = get_deprecated_map();
4716 4726
4717 if (exists($vartypes->{$varname}) || exists($vartypes->{$varcanon})) { 4727 if (exists($vartypes->{$varname}) || exists($vartypes->{$varcanon})) {
4718 # Ok 4728 # Ok
4719 } elsif (exists($deprecated->{$varname}) || exists($deprecated->{$varcanon})) { 4729 } elsif (exists($deprecated->{$varname}) || exists($deprecated->{$varcanon})) {
4720 # Ok 4730 # Ok
4721 } else { 4731 } else {
4722 $line->log_warning("${varname} is defined but not used. Spelling mistake?"); 4732 $line->log_warning("${varname} is defined but not used. Spelling mistake?");
4723 } 4733 }
4724 } 4734 }
4725 4735
4726 if ($value =~ m"/etc/rc\.d") { 4736 if ($value =~ m"/etc/rc\.d") {
4727 $line->log_warning("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to \${RCD_SCRIPTS_EXAMPLEDIR}."); 4737 $line->log_warning("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to \${RCD_SCRIPTS_EXAMPLEDIR}.");
4728 } 4738 }
4729 4739
4730 if (!$is_internal && $varname =~ m"^_") { 4740 if (!$is_internal && $varname =~ m"^_") {
4731 $line->log_warning("Variable names starting with an underscore are reserved for internal pkgsrc use."); 4741 $line->log_warning("Variable names starting with an underscore are reserved for internal pkgsrc use.");
4732 } 4742 }
4733 4743
4734 if ($varname eq "PERL5_PACKLIST" && defined($effective_pkgbase) && $effective_pkgbase =~ m"^p5-(.*)") { 4744 if ($varname eq "PERL5_PACKLIST" && defined($effective_pkgbase) && $effective_pkgbase =~ m"^p5-(.*)") {
4735 my ($guess) = ($1); 4745 my ($guess) = ($1);
4736 $guess =~ s/-/\//g; 4746 $guess =~ s/-/\//g;
4737 $guess = "auto/${guess}/.packlist"; 4747 $guess = "auto/${guess}/.packlist";
4738 4748
4739 my ($ucvalue, $ucguess) = (uc($value), uc($guess)); 4749 my ($ucvalue, $ucguess) = (uc($value), uc($guess));
4740 if ($ucvalue ne $ucguess && $ucvalue ne "\${PERL5_SITEARCH\}/${ucguess}") { 4750 if ($ucvalue ne $ucguess && $ucvalue ne "\${PERL5_SITEARCH\}/${ucguess}") {
4741 $line->log_warning("Unusual value for PERL5_PACKLIST -- \"${guess}\" expected."); 4751 $line->log_warning("Unusual value for PERL5_PACKLIST -- \"${guess}\" expected.");
4742 } 4752 }
4743 } 4753 }
4744 4754
4745 if ($varname eq "CONFIGURE_ARGS" && $value =~ m"=\$\{PREFIX\}/share/kde") { 4755 if ($varname eq "CONFIGURE_ARGS" && $value =~ m"=\$\{PREFIX\}/share/kde") {
4746 $line->log_note("Please .include \"../../meta-pkgs/kde3/kde3.mk\" instead of this line."); 4756 $line->log_note("Please .include \"../../meta-pkgs/kde3/kde3.mk\" instead of this line.");
4747 $line->explain_note( 4757 $line->explain_note(
4748"That file probably does many things automatically and consistently that", 4758"That file probably does many things automatically and consistently that",
4749"this package also does. When using kde3.mk, you can probably also leave", 4759"this package also does. When using kde3.mk, you can probably also leave",
4750"out some explicit dependencies."); 4760"out some explicit dependencies.");
4751 } 4761 }
4752 4762
4753 if ($varname eq "EVAL_PREFIX" && $value =~ m"^([\w_]+)=") { 4763 if ($varname eq "EVAL_PREFIX" && $value =~ m"^([\w_]+)=") {
4754 my ($eval_varname) = ($1); 4764 my ($eval_varname) = ($1);
4755 4765
4756 # The variables mentioned in EVAL_PREFIX will later be 4766 # The variables mentioned in EVAL_PREFIX will later be
4757 # defined by find-prefix.mk. Therefore, they are marked 4767 # defined by find-prefix.mk. Therefore, they are marked
4758 # as known in the current file. 4768 # as known in the current file.
4759 $mkctx_vardef->{$eval_varname} = $line; 4769 $mkctx_vardef->{$eval_varname} = $line;
4760 } 4770 }
4761 4771
4762 if ($varname eq "PYTHON_VERSIONS_ACCEPTED") { 4772 if ($varname eq "PYTHON_VERSIONS_ACCEPTED") {
4763 checkline_decreasing_order($line, $varname, $value); 4773 checkline_decreasing_order($line, $varname, $value);
4764 } 4774 }
4765 4775
4766 if (defined($comment) && $comment eq "# defined" && $varname !~ m".*(?:_MK|_COMMON)$") { 4776 if (defined($comment) && $comment eq "# defined" && $varname !~ m".*(?:_MK|_COMMON)$") {
4767 $line->log_note("Please use \"# empty\", \"# none\" or \"yes\" instead of \"# defined\"."); 4777 $line->log_note("Please use \"# empty\", \"# none\" or \"yes\" instead of \"# defined\".");
4768 $line->explain_note( 4778 $line->explain_note(
4769"The value #defined says something about the state of the variable, but", 4779"The value #defined says something about the state of the variable, but",
4770"not what that _means_. In some cases a variable that is defined means", 4780"not what that _means_. In some cases a variable that is defined means",
4771"\"yes\", in other cases it is an empty list (which is also only the", 4781"\"yes\", in other cases it is an empty list (which is also only the",
4772"state of the variable), whose meaning could be described with \"none\".", 4782"state of the variable), whose meaning could be described with \"none\".",
4773"It is this meaning that should be described."); 4783"It is this meaning that should be described.");
4774 } 4784 }
4775 4785
4776 if ($value =~ m"\$\{(PKGNAME|PKGVERSION)[:\}]") { 4786 if ($value =~ m"\$\{(PKGNAME|PKGVERSION)[:\}]") {
4777 my ($pkgvarname) = ($1); 4787 my ($pkgvarname) = ($1);
4778 if ($varname =~ m"^PKG_.*_REASON$") { 4788 if ($varname =~ m"^PKG_.*_REASON$") {
4779 # ok 4789 # ok
4780 } elsif ($varname =~ m"^(?:DIST_SUBDIR|WRKSRC)$") { 4790 } elsif ($varname =~ m"^(?:DIST_SUBDIR|WRKSRC)$") {
4781 $line->log_warning("${pkgvarname} should not be used in ${varname}, as it sometimes includes the PKGREVISION. Please use ${pkgvarname}_NOREV instead."); 4791 $line->log_warning("${pkgvarname} should not be used in ${varname}, as it sometimes includes the PKGREVISION. Please use ${pkgvarname}_NOREV instead.");
4782 } else { 4792 } else {
4783 $opt_debug_misc and $line->log_debug("Use of PKGNAME in ${varname}."); 4793 $opt_debug_misc and $line->log_debug("Use of PKGNAME in ${varname}.");
4784 } 4794 }
4785 } 4795 }
4786 4796
4787 if (exists(get_deprecated_map()->{$varname})) { 4797 if (exists(get_deprecated_map()->{$varname})) {
4788 $line->log_warning("Definition of ${varname} is deprecated. ".get_deprecated_map()->{$varname}); 4798 $line->log_warning("Definition of ${varname} is deprecated. ".get_deprecated_map()->{$varname});
4789 } elsif (exists(get_deprecated_map()->{$varcanon})) { 4799 } elsif (exists(get_deprecated_map()->{$varcanon})) {
4790 $line->log_warning("Definition of ${varname} is deprecated. ".get_deprecated_map()->{$varcanon}); 4800 $line->log_warning("Definition of ${varname} is deprecated. ".get_deprecated_map()->{$varcanon});
4791 } 4801 }
4792 4802
4793 if ($varname =~ m"^SITES_") { 4803 if ($varname =~ m"^SITES_") {
4794 $line->log_warning("SITES_* is deprecated. Please use SITES.* instead."); 4804 $line->log_warning("SITES_* is deprecated. Please use SITES.* instead.");
4795 } 4805 }
4796 4806
4797 if ($value =~ m"^[^=]\@comment") { 4807 if ($value =~ m"^[^=]\@comment") {
4798 $line->log_warning("Please don't use \@comment in ${varname}."); 4808 $line->log_warning("Please don't use \@comment in ${varname}.");
4799 $line->explain_warning( 4809 $line->explain_warning(
4800"Here you are defining a variable containing \@comment. As this value", 4810"Here you are defining a variable containing \@comment. As this value",
4801"typically includes a space as the last character you probably also used", 4811"typically includes a space as the last character you probably also used",
4802"quotes around the variable. This can lead to confusion when adding this", 4812"quotes around the variable. This can lead to confusion when adding this",
4803"variable to PLIST_SUBST, as all other variables are quoted using the :Q", 4813"variable to PLIST_SUBST, as all other variables are quoted using the :Q",
4804"operator when they are appended. As it is hard to check whether a", 4814"operator when they are appended. As it is hard to check whether a",
4805"variable that is appended to PLIST_SUBST is already quoted or not, you", 4815"variable that is appended to PLIST_SUBST is already quoted or not, you",
4806"should not have pre-quoted variables at all. To solve this, you should", 4816"should not have pre-quoted variables at all. To solve this, you should",
4807"directly use PLIST_SUBST+= ${varname}=${value} or use any other", 4817"directly use PLIST_SUBST+= ${varname}=${value} or use any other",
4808"variable for collecting the list of PLIST substitutions and later", 4818"variable for collecting the list of PLIST substitutions and later",
4809"append that variable with PLIST_SUBST+= \${MY_PLIST_SUBST}."); 4819"append that variable with PLIST_SUBST+= \${MY_PLIST_SUBST}.");
4810 } 4820 }
4811 4821
4812 # Mark the variable as PLIST condition. This is later used in 4822 # Mark the variable as PLIST condition. This is later used in
4813 # checkfile_PLIST. 4823 # checkfile_PLIST.
4814 if (defined($pkgctx_plist_subst_cond) && $value =~ m"(.+)=.*\@comment.*") { 4824 if (defined($pkgctx_plist_subst_cond) && $value =~ m"(.+)=.*\@comment.*") {
4815 $pkgctx_plist_subst_cond->{$1}++; 4825 $pkgctx_plist_subst_cond->{$1}++;
4816 } 4826 }
4817 4827
4818 use constant op_to_use_time => { 4828 use constant op_to_use_time => {
4819 ":=" => VUC_TIME_LOAD, 4829 ":=" => VUC_TIME_LOAD,
4820 "!=" => VUC_TIME_LOAD, 4830 "!=" => VUC_TIME_LOAD,
4821 "=" => VUC_TIME_RUN, 4831 "=" => VUC_TIME_RUN,
4822 "+=" => VUC_TIME_RUN, 4832 "+=" => VUC_TIME_RUN,
4823 "?=" => VUC_TIME_RUN 4833 "?=" => VUC_TIME_RUN
4824 }; 4834 };
4825  4835
4826 $used_vars = extract_used_variables($line, $value); 4836 $used_vars = extract_used_variables($line, $value);
4827 my $vuc = PkgLint::VarUseContext->new( 4837 my $vuc = PkgLint::VarUseContext->new(
4828 op_to_use_time->{$op}, 4838 op_to_use_time->{$op},
4829 get_variable_type($line, $varname), 4839 get_variable_type($line, $varname),
4830 VUC_SHELLWORD_UNKNOWN, # XXX: maybe PLAIN? 4840 VUC_SHELLWORD_UNKNOWN, # XXX: maybe PLAIN?
4831 VUC_EXTENT_UNKNOWN 4841 VUC_EXTENT_UNKNOWN
4832 ); 4842 );
4833 foreach my $used_var (@{$used_vars}) { 4843 foreach my $used_var (@{$used_vars}) {
4834 checkline_mk_varuse($line, $used_var, "", $vuc); 4844 checkline_mk_varuse($line, $used_var, "", $vuc);
4835 } 4845 }
4836} 4846}
4837 4847
4838# The bmake parser is way too sloppy about syntax, so we need to check 4848# The bmake parser is way too sloppy about syntax, so we need to check
4839# that here. 4849# that here.
4840# 4850#
4841sub checkline_mk_cond($$) { 4851sub checkline_mk_cond($$) {
4842 my ($line, $cond) = @_; 4852 my ($line, $cond) = @_;
4843 my ($op, $varname, $match, $value); 4853 my ($op, $varname, $match, $value);
4844 4854
4845 $opt_debug_trace and $line->log_debug("checkline_mk_cond($cond)"); 4855 $opt_debug_trace and $line->log_debug("checkline_mk_cond($cond)");
4846 my $tree = parse_mk_cond($line, $cond); 4856 my $tree = parse_mk_cond($line, $cond);
4847 if (tree_match($tree, ["not", ["empty", ["match", \$varname, \$match]]])) { 4857 if (tree_match($tree, ["not", ["empty", ["match", \$varname, \$match]]])) {
4848 #$line->log_note("tree_match: varname=$varname, match=$match"); 4858 #$line->log_note("tree_match: varname=$varname, match=$match");
4849 4859
4850 my $type = get_variable_type($line, $varname); 4860 my $type = get_variable_type($line, $varname);
4851 my $btype = defined($type) ? $type->basic_type : undef; 4861 my $btype = defined($type) ? $type->basic_type : undef;
4852 if (defined($btype) && ref($type->basic_type) eq "HASH") { 4862 if (defined($btype) && ref($type->basic_type) eq "HASH") {
4853 if ($match !~ m"[\$\[*]" && !exists($btype->{$match})) { 4863 if ($match !~ m"[\$\[*]" && !exists($btype->{$match})) {
4854 $line->log_warning("Invalid :M value \"$match\". Only { " . join(" ", sort keys %$btype) . " } are allowed."); 4864 $line->log_warning("Invalid :M value \"$match\". Only { " . join(" ", sort keys %$btype) . " } are allowed.");
4855 } 4865 }
4856 } 4866 }
4857 4867
4858 # Currently disabled because the valid options can also be defined in PKG_OPTIONS_GROUP.*. 4868 # Currently disabled because the valid options can also be defined in PKG_OPTIONS_GROUP.*.
4859 # Additionally, all these variables may have multiple assigments (+=). 4869 # Additionally, all these variables may have multiple assigments (+=).
4860 if (false && $varname eq "PKG_OPTIONS" && defined($pkgctx_vardef) && exists($pkgctx_vardef->{"PKG_SUPPORTED_OPTIONS"})) { 4870 if (false && $varname eq "PKG_OPTIONS" && defined($pkgctx_vardef) && exists($pkgctx_vardef->{"PKG_SUPPORTED_OPTIONS"})) {
4861 my $options = $pkgctx_vardef->{"PKG_SUPPORTED_OPTIONS"}->get("value"); 4871 my $options = $pkgctx_vardef->{"PKG_SUPPORTED_OPTIONS"}->get("value");
4862 4872
4863 if ($match !~ m"[\$\[*]" && index(" $options ", " $match ") == -1) { 4873 if ($match !~ m"[\$\[*]" && index(" $options ", " $match ") == -1) {
4864 $line->log_warning("Invalid option \"$match\". Only { $options } are allowed."); 4874 $line->log_warning("Invalid option \"$match\". Only { $options } are allowed.");
4865 } 4875 }
4866 } 4876 }
4867 4877
4868 # TODO: PKG_BUILD_OPTIONS. That requires loading the 4878 # TODO: PKG_BUILD_OPTIONS. That requires loading the
4869 # complete package definitition for the package "pkgbase" 4879 # complete package definitition for the package "pkgbase"
4870 # or some other database. If we could confine all option 4880 # or some other database. If we could confine all option
4871 # definitions to options.mk, this would become easier. 4881 # definitions to options.mk, this would become easier.
4872 4882
4873 } elsif (tree_match($tree, [\$op, ["var", \$varname], ["string", \$value]])) { 4883 } elsif (tree_match($tree, [\$op, ["var", \$varname], ["string", \$value]])) {
4874 checkline_mk_vartype($line, $varname, "use", $value, undef); 4884 checkline_mk_vartype($line, $varname, "use", $value, undef);
4875 4885
4876 } 4886 }
4877 # XXX: When adding new cases, be careful that the variables may have 4887 # XXX: When adding new cases, be careful that the variables may have
4878 # been partially initialized by previous calls to tree_match. 4888 # been partially initialized by previous calls to tree_match.
4879 # XXX: Maybe it is better to clear these references at the beginning 4889 # XXX: Maybe it is better to clear these references at the beginning
4880 # of tree_match. 4890 # of tree_match.
4881} 4891}
4882 4892
4883# 4893#
4884# Procedures to check an array of lines. 4894# Procedures to check an array of lines.
4885# 4895#
4886 4896
4887sub checklines_trailing_empty_lines($) { 4897sub checklines_trailing_empty_lines($) {
4888 my ($lines) = @_; 4898 my ($lines) = @_;
4889 my ($last, $max); 4899 my ($last, $max);
4890 4900
4891 $max = $#{$lines} + 1; 4901 $max = $#{$lines} + 1;
4892 for ($last = $max; $last > 1 && $lines->[$last - 1]->text eq ""; ) { 4902 for ($last = $max; $last > 1 && $lines->[$last - 1]->text eq ""; ) {
4893 $last--; 4903 $last--;
4894 } 4904 }
4895 if ($last != $max) { 4905 if ($last != $max) {
4896 $lines->[$last]->log_note("Trailing empty lines."); 4906 $lines->[$last]->log_note("Trailing empty lines.");
4897 } 4907 }
4898} 4908}
4899 4909
4900sub checklines_package_Makefile_varorder($) { 4910sub checklines_package_Makefile_varorder($) {
4901 my ($lines) = @_; 4911 my ($lines) = @_;
4902 4912
4903 return unless $opt_warn_varorder; 4913 return unless $opt_warn_varorder;
4904 4914
4905 use enum qw(once optional many); 4915 use enum qw(once optional many);
4906 my (@sections) = ( 4916 my (@sections) = (
4907 [ "Initial comments", once, 4917 [ "Initial comments", once,
4908 [ 4918 [
4909 ] 4919 ]
4910 ], 4920 ],
4911 [ "Unsorted stuff, part 1", once, 4921 [ "Unsorted stuff, part 1", once,
4912 [ 4922 [
4913 [ "DISTNAME", once ], 4923 [ "DISTNAME", once ],
4914 [ "PKGNAME", optional ], 4924 [ "PKGNAME", optional ],
4915 [ "PKGREVISION", optional ], 4925 [ "PKGREVISION", optional ],
4916 [ "SVR4_PKGNAME", optional ], 4926 [ "SVR4_PKGNAME", optional ],
4917 [ "CATEGORIES", once ], 4927 [ "CATEGORIES", once ],
4918 [ "MASTER_SITES", optional ], 4928 [ "MASTER_SITES", optional ],
4919 [ "DIST_SUBDIR", optional ], 4929 [ "DIST_SUBDIR", optional ],
4920 [ "EXTRACT_SUFX", optional ], 4930 [ "EXTRACT_SUFX", optional ],
4921 [ "DISTFILES", many ], 4931 [ "DISTFILES", many ],
4922 [ "SITES.*", many ], 4932 [ "SITES.*", many ],
4923 ] 4933 ]
4924 ], 4934 ],
4925 [ "Distribution patches", optional, 4935 [ "Distribution patches", optional,
4926 [ 4936 [
4927 [ "PATCH_SITES", optional ], # or once? 4937 [ "PATCH_SITES", optional ], # or once?
4928 [ "PATCH_SITE_SUBDIR", optional ], 4938 [ "PATCH_SITE_SUBDIR", optional ],
4929 [ "PATCHFILES", optional ], # or once? 4939 [ "PATCHFILES", optional ], # or once?
4930 [ "PATCH_DIST_ARGS", optional ], 4940 [ "PATCH_DIST_ARGS", optional ],
4931 [ "PATCH_DIST_STRIP", optional ], 4941 [ "PATCH_DIST_STRIP", optional ],
4932 [ "PATCH_DIST_CAT", optional ], 4942 [ "PATCH_DIST_CAT", optional ],
4933 ] 4943 ]
4934 ], 4944 ],
4935 [ "Unsorted stuff, part 2", once, 4945 [ "Unsorted stuff, part 2", once,
4936 [ 4946 [
4937 [ "MAINTAINER", optional ], 4947 [ "MAINTAINER", optional ],
4938 [ "OWNER", optional ], 4948 [ "OWNER", optional ],
4939 [ "HOMEPAGE", optional ], 4949 [ "HOMEPAGE", optional ],
4940 [ "COMMENT", once ], 4950 [ "COMMENT", once ],
4941 [ "LICENSE", once ], 4951 [ "LICENSE", once ],
4942 ] 4952 ]
4943 ], 4953 ],
4944 [ "Legal issues", optional, 4954 [ "Legal issues", optional,
4945 [ 4955 [
4946 [ "LICENSE_FILE", optional ], 4956 [ "LICENSE_FILE", optional ],
4947 [ "RESTRICTED", optional ], 4957 [ "RESTRICTED", optional ],
4948 [ "NO_BIN_ON_CDROM", optional ], 4958 [ "NO_BIN_ON_CDROM", optional ],
4949 [ "NO_BIN_ON_FTP", optional ], 4959 [ "NO_BIN_ON_FTP", optional ],
4950 [ "NO_SRC_ON_CDROM", optional ], 4960 [ "NO_SRC_ON_CDROM", optional ],
4951 [ "NO_SRC_ON_FTP", optional ], 4961 [ "NO_SRC_ON_FTP", optional ],
4952 ] 4962 ]
4953 ], 4963 ],
4954 [ "Technical restrictions", optional, 4964 [ "Technical restrictions", optional,
4955 [ 4965 [
4956 [ "NOT_FOR_PLATFORM", many ], 4966 [ "NOT_FOR_PLATFORM", many ],
4957 [ "ONLY_FOR_PLATFORM", many ], 4967 [ "ONLY_FOR_PLATFORM", many ],
4958 [ "NOT_FOR_COMPILER", many ], 4968 [ "NOT_FOR_COMPILER", many ],
4959 [ "ONLY_FOR_COMPILER", many ], 4969 [ "ONLY_FOR_COMPILER", many ],
4960 [ "NOT_FOR_UNPRIVILEGED", optional ], 4970 [ "NOT_FOR_UNPRIVILEGED", optional ],
4961 [ "ONLY_FOR_UNPRIVILEGED", optional ], 4971 [ "ONLY_FOR_UNPRIVILEGED", optional ],
4962 ] 4972 ]
4963 ], 4973 ],
4964 [ "Dependencies", optional, 4974 [ "Dependencies", optional,
4965 [ 4975 [
4966 [ "BUILD_DEPENDS", many ], 4976 [ "BUILD_DEPENDS", many ],
4967 [ "DEPENDS", many ], 4977 [ "DEPENDS", many ],
4968 ] 4978 ]
4969 ] 4979 ]
4970 ); 4980 );
4971 4981
4972 if (!defined($seen_Makefile_common) || $seen_Makefile_common) { 4982 if (!defined($seen_Makefile_common) || $seen_Makefile_common) {
4973 return; 4983 return;
4974 } 4984 }
4975 4985
4976 my ($lineno, $sectindex, $varindex) = (0, -1, 0); 4986 my ($lineno, $sectindex, $varindex) = (0, -1, 0);
4977 my ($next_section, $vars, $below, $below_what) = (true, undef, {}, undef); 4987 my ($next_section, $vars, $below, $below_what) = (true, undef, {}, undef);
4978 4988
4979 # If the current section is optional but contains non-optional 4989 # If the current section is optional but contains non-optional
4980 # fields, the complete section may be skipped as long as there 4990 # fields, the complete section may be skipped as long as there
4981 # has not been a non-optional variable. 4991 # has not been a non-optional variable.
4982 my $may_skip_section = false; 4992 my $may_skip_section = false;
4983 4993
4984 # In each iteration, one of the following becomes true: 4994 # In each iteration, one of the following becomes true:
4985 # - new.lineno > old.lineno 4995 # - new.lineno > old.lineno
4986 # - new.sectindex > old.sectindex 4996 # - new.sectindex > old.sectindex
4987 # - new.sectindex == old.sectindex && new.varindex > old.varindex 4997 # - new.sectindex == old.sectindex && new.varindex > old.varindex
4988 # - new.next_section == true && old.next_section == false 4998 # - new.next_section == true && old.next_section == false
4989 while ($lineno <= $#{$lines}) { 4999 while ($lineno <= $#{$lines}) {
4990 my $line = $lines->[$lineno]; 5000 my $line = $lines->[$lineno];
4991 my $text = $line->text; 5001 my $text = $line->text;
4992 5002
4993 $opt_debug_misc and $line->log_debug("[varorder] section ${sectindex} variable ${varindex}."); 5003 $opt_debug_misc and $line->log_debug("[varorder] section ${sectindex} variable ${varindex}.");
4994 5004
4995 if ($next_section) { 5005 if ($next_section) {
4996 $next_section = false; 5006 $next_section = false;
4997 $sectindex++; 5007 $sectindex++;
4998 last if ($sectindex > $#sections); 5008 last if ($sectindex > $#sections);
4999 $vars = $sections[$sectindex]->[2]; 5009 $vars = $sections[$sectindex]->[2];
5000 $may_skip_section = ($sections[$sectindex]->[1] == optional); 5010 $may_skip_section = ($sections[$sectindex]->[1] == optional);
5001 $varindex = 0; 5011 $varindex = 0;
5002 } 5012 }
5003 5013
5004 if ($text =~ m"^#") { 5014 if ($text =~ m"^#") {
5005 $lineno++; 5015 $lineno++;
5006 5016
5007 } elsif ($line->has("varcanon")) { 5017 } elsif ($line->has("varcanon")) {
5008 my $varcanon = $line->get("varcanon"); 5018 my $varcanon = $line->get("varcanon");
5009 5019
5010 if (exists($below->{$varcanon})) { 5020 if (exists($below->{$varcanon})) {
5011 if (defined($below->{$varcanon})) { 5021 if (defined($below->{$varcanon})) {
5012 $line->log_warning("${varcanon} appears too late. Please put it below $below->{$varcanon}."); 5022 $line->log_warning("${varcanon} appears too late. Please put it below $below->{$varcanon}.");
5013 } else { 5023 } else {
5014 $line->log_warning("${varcanon} appears too late. It should be the very first definition."); 5024 $line->log_warning("${varcanon} appears too late. It should be the very first definition.");
5015 } 5025 }
5016 $lineno++; 5026 $lineno++;
5017 next; 5027 next;
5018 } 5028 }
5019 5029
5020 while ($varindex <= $#{$vars} && $varcanon ne $vars->[$varindex]->[0] && ($vars->[$varindex]->[1] != once || $may_skip_section)) { 5030 while ($varindex <= $#{$vars} && $varcanon ne $vars->[$varindex]->[0] && ($vars->[$varindex]->[1] != once || $may_skip_section)) {
5021 if ($vars->[$varindex]->[1] == once) { 5031 if ($vars->[$varindex]->[1] == once) {
5022 $may_skip_section = false; 5032 $may_skip_section = false;
5023 } 5033 }
5024 $below->{$vars->[$varindex]->[0]} = $below_what; 5034 $below->{$vars->[$varindex]->[0]} = $below_what;
5025 $varindex++; 5035 $varindex++;
5026 } 5036 }
5027 if ($varindex > $#{$vars}) { 5037 if ($varindex > $#{$vars}) {
5028 if ($sections[$sectindex]->[1] != optional) { 5038 if ($sections[$sectindex]->[1] != optional) {
5029 $line->log_warning("Empty line expected."); 5039 $line->log_warning("Empty line expected.");
5030 } 5040 }
5031 $next_section = true; 5041 $next_section = true;
5032 5042
5033 } elsif ($varcanon ne $vars->[$varindex]->[0]) { 5043 } elsif ($varcanon ne $vars->[$varindex]->[0]) {
5034 $line->log_warning("Expected " . $vars->[$varindex]->[0] . ", but found " . $varcanon . "."); 5044 $line->log_warning("Expected " . $vars->[$varindex]->[0] . ", but found " . $varcanon . ".");
5035 $lineno++; 5045 $lineno++;
5036 5046
5037 } else { 5047 } else {
5038 if ($vars->[$varindex]->[1] != many) { 5048 if ($vars->[$varindex]->[1] != many) {
5039 $below->{$vars->[$varindex]->[0]} = $below_what; 5049 $below->{$vars->[$varindex]->[0]} = $below_what;
5040 $varindex++; 5050 $varindex++;
5041 } 5051 }
5042 $lineno++; 5052 $lineno++;
5043 } 5053 }
5044 $below_what = $varcanon; 5054 $below_what = $varcanon;
5045 5055
5046 } else { 5056 } else {
5047 while ($varindex <= $#{$vars}) { 5057 while ($varindex <= $#{$vars}) {
5048 if ($vars->[$varindex]->[1] == once && !$may_skip_section) { 5058 if ($vars->[$varindex]->[1] == once && !$may_skip_section) {
5049 $line->log_warning($vars->[$varindex]->[0] . " should be set here."); 5059 $line->log_warning($vars->[$varindex]->[0] . " should be set here.");
5050 } 5060 }
5051 $below->{$vars->[$varindex]->[0]} = $below_what; 5061 $below->{$vars->[$varindex]->[0]} = $below_what;
5052 $varindex++; 5062 $varindex++;
5053 } 5063 }
5054 $next_section = true; 5064 $next_section = true;
5055 if ($text eq "") { 5065 if ($text eq "") {
5056 $below_what = "the previous empty line"; 5066 $below_what = "the previous empty line";
5057 $lineno++; 5067 $lineno++;
5058 } 5068 }
5059 } 5069 }
5060 } 5070 }
5061} 5071}
5062 5072
5063sub checklines_mk($) { 5073sub checklines_mk($) {
5064 my ($lines) = @_; 5074 my ($lines) = @_;
5065 my ($allowed_targets) = ({}); 5075 my ($allowed_targets) = ({});
5066 my ($substcontext) = PkgLint::SubstContext->new(); 5076 my ($substcontext) = PkgLint::SubstContext->new();
5067 5077
5068 assert(@{$lines} != 0, "checklines_mk may only be called with non-empty lines."); 5078 assert(@{$lines} != 0, "checklines_mk may only be called with non-empty lines.");
5069 $opt_debug_trace and log_debug($lines->[0]->fname, NO_LINES, "checklines_mk()"); 5079 $opt_debug_trace and log_debug($lines->[0]->fname, NO_LINES, "checklines_mk()");
5070 5080
5071 # Define global variables for the Makefile context. 5081 # Define global variables for the Makefile context.
5072 $mkctx_indentations = [0]; 5082 $mkctx_indentations = [0];
5073 $mkctx_target = undef; 5083 $mkctx_target = undef;
5074 $mkctx_for_variables = {}; 5084 $mkctx_for_variables = {};
5075 $mkctx_vardef = {}; 5085 $mkctx_vardef = {};
5076 $mkctx_build_defs = {}; 5086 $mkctx_build_defs = {};
5077 $mkctx_plist_vars = {}; 5087 $mkctx_plist_vars = {};
5078 $mkctx_tools = {%{get_predefined_tool_names()}}; 5088 $mkctx_tools = {%{get_predefined_tool_names()}};
5079 $mkctx_varuse = {}; 5089 $mkctx_varuse = {};
5080 5090
5081 determine_used_variables($lines); 5091 determine_used_variables($lines);
5082 5092
5083 foreach my $prefix (qw(pre do post)) { 5093 foreach my $prefix (qw(pre do post)) {
5084 foreach my $action (qw(fetch extract patch tools wrapper configure build test install package clean)) { 5094 foreach my $action (qw(fetch extract patch tools wrapper configure build test install package clean)) {
5085 $allowed_targets->{"${prefix}-${action}"} = true; 5095 $allowed_targets->{"${prefix}-${action}"} = true;
5086 } 5096 }
5087 } 5097 }
5088 5098
5089 # 5099 #
5090 # In the first pass, all additions to BUILD_DEFS and USE_TOOLS 5100 # In the first pass, all additions to BUILD_DEFS and USE_TOOLS
5091 # are collected to make the order of the definitions irrelevant. 5101 # are collected to make the order of the definitions irrelevant.
5092 # 5102 #
5093 5103
5094 foreach my $line (@{$lines}) { 5104 foreach my $line (@{$lines}) {
5095 next unless $line->has("is_varassign"); 5105 next unless $line->has("is_varassign");
5096 my $varcanon = $line->get("varcanon"); 5106 my $varcanon = $line->get("varcanon");
5097 5107
5098 if ($varcanon eq "BUILD_DEFS" || $varcanon eq "PKG_GROUPS_VARS" || $varcanon eq "PKG_USERS_VARS") { 5108 if ($varcanon eq "BUILD_DEFS" || $varcanon eq "PKG_GROUPS_VARS" || $varcanon eq "PKG_USERS_VARS") {
5099 foreach my $varname (split(qr"\s+", $line->get("value"))) { 5109 foreach my $varname (split(qr"\s+", $line->get("value"))) {
5100 $mkctx_build_defs->{$varname} = true; 5110 $mkctx_build_defs->{$varname} = true;
5101 $opt_debug_misc and $line->log_debug("${varname} is added to BUILD_DEFS."); 5111 $opt_debug_misc and $line->log_debug("${varname} is added to BUILD_DEFS.");
5102 } 5112 }
5103 5113
5104 } elsif ($varcanon eq "PLIST_VARS") { 5114 } elsif ($varcanon eq "PLIST_VARS") {
5105 foreach my $id (split(qr"\s+", $line->get("value"))) { 5115 foreach my $id (split(qr"\s+", $line->get("value"))) {
5106 $mkctx_plist_vars->{"PLIST.$id"} = true; 5116 $mkctx_plist_vars->{"PLIST.$id"} = true;
5107 $opt_debug_misc and $line->log_debug("PLIST.${id} is added to PLIST_VARS."); 5117 $opt_debug_misc and $line->log_debug("PLIST.${id} is added to PLIST_VARS.");
5108 use_var($line, "PLIST.$id"); 5118 use_var($line, "PLIST.$id");
5109 } 5119 }
5110 5120
5111 } elsif ($varcanon eq "USE_TOOLS") { 5121 } elsif ($varcanon eq "USE_TOOLS") {
5112 foreach my $tool (split(qr"\s+", $line->get("value"))) { 5122 foreach my $tool (split(qr"\s+", $line->get("value"))) {
5113 $mkctx_tools->{$tool} = true; 5123 $mkctx_tools->{$tool} = true;
5114 $opt_debug_misc and $line->log_debug("${tool} is added to USE_TOOLS."); 5124 $opt_debug_misc and $line->log_debug("${tool} is added to USE_TOOLS.");
5115 } 5125 }
5116 5126
5117 } elsif ($varcanon eq "SUBST_VARS.*") { 5127 } elsif ($varcanon eq "SUBST_VARS.*") {
5118 foreach my $svar (split(/\s+/, $line->get("value"))) { 5128 foreach my $svar (split(/\s+/, $line->get("value"))) {
5119 use_var($svar, varname_canon($svar)); 5129 use_var($svar, varname_canon($svar));
5120 $opt_debug_misc and $line->log_debug("varuse $svar"); 5130 $opt_debug_misc and $line->log_debug("varuse $svar");
5121 } 5131 }
5122 5132
5123 } elsif ($varcanon eq "OPSYSVARS") { 5133 } elsif ($varcanon eq "OPSYSVARS") {
5124 foreach my $osvar (split(/\s+/, $line->get("value"))) { 5134 foreach my $osvar (split(/\s+/, $line->get("value"))) {
5125 use_var($line, "$osvar.*"); 5135 use_var($line, "$osvar.*");
5126 def_var($line, $osvar); 5136 def_var($line, $osvar);
5127 } 5137 }
5128 } 5138 }
5129 } 5139 }
5130 5140
5131 # 5141 #
5132 # In the second pass, all "normal" checks are done. 5142 # In the second pass, all "normal" checks are done.
5133 # 5143 #
5134 5144
5135 if (0 <= $#{$lines}) { 5145 if (0 <= $#{$lines}) {
5136 checkline_rcsid_regex($lines->[0], qr"^#\s+", "# "); 5146 checkline_rcsid_regex($lines->[0], qr"^#\s+", "# ");
5137 } 5147 }
5138 5148
5139 foreach my $line (@{$lines}) { 5149 foreach my $line (@{$lines}) {
5140 my $text = $line->text; 5150 my $text = $line->text;
5141 5151
5142 checkline_trailing_whitespace($line); 5152 checkline_trailing_whitespace($line);
5143 checkline_spellcheck($line); 5153 checkline_spellcheck($line);
5144 5154
5145 if ($line->has("is_empty")) { 5155 if ($line->has("is_empty")) {
5146 $substcontext->check_end($line); 5156 $substcontext->check_end($line);
5147 5157
5148 } elsif ($line->has("is_comment")) { 5158 } elsif ($line->has("is_comment")) {
5149 # No further checks. 5159 # No further checks.
5150 5160
5151 } elsif ($text =~ regex_varassign) { 5161 } elsif ($text =~ regex_varassign) {
5152 my ($varname, $op, undef, $comment) = ($1, $2, $3, $4); 5162 my ($varname, $op, undef, $comment) = ($1, $2, $3, $4);
5153 my $space1 = substr($text, $+[1], $-[2] - $+[1]); 5163 my $space1 = substr($text, $+[1], $-[2] - $+[1]);
5154 my $align = substr($text, $+[2], $-[3] - $+[2]); 5164 my $align = substr($text, $+[2], $-[3] - $+[2]);
5155 my $value = $line->get("value"); 5165 my $value = $line->get("value");
5156 5166
5157 if ($align !~ m"^(\t*|[ ])$") { 5167 if ($align !~ m"^(\t*|[ ])$") {
5158 $opt_warn_space && $line->log_note("Alignment of variable values should be done with tabs, not spaces."); 5168 $opt_warn_space && $line->log_note("Alignment of variable values should be done with tabs, not spaces.");
5159 my $prefix = "${varname}${space1}${op}"; 5169 my $prefix = "${varname}${space1}${op}";
5160 my $aligned_len = tablen("${prefix}${align}"); 5170 my $aligned_len = tablen("${prefix}${align}");
5161 if ($aligned_len % 8 == 0) { 5171 if ($aligned_len % 8 == 0) {
5162 my $tabalign = ("\t" x (($aligned_len - tablen($prefix) + 7) / 8)); 5172 my $tabalign = ("\t" x (($aligned_len - tablen($prefix) + 7) / 8));
5163 $line->replace("${prefix}${align}", "${prefix}${tabalign}"); 5173 $line->replace("${prefix}${align}", "${prefix}${tabalign}");
5164 } 5174 }
5165 } 5175 }
5166 checkline_mk_varassign($line, $varname, $op, $value, $comment); 5176 checkline_mk_varassign($line, $varname, $op, $value, $comment);
5167 $substcontext->check_varassign($line, $varname, $op, $value); 5177 $substcontext->check_varassign($line, $varname, $op, $value);
5168 5178
5169 } elsif ($text =~ regex_mk_shellcmd) { 5179 } elsif ($text =~ regex_mk_shellcmd) {
5170 my ($shellcmd) = ($1); 5180 my ($shellcmd) = ($1);
5171 checkline_mk_shellcmd($line, $shellcmd); 5181 checkline_mk_shellcmd($line, $shellcmd);
5172 5182
5173 } elsif ($text =~ regex_mk_include) { 5183 } elsif ($text =~ regex_mk_include) {
5174 my ($include, $includefile) = ($1, $2); 5184 my ($include, $includefile) = ($1, $2);
5175 5185
5176 $opt_debug_include and $line->log_debug("includefile=${includefile}"); 5186 $opt_debug_include and $line->log_debug("includefile=${includefile}");
5177 checkline_relative_path($line, $includefile, $include eq "include"); 5187 checkline_relative_path($line, $includefile, $include eq "include");
5178 5188
5179 if ($includefile =~ m"../Makefile$") { 5189 if ($includefile =~ m"../Makefile$") {
5180 $line->log_error("Other Makefiles must not be included directly."); 5190 $line->log_error("Other Makefiles must not be included directly.");
5181 $line->explain_warning( 5191 $line->explain_warning(
5182"If you want to include portions of another Makefile, extract", 5192"If you want to include portions of another Makefile, extract",
5183"the common parts and put them into a Makefile.common. After", 5193"the common parts and put them into a Makefile.common. After",
5184"that, both this one and the other package should include the", 5194"that, both this one and the other package should include the",
5185"Makefile.common."); 5195"Makefile.common.");
5186 } 5196 }
5187 5197
5188 if ($includefile eq "../../mk/bsd.prefs.mk") { 5198 if ($includefile eq "../../mk/bsd.prefs.mk") {
5189 if ($line->fname =~ m"buildlink3\.mk$") { 5199 if ($line->fname =~ m"buildlink3\.mk$") {
5190 $line->log_note("For efficiency reasons, please include bsd.fast.prefs.mk instead of bsd.prefs.mk."); 5200 $line->log_note("For efficiency reasons, please include bsd.fast.prefs.mk instead of bsd.prefs.mk.");
5191 } 5201 }
5192 $seen_bsd_prefs_mk = true; 5202 $seen_bsd_prefs_mk = true;
5193 } elsif ($includefile eq "../../mk/bsd.fast.prefs.mk") { 5203 } elsif ($includefile eq "../../mk/bsd.fast.prefs.mk") {
5194 $seen_bsd_prefs_mk = true; 5204 $seen_bsd_prefs_mk = true;
5195 } 5205 }
5196 5206
5197 if ($includefile =~ m"/x11-links/buildlink3\.mk$") { 5207 if ($includefile =~ m"/x11-links/buildlink3\.mk$") {
5198 $line->log_error("${includefile} must not be included directly. Include \"../../mk/x11.buildlink3.mk\" instead."); 5208 $line->log_error("${includefile} must not be included directly. Include \"../../mk/x11.buildlink3.mk\" instead.");
5199 } 5209 }
5200 if ($includefile =~ m"/giflib/buildlink3\.mk$") { 5210 if ($includefile =~ m"/giflib/buildlink3\.mk$") {
5201 $line->log_error("${includefile} must not be included directly. Include \"../../mk/giflib.buildlink3.mk\" instead."); 5211 $line->log_error("${includefile} must not be included directly. Include \"../../mk/giflib.buildlink3.mk\" instead.");
5202 } 5212 }
5203 if ($includefile =~ m"/jpeg/buildlink3\.mk$") { 5213 if ($includefile =~ m"/jpeg/buildlink3\.mk$") {
5204 $line->log_error("${includefile} must not be included directly. Include \"../../mk/jpeg.buildlink3.mk\" instead."); 5214 $line->log_error("${includefile} must not be included directly. Include \"../../mk/jpeg.buildlink3.mk\" instead.");
5205 } 5215 }
5206 if ($includefile =~ m"/libungif/buildlink3\.mk$") { 5216 if ($includefile =~ m"/libungif/buildlink3\.mk$") {
5207 $line->log_error("${includefile} must not be included directly. Include \"../../mk/giflib.buildlink3.mk\" instead."); 5217 $line->log_error("${includefile} must not be included directly. Include \"../../mk/giflib.buildlink3.mk\" instead.");
5208 } 5218 }
5209 if ($includefile =~ m"/intltool/buildlink3\.mk$") { 5219 if ($includefile =~ m"/intltool/buildlink3\.mk$") {
5210 $line->log_warning("Please say \"USE_TOOLS+= intltool\" instead of this line."); 5220 $line->log_warning("Please say \"USE_TOOLS+= intltool\" instead of this line.");
5211 } 5221 }
5212 if ($includefile =~ m"(.*)/builtin\.mk$") { 5222 if ($includefile =~ m"(.*)/builtin\.mk$") {
5213 my ($dir) = ($1); 5223 my ($dir) = ($1);
5214 $line->log_error("${includefile} must not be included directly. Include \"${dir}/buildlink3.mk\" instead."); 5224 $line->log_error("${includefile} must not be included directly. Include \"${dir}/buildlink3.mk\" instead.");
5215 } 5225 }
5216 5226
5217 } elsif ($text =~ regex_mk_sysinclude) { 5227 } elsif ($text =~ regex_mk_sysinclude) {
5218 my ($includefile, $comment) = ($1, $2); 5228 my ($includefile, $comment) = ($1, $2);
5219 5229
5220 # No further action. 5230 # No further action.
5221 5231
5222 } elsif ($text =~ regex_mk_cond) { 5232 } elsif ($text =~ regex_mk_cond) {
5223 my ($indent, $directive, $args, $comment) = ($1, $2, $3, $4); 5233 my ($indent, $directive, $args, $comment) = ($1, $2, $3, $4);
5224 5234
5225 use constant regex_directives_with_args => qr"^(?:if|ifdef|ifndef|elif|for|undef)$"; 5235 use constant regex_directives_with_args => qr"^(?:if|ifdef|ifndef|elif|for|undef)$";
5226 5236
5227 if ($directive =~ m"^(?:endif|endfor|elif|else)$") { 5237 if ($directive =~ m"^(?:endif|endfor|elif|else)$") {
5228 if ($#{$mkctx_indentations} >= 1) { 5238 if ($#{$mkctx_indentations} >= 1) {
5229 pop(@{$mkctx_indentations}); 5239 pop(@{$mkctx_indentations});
5230 } else { 5240 } else {
5231 $line->log_error("Unmatched .${directive}."); 5241 $line->log_error("Unmatched .${directive}.");
5232 } 5242 }
5233 } 5243 }
5234 5244
5235 # Check the indentation 5245 # Check the indentation
5236 if ($indent ne " " x $mkctx_indentations->[-1]) { 5246 if ($indent ne " " x $mkctx_indentations->[-1]) {
5237 $opt_warn_space and $line->log_note("This directive should be indented by ".$mkctx_indentations->[-1]." spaces."); 5247 $opt_warn_space and $line->log_note("This directive should be indented by ".$mkctx_indentations->[-1]." spaces.");
5238 } 5248 }
5239 5249
5240 if ($directive eq "if" && $args =~ m"^!defined\([\w]+_MK\)$") { 5250 if ($directive eq "if" && $args =~ m"^!defined\([\w]+_MK\)$") {
5241 push(@{$mkctx_indentations}, $mkctx_indentations->[-1]); 5251 push(@{$mkctx_indentations}, $mkctx_indentations->[-1]);
5242 5252
5243 } elsif ($directive =~ m"^(?:if|ifdef|ifndef|for|elif|else)$") { 5253 } elsif ($directive =~ m"^(?:if|ifdef|ifndef|for|elif|else)$") {
5244 push(@{$mkctx_indentations}, $mkctx_indentations->[-1] + 2); 5254 push(@{$mkctx_indentations}, $mkctx_indentations->[-1] + 2);
5245 } 5255 }
5246 5256
5247 if ($directive =~ regex_directives_with_args && !defined($args)) { 5257 if ($directive =~ regex_directives_with_args && !defined($args)) {
5248 $line->log_error("\".${directive}\" must be given some arguments."); 5258 $line->log_error("\".${directive}\" must be given some arguments.");
5249 5259
5250 } elsif ($directive !~ regex_directives_with_args && defined($args)) { 5260 } elsif ($directive !~ regex_directives_with_args && defined($args)) {
5251 $line->log_error("\".${directive}\" does not take arguments."); 5261 $line->log_error("\".${directive}\" does not take arguments.");
5252 5262
5253 if ($directive eq "else") { 5263 if ($directive eq "else") {
5254 $line->log_note("If you meant \"else if\", use \".elif\"."); 5264 $line->log_note("If you meant \"else if\", use \".elif\".");
5255 } 5265 }
5256 5266
5257 } elsif ($directive eq "if" || $directive eq "elif") { 5267 } elsif ($directive eq "if" || $directive eq "elif") {
5258 checkline_mk_cond($line, $args); 5268 checkline_mk_cond($line, $args);
5259 5269
5260 } elsif ($directive eq "ifdef" || $directive eq "ifndef") { 5270 } elsif ($directive eq "ifdef" || $directive eq "ifndef") {
5261 if ($args =~ m"\s") { 5271 if ($args =~ m"\s") {
5262 $line->log_error("The \".${directive}\" directive can only handle _one_ argument."); 5272 $line->log_error("The \".${directive}\" directive can only handle _one_ argument.");
5263 } else { 5273 } else {
5264 $line->log_warning("The \".${directive}\" directive is deprecated. Please use \".if " 5274 $line->log_warning("The \".${directive}\" directive is deprecated. Please use \".if "
5265 . (($directive eq "ifdef" ? "" : "!")) 5275 . (($directive eq "ifdef" ? "" : "!"))
5266 . "defined(${args})\" instead."); 5276 . "defined(${args})\" instead.");
5267 } 5277 }
5268 5278
5269 } elsif ($directive eq "for") { 5279 } elsif ($directive eq "for") {
5270 if ($args =~ m"^(\S+(?:\s*\S+)*?)\s+in\s+(.*)$") { 5280 if ($args =~ m"^(\S+(?:\s*\S+)*?)\s+in\s+(.*)$") {
5271 my ($vars, $values) = ($1, $2); 5281 my ($vars, $values) = ($1, $2);
5272 5282
5273 foreach my $var (split(qr"\s+", $vars)) { 5283 foreach my $var (split(qr"\s+", $vars)) {
5274 if (!$is_internal && $var =~ m"^_") { 5284 if (!$is_internal && $var =~ m"^_") {
5275 $line->log_warning("Variable names starting with an underscore are reserved for internal pkgsrc use."); 5285 $line->log_warning("Variable names starting with an underscore are reserved for internal pkgsrc use.");
5276 } 5286 }
5277 5287
5278 if ($var =~ m"^[_a-z][_a-z0-9]*$") { 5288 if ($var =~ m"^[_a-z][_a-z0-9]*$") {
5279 # Fine. 5289 # Fine.
5280 } elsif ($var =~ m"[A-Z]") { 5290 } elsif ($var =~ m"[A-Z]") {
5281 $line->log_warning(".for variable names should not contain uppercase letters."); 5291 $line->log_warning(".for variable names should not contain uppercase letters.");
5282 } else { 5292 } else {
5283 $line->log_error("Invalid variable name \"${var}\"."); 5293 $line->log_error("Invalid variable name \"${var}\".");
5284 } 5294 }
5285 5295
5286 $mkctx_for_variables->{$var} = true; 5296 $mkctx_for_variables->{$var} = true;
5287 } 5297 }
5288 5298
5289 # Check if any of the value's types is not guessed. 5299 # Check if any of the value's types is not guessed.
5290 my $guessed = true; 5300 my $guessed = true;
5291 foreach my $value (split(qr"\s+", $values)) { # XXX: too simple 5301 foreach my $value (split(qr"\s+", $values)) { # XXX: too simple
5292 if ($value =~ m"^\$\{(.*)\}") { 5302 if ($value =~ m"^\$\{(.*)\}") {
5293 my $type = get_variable_type($line, $1); 5303 my $type = get_variable_type($line, $1);
5294 if (defined($type) && !$type->is_guessed()) { 5304 if (defined($type) && !$type->is_guessed()) {
5295 $guessed = false; 5305 $guessed = false;
5296 } 5306 }
5297 } 5307 }
5298 } 5308 }
5299 5309
5300 my $for_loop_type = PkgLint::Type->new( 5310 my $for_loop_type = PkgLint::Type->new(
5301 LK_INTERNAL, 5311 LK_INTERNAL,
5302 "Unchecked", 5312 "Unchecked",
5303 [[qr".*", "pu"]], 5313 [[qr".*", "pu"]],
5304 $guessed 5314 $guessed
5305 ); 5315 );
5306 my $for_loop_context = PkgLint::VarUseContext->new( 5316 my $for_loop_context = PkgLint::VarUseContext->new(
5307 VUC_TIME_LOAD, 5317 VUC_TIME_LOAD,
5308 $for_loop_type, 5318 $for_loop_type,
5309 VUC_SHELLWORD_FOR, 5319 VUC_SHELLWORD_FOR,
5310 VUC_EXTENT_WORD 5320 VUC_EXTENT_WORD
5311 ); 5321 );
5312 foreach my $var (@{extract_used_variables($line, $values)}) { 5322 foreach my $var (@{extract_used_variables($line, $values)}) {
5313 checkline_mk_varuse($line, $var, "", $for_loop_context); 5323 checkline_mk_varuse($line, $var, "", $for_loop_context);
5314 } 5324 }
5315 5325
5316 } 5326 }
5317 5327
5318 } elsif ($directive eq "undef" && defined($args)) { 5328 } elsif ($directive eq "undef" && defined($args)) {
5319 foreach my $var (split(qr"\s+", $args)) { 5329 foreach my $var (split(qr"\s+", $args)) {
5320 if (exists($mkctx_for_variables->{$var})) { 5330 if (exists($mkctx_for_variables->{$var})) {
5321 $line->log_note("Using \".undef\" after a \".for\" loop is unnecessary."); 5331 $line->log_note("Using \".undef\" after a \".for\" loop is unnecessary.");
5322 } 5332 }
5323 } 5333 }
5324 } 5334 }
5325 5335
5326 } elsif ($text =~ regex_mk_dependency) { 5336 } elsif ($text =~ regex_mk_dependency) {
5327 my ($targets, $whitespace, $dependencies, $comment) = ($1, $2, $3, $4); 5337 my ($targets, $whitespace, $dependencies, $comment) = ($1, $2, $3, $4);
5328 5338
5329 $opt_debug_misc and $line->log_debug("targets=${targets}, dependencies=${dependencies}"); 5339 $opt_debug_misc and $line->log_debug("targets=${targets}, dependencies=${dependencies}");
5330 $mkctx_target = $targets; 5340 $mkctx_target = $targets;
5331 5341
5332 foreach my $source (split(/\s+/, $dependencies)) { 5342 foreach my $source (split(/\s+/, $dependencies)) {
5333 if ($source eq ".PHONY") { 5343 if ($source eq ".PHONY") {
5334 foreach my $target (split(/\s+/, $targets)) { 5344 foreach my $target (split(/\s+/, $targets)) {
5335 $allowed_targets->{$target} = true; 5345 $allowed_targets->{$target} = true;
5336 } 5346 }
5337 } 5347 }
5338 } 5348 }
5339 5349
5340 foreach my $target (split(/\s+/, $targets)) { 5350 foreach my $target (split(/\s+/, $targets)) {
5341 if ($target eq ".PHONY") { 5351 if ($target eq ".PHONY") {
5342 foreach my $dep (split(qr"\s+", $dependencies)) { 5352 foreach my $dep (split(qr"\s+", $dependencies)) {
5343 $allowed_targets->{$dep} = true; 5353 $allowed_targets->{$dep} = true;
5344 } 5354 }
5345 5355
5346 } elsif ($target eq ".ORDER") { 5356 } elsif ($target eq ".ORDER") {
5347 # TODO: Check for spelling mistakes. 5357 # TODO: Check for spelling mistakes.
5348 5358
5349 } elsif (!exists($allowed_targets->{$target})) { 5359 } elsif (!exists($allowed_targets->{$target})) {
5350 $line->log_warning("Unusual target \"${target}\"."); 5360 $line->log_warning("Unusual target \"${target}\".");
5351 $line->explain_warning( 5361 $line->explain_warning(
5352"If you really want to define your own targets, you can \"declare\"", 5362"If you really want to define your own targets, you can \"declare\"",
5353"them by inserting a \".PHONY: my-target\" line before this line. This", 5363"them by inserting a \".PHONY: my-target\" line before this line. This",
5354"will tell make(1) to not interpret this target's name as a filename."); 5364"will tell make(1) to not interpret this target's name as a filename.");
5355 } 5365 }
5356 } 5366 }
5357 5367
5358 } elsif ($text =~ m"^\.\s*(\S*)") { 5368 } elsif ($text =~ m"^\.\s*(\S*)") {
5359 my ($directive) = ($1); 5369 my ($directive) = ($1);
5360 5370
5361 $line->log_error("Unknown directive \".${directive}\"."); 5371 $line->log_error("Unknown directive \".${directive}\".");
5362 5372
5363 } elsif ($text =~ m"^ ") { 5373 } elsif ($text =~ m"^ ") {
5364 $line->log_warning("Makefile lines should not start with space characters."); 5374 $line->log_warning("Makefile lines should not start with space characters.");
5365 $line->explain_warning( 5375 $line->explain_warning(
5366"If you want this line to contain a shell program, use a tab", 5376"If you want this line to contain a shell program, use a tab",
5367"character for indentation. Otherwise please remove the leading", 5377"character for indentation. Otherwise please remove the leading",
5368"white-space."); 5378"white-space.");
5369 5379
5370 } else { 5380 } else {
5371 $line->log_error("[Internal] Unknown line format: $text"); 5381 $line->log_error("[Internal] Unknown line format: $text");
5372 } 5382 }
5373 } 5383 }
5374 if (@{$lines} > 0) { 5384 if (@{$lines} > 0) {
5375 $substcontext->check_end($lines->[-1]); 5385 $substcontext->check_end($lines->[-1]);
5376 } 5386 }
5377 5387
5378 checklines_trailing_empty_lines($lines); 5388 checklines_trailing_empty_lines($lines);
5379 5389
5380 if ($#{$mkctx_indentations} != 0) { 5390 if ($#{$mkctx_indentations} != 0) {
5381 $lines->[-1]->log_error("Directive indentation is not 0, but ".$mkctx_indentations->[-1]." at EOF."); 5391 $lines->[-1]->log_error("Directive indentation is not 0, but ".$mkctx_indentations->[-1]." at EOF.");
5382 } 5392 }
5383 5393
5384 # Clean up global variables. 5394 # Clean up global variables.
5385 $mkctx_for_variables = undef; 5395 $mkctx_for_variables = undef;
5386 $mkctx_indentations = undef; 5396 $mkctx_indentations = undef;
5387 $mkctx_target = undef; 5397 $mkctx_target = undef;
5388 $mkctx_vardef = undef; 5398 $mkctx_vardef = undef;
5389 $mkctx_build_defs = undef; 5399 $mkctx_build_defs = undef;
5390 $mkctx_plist_vars = undef; 5400 $mkctx_plist_vars = undef;
5391 $mkctx_tools = undef; 5401 $mkctx_tools = undef;
5392 $mkctx_varuse = undef; 5402 $mkctx_varuse = undef;
5393} 5403}
5394 5404
5395sub checklines_buildlink3_inclusion($) { 5405sub checklines_buildlink3_inclusion($) {
5396 my ($lines) = @_; 5406 my ($lines) = @_;
5397 my ($included_files); 5407 my ($included_files);
5398 5408
5399 assert(@{$lines} != 0, "The lines array must be non-empty."); 5409 assert(@{$lines} != 0, "The lines array must be non-empty.");
5400 $opt_debug_trace and log_debug($lines->[0]->fname, NO_LINES, "checklines_buildlink3_inclusion()"); 5410 $opt_debug_trace and log_debug($lines->[0]->fname, NO_LINES, "checklines_buildlink3_inclusion()");
5401 5411
@@ -5935,1615 +5945,1618 @@ sub checkfile_distinfo($) { @@ -5935,1615 +5945,1618 @@ sub checkfile_distinfo($) {
5935 $line->log_error("The ${alg} checksum for ${chksum_fname} differs ..."); 5945 $line->log_error("The ${alg} checksum for ${chksum_fname} differs ...");
5936 $other->[0]->log_error("... from this one."); 5946 $other->[0]->log_error("... from this one.");
5937 } 5947 }
5938 } else { 5948 } else {
5939 $ipc_distinfo->{$alg}->{$chksum_fname} = [$line, $sum]; 5949 $ipc_distinfo->{$alg}->{$chksum_fname} = [$line, $sum];
5940 } 5950 }
5941 } 5951 }
5942 5952
5943 if ($alg eq "MD5") { 5953 if ($alg eq "MD5") {
5944 $line->log_error("MD5 checksums are obsolete."); 5954 $line->log_error("MD5 checksums are obsolete.");
5945 $line->explain_error( 5955 $line->explain_error(
5946"Run \"".conf_make." makedistinfo\" to regenerate the distinfo file."); 5956"Run \"".conf_make." makedistinfo\" to regenerate the distinfo file.");
5947 next; 5957 next;
5948 } 5958 }
5949 5959
5950 if ($state == DIS_SHA1) { 5960 if ($state == DIS_SHA1) {
5951 if ($alg eq "SHA1") { 5961 if ($alg eq "SHA1") {
5952 $state = ($is_patch ? DIS_start : DIS_RMD160); 5962 $state = ($is_patch ? DIS_start : DIS_RMD160);
5953 $current_fname = $chksum_fname; 5963 $current_fname = $chksum_fname;
5954 } else { 5964 } else {
5955 $line->log_warning("Expected an SHA1 checksum."); 5965 $line->log_warning("Expected an SHA1 checksum.");
5956 } 5966 }
5957 5967
5958 } elsif ($state == DIS_RMD160) { 5968 } elsif ($state == DIS_RMD160) {
5959 $state = DIS_start; 5969 $state = DIS_start;
5960 if ($alg eq "RMD160") { 5970 if ($alg eq "RMD160") {
5961 if ($chksum_fname eq $current_fname) { 5971 if ($chksum_fname eq $current_fname) {
5962 $state = DIS_Size; 5972 $state = DIS_Size;
5963 } else { 5973 } else {
5964 $line->log_warning("Expected an RMD160 checksum for ${current_fname}, not for ${chksum_fname}."); 5974 $line->log_warning("Expected an RMD160 checksum for ${current_fname}, not for ${chksum_fname}.");
5965 } 5975 }
5966 } else { 5976 } else {
5967 if ($chksum_fname eq $current_fname) { 5977 if ($chksum_fname eq $current_fname) {
5968 # This is an error because this really should be fixed. 5978 # This is an error because this really should be fixed.
5969 $line->log_error("Expected an RMD160 checksum, not ${alg} for ${chksum_fname}."); 5979 $line->log_error("Expected an RMD160 checksum, not ${alg} for ${chksum_fname}.");
5970 } else { 5980 } else {
5971 $line->log_warning("Expected an RMD160 checksum for ${current_fname}, not ${alg} for ${chksum_fname}."); 5981 $line->log_warning("Expected an RMD160 checksum for ${current_fname}, not ${alg} for ${chksum_fname}.");
5972 } 5982 }
5973 } 5983 }
5974 5984
5975 } elsif ($state == DIS_Size) { 5985 } elsif ($state == DIS_Size) {
5976 $state = DIS_start; 5986 $state = DIS_start;
5977 if ($alg eq "Size") { 5987 if ($alg eq "Size") {
5978 if ($chksum_fname ne $current_fname) { 5988 if ($chksum_fname ne $current_fname) {
5979 $line->log_warning("Expected a Size checksum for ${current_fname}, not for ${chksum_fname}."); 5989 $line->log_warning("Expected a Size checksum for ${current_fname}, not for ${chksum_fname}.");
5980 } 5990 }
5981 } else { 5991 } else {
5982 if ($chksum_fname eq $current_fname) { 5992 if ($chksum_fname eq $current_fname) {
5983 $line->log_warning("Expected a Size checksum, not ${alg} for ${chksum_fname}."); 5993 $line->log_warning("Expected a Size checksum, not ${alg} for ${chksum_fname}.");
5984 } else { 5994 } else {
5985 $line->log_warning("Expected a Size checksum for ${current_fname}, not ${alg} for ${chksum_fname}."); 5995 $line->log_warning("Expected a Size checksum for ${current_fname}, not ${alg} for ${chksum_fname}.");
5986 } 5996 }
5987 } 5997 }
5988 } 5998 }
5989 5999
5990 if ($is_patch && defined($patches_dir) && !(defined($distinfo_file) && $distinfo_file eq "./../../lang/php5/distinfo")) { 6000 if ($is_patch && defined($patches_dir) && !(defined($distinfo_file) && $distinfo_file eq "./../../lang/php5/distinfo")) {
5991 my $fname = "${current_dir}/${patches_dir}/${chksum_fname}"; 6001 my $fname = "${current_dir}/${patches_dir}/${chksum_fname}";
5992 if ($di_is_committed && !is_committed($fname)) { 6002 if ($di_is_committed && !is_committed($fname)) {
5993 $line->log_warning("${patches_dir}/${chksum_fname} is registered in distinfo but not added to CVS."); 6003 $line->log_warning("${patches_dir}/${chksum_fname} is registered in distinfo but not added to CVS.");
5994 } 6004 }
5995 6005
5996 if (open(PATCH, "<", $fname)) { 6006 if (open(PATCH, "<", $fname)) {
5997 my $data = ""; 6007 my $data = "";
5998 foreach my $patchline (<PATCH>) { 6008 foreach my $patchline (<PATCH>) {
5999 $data .= $patchline unless $patchline =~ m"\$[N]etBSD"; 6009 $data .= $patchline unless $patchline =~ m"\$[N]etBSD";
6000 } 6010 }
6001 close(PATCH); 6011 close(PATCH);
6002 my $chksum = Digest::SHA1::sha1_hex($data); 6012 my $chksum = Digest::SHA1::sha1_hex($data);
6003 if ($sum ne $chksum) { 6013 if ($sum ne $chksum) {
6004 $line->log_error("${alg} checksum of ${chksum_fname} differs (expected ${sum}, got ${chksum}). Rerun '".conf_make." makepatchsum'."); 6014 $line->log_error("${alg} checksum of ${chksum_fname} differs (expected ${sum}, got ${chksum}). Rerun '".conf_make." makepatchsum'.");
6005 } 6015 }
6006 } elsif (true) { 6016 } elsif (true) {
6007 $line->log_warning("${chksum_fname} does not exist."); 6017 $line->log_warning("${chksum_fname} does not exist.");
6008 $line->explain_warning( 6018 $line->explain_warning(
6009"All patches that are mentioned in a distinfo file should actually exist.", 6019"All patches that are mentioned in a distinfo file should actually exist.",
6010"What's the use of a checksum if there is no file to check?"); 6020"What's the use of a checksum if there is no file to check?");
6011 } 6021 }
6012 } 6022 }
6013 $in_distinfo{$chksum_fname} = true; 6023 $in_distinfo{$chksum_fname} = true;
6014 } 6024 }
6015 checklines_trailing_empty_lines($lines); 6025 checklines_trailing_empty_lines($lines);
6016 6026
6017 if (defined($patches_dir)) { 6027 if (defined($patches_dir)) {
6018 foreach my $patch (<${current_dir}/${patches_dir}/patch-*>) { 6028 foreach my $patch (<${current_dir}/${patches_dir}/patch-*>) {
6019 $patch = basename($patch); 6029 $patch = basename($patch);
6020 if (!exists($in_distinfo{$patch})) { 6030 if (!exists($in_distinfo{$patch})) {
6021 log_error($fname, NO_LINE_NUMBER, "$patch is not recorded. Rerun '".conf_make." makepatchsum'."); 6031 log_error($fname, NO_LINE_NUMBER, "$patch is not recorded. Rerun '".conf_make." makepatchsum'.");
6022 } 6032 }
6023 } 6033 }
6024 } 6034 }
6025} 6035}
6026 6036
6027sub checkfile_extra($) { 6037sub checkfile_extra($) {
6028 my ($fname) = @_; 6038 my ($fname) = @_;
6029 my ($lines); 6039 my ($lines);
6030 6040
6031 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_extra()"); 6041 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_extra()");
6032 6042
6033 $lines = load_file($fname); 6043 $lines = load_file($fname);
6034 if (!$lines) { 6044 if (!$lines) {
6035 log_error($fname, NO_LINE_NUMBER, "Could not be read."); 6045 log_error($fname, NO_LINE_NUMBER, "Could not be read.");
6036 return; 6046 return;
6037 } 6047 }
6038 checklines_trailing_empty_lines($lines); 6048 checklines_trailing_empty_lines($lines);
6039 checkperms($fname); 6049 checkperms($fname);
6040} 6050}
6041 6051
6042sub checkfile_INSTALL($) { 6052sub checkfile_INSTALL($) {
6043 my ($fname) = @_; 6053 my ($fname) = @_;
6044 my ($lines); 6054 my ($lines);
6045 6055
6046 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_INSTALL()"); 6056 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_INSTALL()");
6047 6057
6048 checkperms($fname); 6058 checkperms($fname);
6049 if (!($lines = load_file($fname))) { 6059 if (!($lines = load_file($fname))) {
6050 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 6060 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
6051 return; 6061 return;
6052 } 6062 }
6053} 6063}
6054 6064
6055sub checkfile_MESSAGE($) { 6065sub checkfile_MESSAGE($) {
6056 my ($fname) = @_; 6066 my ($fname) = @_;
6057 my ($lines); 6067 my ($lines);
6058 6068
6059 my @explanation = ( 6069 my @explanation = (
6060 "A MESSAGE file should consist of a header line, having 75 \"=\"", 6070 "A MESSAGE file should consist of a header line, having 75 \"=\"",
6061 "characters, followed by a line containing only the RCS Id, then an", 6071 "characters, followed by a line containing only the RCS Id, then an",
6062 "empty line, your text and finally the footer line, which is the", 6072 "empty line, your text and finally the footer line, which is the",
6063 "same as the header line."); 6073 "same as the header line.");
6064 6074
6065 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_MESSAGE()"); 6075 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_MESSAGE()");
6066 6076
6067 checkperms($fname); 6077 checkperms($fname);
6068 if (!($lines = load_file($fname))) { 6078 if (!($lines = load_file($fname))) {
6069 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 6079 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
6070 return; 6080 return;
6071 } 6081 }
6072 6082
6073 if (@{$lines} < 3) { 6083 if (@{$lines} < 3) {
6074 log_warning($fname, NO_LINE_NUMBER, "File too short."); 6084 log_warning($fname, NO_LINE_NUMBER, "File too short.");
6075 explain_warning($fname, NO_LINE_NUMBER, @explanation); 6085 explain_warning($fname, NO_LINE_NUMBER, @explanation);
6076 return; 6086 return;
6077 } 6087 }
6078 if ($lines->[0]->text ne "=" x 75) { 6088 if ($lines->[0]->text ne "=" x 75) {
6079 $lines->[0]->log_warning("Expected a line of exactly 75 \"=\" characters."); 6089 $lines->[0]->log_warning("Expected a line of exactly 75 \"=\" characters.");
6080 explain_warning($fname, NO_LINE_NUMBER, @explanation); 6090 explain_warning($fname, NO_LINE_NUMBER, @explanation);
6081 } 6091 }
6082 checkline_rcsid($lines->[1], ""); 6092 checkline_rcsid($lines->[1], "");
6083 foreach my $line (@{$lines}) { 6093 foreach my $line (@{$lines}) {
6084 checkline_length($line, 80); 6094 checkline_length($line, 80);
6085 checkline_trailing_whitespace($line); 6095 checkline_trailing_whitespace($line);
6086 checkline_valid_characters($line, regex_validchars); 6096 checkline_valid_characters($line, regex_validchars);
6087 checkline_spellcheck($line); 6097 checkline_spellcheck($line);
6088 } 6098 }
6089 if ($lines->[-1]->text ne "=" x 75) { 6099 if ($lines->[-1]->text ne "=" x 75) {
6090 $lines->[-1]->log_warning("Expected a line of exactly 75 \"=\" characters."); 6100 $lines->[-1]->log_warning("Expected a line of exactly 75 \"=\" characters.");
6091 explain_warning($fname, NO_LINE_NUMBER, @explanation); 6101 explain_warning($fname, NO_LINE_NUMBER, @explanation);
6092 } 6102 }
6093 checklines_trailing_empty_lines($lines); 6103 checklines_trailing_empty_lines($lines);
6094} 6104}
6095 6105
6096sub checkfile_mk($) { 6106sub checkfile_mk($) {
6097 my ($fname) = @_; 6107 my ($fname) = @_;
6098 my ($lines); 6108 my ($lines);
6099 6109
6100 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_mk()"); 6110 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_mk()");
6101 6111
6102 checkperms($fname); 6112 checkperms($fname);
6103 if (!($lines = load_lines($fname, true))) { 6113 if (!($lines = load_lines($fname, true))) {
6104 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 6114 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
6105 return; 6115 return;
6106 } 6116 }
6107 6117
6108 parselines_mk($lines); 6118 parselines_mk($lines);
6109 checklines_mk($lines); 6119 checklines_mk($lines);
6110 autofix($lines); 6120 autofix($lines);
6111} 6121}
6112 6122
6113sub checkfile_package_Makefile($$) { 6123sub checkfile_package_Makefile($$) {
6114 my ($fname, $lines) = @_; 6124 my ($fname, $lines) = @_;
6115 6125
6116 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_package_Makefile(..., ...)"); 6126 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_package_Makefile(..., ...)");
6117 6127
6118 checkperms($fname); 6128 checkperms($fname);
6119 6129
6120 if (!exists($pkgctx_vardef->{"PLIST_SRC"}) 6130 if (!exists($pkgctx_vardef->{"PLIST_SRC"})
6121 && !exists($pkgctx_vardef->{"GENERATE_PLIST"}) 6131 && !exists($pkgctx_vardef->{"GENERATE_PLIST"})
6122 && !exists($pkgctx_vardef->{"META_PACKAGE"}) 6132 && !exists($pkgctx_vardef->{"META_PACKAGE"})
6123 && defined($pkgdir) 6133 && defined($pkgdir)
6124 && !-f "${current_dir}/$pkgdir/PLIST" 6134 && !-f "${current_dir}/$pkgdir/PLIST"
6125 && !-f "${current_dir}/$pkgdir/PLIST.common") { 6135 && !-f "${current_dir}/$pkgdir/PLIST.common") {
6126 log_warning($fname, NO_LINE_NUMBER, "Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?"); 6136 log_warning($fname, NO_LINE_NUMBER, "Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?");
6127 } 6137 }
6128 6138
6129 if ((exists($pkgctx_vardef->{"NO_CHECKSUM"}) || $pkgctx_vardef->{"META_PACKAGE"}) && is_emptydir("${current_dir}/${patchdir}")) { 6139 if ((exists($pkgctx_vardef->{"NO_CHECKSUM"}) || $pkgctx_vardef->{"META_PACKAGE"}) && is_emptydir("${current_dir}/${patchdir}")) {
6130 if (-f "${current_dir}/${distinfo_file}") { 6140 if (-f "${current_dir}/${distinfo_file}") {
6131 log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "This file should not exist if NO_CHECKSUM or META_PACKAGE is set."); 6141 log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "This file should not exist if NO_CHECKSUM or META_PACKAGE is set.");
6132 } 6142 }
6133 } else { 6143 } else {
6134 if (!-f "${current_dir}/${distinfo_file}") { 6144 if (!-f "${current_dir}/${distinfo_file}") {
6135 log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makesum'."); 6145 log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makesum'.");
6136 } 6146 }
6137 } 6147 }
6138 6148
6139 if (exists($pkgctx_vardef->{"REPLACE_PERL"}) && exists($pkgctx_vardef->{"NO_CONFIGURE"})) { 6149 if (exists($pkgctx_vardef->{"REPLACE_PERL"}) && exists($pkgctx_vardef->{"NO_CONFIGURE"})) {
6140 $pkgctx_vardef->{"REPLACE_PERL"}->log_warning("REPLACE_PERL is ignored when ..."); 6150 $pkgctx_vardef->{"REPLACE_PERL"}->log_warning("REPLACE_PERL is ignored when ...");
6141 $pkgctx_vardef->{"NO_CONFIGURE"}->log_warning("... NO_CONFIGURE is set."); 6151 $pkgctx_vardef->{"NO_CONFIGURE"}->log_warning("... NO_CONFIGURE is set.");
6142 } 6152 }
6143 6153
6144 if (!exists($pkgctx_vardef->{"LICENSE"})) { 6154 if (!exists($pkgctx_vardef->{"LICENSE"})) {
6145 log_error($fname, NO_LINE_NUMBER, "Each package must define its LICENSE."); 6155 log_error($fname, NO_LINE_NUMBER, "Each package must define its LICENSE.");
6146 } 6156 }
6147 6157
6148 if (exists($pkgctx_vardef->{"GNU_CONFIGURE"}) && exists($pkgctx_vardef->{"USE_LANGUAGES"})) { 6158 if (exists($pkgctx_vardef->{"GNU_CONFIGURE"}) && exists($pkgctx_vardef->{"USE_LANGUAGES"})) {
6149 my $languages_line = $pkgctx_vardef->{"USE_LANGUAGES"}; 6159 my $languages_line = $pkgctx_vardef->{"USE_LANGUAGES"};
6150 my $value = $languages_line->get("value"); 6160 my $value = $languages_line->get("value");
6151 6161
6152 if ($languages_line->has("comment") && $languages_line->get("comment") =~ m"\b(?:c|empty|none)\b"i) { 6162 if ($languages_line->has("comment") && $languages_line->get("comment") =~ m"\b(?:c|empty|none)\b"i) {
6153 # Don't emit a warning, since the comment 6163 # Don't emit a warning, since the comment
6154 # probably contains a statement that C is 6164 # probably contains a statement that C is
6155 # really not needed. 6165 # really not needed.
6156 6166
6157 } elsif ($value !~ m"(?:^|\s+)(?:c|c99|objc)(?:\s+|$)") { 6167 } elsif ($value !~ m"(?:^|\s+)(?:c|c99|objc)(?:\s+|$)") {
6158 $pkgctx_vardef->{"GNU_CONFIGURE"}->log_warning("GNU_CONFIGURE almost always needs a C compiler, ..."); 6168 $pkgctx_vardef->{"GNU_CONFIGURE"}->log_warning("GNU_CONFIGURE almost always needs a C compiler, ...");
6159 $languages_line->log_warning("... but \"c\" is not added to USE_LANGUAGES."); 6169 $languages_line->log_warning("... but \"c\" is not added to USE_LANGUAGES.");
6160 } 6170 }
6161 } 6171 }
6162 6172
6163 my $distname_line = $pkgctx_vardef->{"DISTNAME"}; 6173 my $distname_line = $pkgctx_vardef->{"DISTNAME"};
6164 my $pkgname_line = $pkgctx_vardef->{"PKGNAME"}; 6174 my $pkgname_line = $pkgctx_vardef->{"PKGNAME"};
6165 6175
6166 my $distname = defined($distname_line) ? $distname_line->get("value") : undef; 6176 my $distname = defined($distname_line) ? $distname_line->get("value") : undef;
6167 my $pkgname = defined($pkgname_line) ? $pkgname_line->get("value") : undef; 6177 my $pkgname = defined($pkgname_line) ? $pkgname_line->get("value") : undef;
6168 my $nbpart = get_nbpart(); 6178 my $nbpart = get_nbpart();
6169 6179
6170 # Let's do some tricks to get the proper value of the package 6180 # Let's do some tricks to get the proper value of the package
6171 # name more often. 6181 # name more often.
6172 if (defined($distname) && defined($pkgname)) { 6182 if (defined($distname) && defined($pkgname)) {
6173 $pkgname =~ s/\$\{DISTNAME\}/$distname/; 6183 $pkgname =~ s/\$\{DISTNAME\}/$distname/;
6174 6184
6175 if ($pkgname =~ m"^(.*)\$\{DISTNAME:S(.)([^:]*)\2([^:]*)\2(g?)\}(.*)$") { 6185 if ($pkgname =~ m"^(.*)\$\{DISTNAME:S(.)([^:]*)\2([^:]*)\2(g?)\}(.*)$") {
6176 my ($before, $separator, $old, $new, $mod, $after) = ($1, $2, $3, $4, $5, $6); 6186 my ($before, $separator, $old, $new, $mod, $after) = ($1, $2, $3, $4, $5, $6);
6177 my $newname = $distname; 6187 my $newname = $distname;
6178 $old = quotemeta($old); 6188 $old = quotemeta($old);
6179 $old =~ s/^\\\^/^/; 6189 $old =~ s/^\\\^/^/;
6180 $old =~ s/\\\$$/\$/; 6190 $old =~ s/\\\$$/\$/;
6181 if ($mod eq "g") { 6191 if ($mod eq "g") {
6182 $newname =~ s/$old/$new/g; 6192 $newname =~ s/$old/$new/g;
6183 } else { 6193 } else {
6184 $newname =~ s/$old/$new/; 6194 $newname =~ s/$old/$new/;
6185 } 6195 }
6186 $opt_debug_misc and $pkgname_line->log_debug("old pkgname=$pkgname"); 6196 $opt_debug_misc and $pkgname_line->log_debug("old pkgname=$pkgname");
6187 $pkgname = $before . $newname . $after; 6197 $pkgname = $before . $newname . $after;
6188 $opt_debug_misc and $pkgname_line->log_debug("new pkgname=$pkgname"); 6198 $opt_debug_misc and $pkgname_line->log_debug("new pkgname=$pkgname");
6189 } 6199 }
6190 } 6200 }
6191 6201
6192 if (defined($pkgname) && defined($distname) && $pkgname eq $distname) { 6202 if (defined($pkgname) && defined($distname) && $pkgname eq $distname) {
6193 $pkgname_line->log_note("PKGNAME is \${DISTNAME} by default. You probably don't need to define PKGNAME."); 6203 $pkgname_line->log_note("PKGNAME is \${DISTNAME} by default. You probably don't need to define PKGNAME.");
6194 } 6204 }
6195 6205
6196 if (!defined($pkgname) && defined($distname) && $distname !~ regex_unresolved && $distname !~ regex_pkgname) { 6206 if (!defined($pkgname) && defined($distname) && $distname !~ regex_unresolved && $distname !~ regex_pkgname) {
6197 $distname_line->log_warning("As DISTNAME is not a valid package name, please define the PKGNAME explicitly."); 6207 $distname_line->log_warning("As DISTNAME is not a valid package name, please define the PKGNAME explicitly.");
6198 } 6208 }
6199 6209
6200 ($effective_pkgname, $effective_pkgname_line, $effective_pkgbase, $effective_pkgversion) 6210 ($effective_pkgname, $effective_pkgname_line, $effective_pkgbase, $effective_pkgversion)
6201 = (defined($pkgname) && $pkgname !~ regex_unresolved && $pkgname =~ regex_pkgname) ? ($pkgname.$nbpart, $pkgname_line, $1, $2) 6211 = (defined($pkgname) && $pkgname !~ regex_unresolved && $pkgname =~ regex_pkgname) ? ($pkgname.$nbpart, $pkgname_line, $1, $2)
6202 : (defined($distname) && $distname !~ regex_unresolved && $distname =~ regex_pkgname) ? ($distname.$nbpart, $distname_line, $1, $2) 6212 : (defined($distname) && $distname !~ regex_unresolved && $distname =~ regex_pkgname) ? ($distname.$nbpart, $distname_line, $1, $2)
6203 : (undef, undef, undef, undef); 6213 : (undef, undef, undef, undef);
6204 if (defined($effective_pkgname_line)) { 6214 if (defined($effective_pkgname_line)) {
6205 $opt_debug_misc and $effective_pkgname_line->log_debug("Effective name=${effective_pkgname} base=${effective_pkgbase} version=${effective_pkgversion}."); 6215 $opt_debug_misc and $effective_pkgname_line->log_debug("Effective name=${effective_pkgname} base=${effective_pkgbase} version=${effective_pkgversion}.");
6206 # XXX: too many false positives 6216 # XXX: too many false positives
6207 if (false && $pkgpath =~ m"/([^/]+)$" && $effective_pkgbase ne $1) { 6217 if (false && $pkgpath =~ m"/([^/]+)$" && $effective_pkgbase ne $1) {
6208 $effective_pkgname_line->log_warning("Mismatch between PKGNAME ($effective_pkgname) and package directory ($1)."); 6218 $effective_pkgname_line->log_warning("Mismatch between PKGNAME ($effective_pkgname) and package directory ($1).");
6209 } 6219 }
6210 } 6220 }
6211 6221
6212 checkpackage_possible_downgrade(); 6222 checkpackage_possible_downgrade();
6213 6223
6214 if (!exists($pkgctx_vardef->{"COMMENT"})) { 6224 if (!exists($pkgctx_vardef->{"COMMENT"})) {
6215 log_warning($fname, NO_LINE_NUMBER, "No COMMENT given."); 6225 log_warning($fname, NO_LINE_NUMBER, "No COMMENT given.");
6216 } 6226 }
6217 6227
6218 if (exists($pkgctx_vardef->{"USE_IMAKE"}) && exists($pkgctx_vardef->{"USE_X11"})) { 6228 if (exists($pkgctx_vardef->{"USE_IMAKE"}) && exists($pkgctx_vardef->{"USE_X11"})) {
6219 $pkgctx_vardef->{"USE_IMAKE"}->log_note("USE_IMAKE makes ..."); 6229 $pkgctx_vardef->{"USE_IMAKE"}->log_note("USE_IMAKE makes ...");
6220 $pkgctx_vardef->{"USE_X11"}->log_note("... USE_X11 superfluous."); 6230 $pkgctx_vardef->{"USE_X11"}->log_note("... USE_X11 superfluous.");
6221 } 6231 }
6222 6232
6223 if (defined($effective_pkgbase)) { 6233 if (defined($effective_pkgbase)) {
6224 6234
6225 foreach my $suggested_update (@{get_suggested_package_updates()}) { 6235 foreach my $suggested_update (@{get_suggested_package_updates()}) {
6226 my ($line, $suggbase, $suggver, $suggcomm) = @{$suggested_update}; 6236 my ($line, $suggbase, $suggver, $suggcomm) = @{$suggested_update};
6227 my $comment = (defined($suggcomm) ? " (${suggcomm})" : ""); 6237 my $comment = (defined($suggcomm) ? " (${suggcomm})" : "");
6228 6238
6229 next unless $effective_pkgbase eq $suggbase; 6239 next unless $effective_pkgbase eq $suggbase;
6230 6240
6231 if (dewey_cmp($effective_pkgversion, "<", $suggver)) { 6241 if (dewey_cmp($effective_pkgversion, "<", $suggver)) {
6232 $effective_pkgname_line->log_warning("This package should be updated to ${suggver}${comment}."); 6242 $effective_pkgname_line->log_warning("This package should be updated to ${suggver}${comment}.");
6233 $effective_pkgname_line->explain_warning( 6243 $effective_pkgname_line->explain_warning(
6234"The wishlist for package updates in doc/TODO mentions that a newer", 6244"The wishlist for package updates in doc/TODO mentions that a newer",
6235"version of this package is available."); 6245"version of this package is available.");
6236 } 6246 }
6237 if (dewey_cmp($effective_pkgversion, "==", $suggver)) { 6247 if (dewey_cmp($effective_pkgversion, "==", $suggver)) {
6238 $effective_pkgname_line->log_note("The update request to ${suggver} from doc/TODO${comment} has been done."); 6248 $effective_pkgname_line->log_note("The update request to ${suggver} from doc/TODO${comment} has been done.");
6239 } 6249 }
6240 if (dewey_cmp($effective_pkgversion, ">", $suggver)) { 6250 if (dewey_cmp($effective_pkgversion, ">", $suggver)) {
6241 $effective_pkgname_line->log_note("This package is newer than the update request to ${suggver}${comment}."); 6251 $effective_pkgname_line->log_note("This package is newer than the update request to ${suggver}${comment}.");
6242 } 6252 }
6243 } 6253 }
6244 } 6254 }
6245 6255
6246 checklines_mk($lines); 6256 checklines_mk($lines);
6247 checklines_package_Makefile_varorder($lines); 6257 checklines_package_Makefile_varorder($lines);
6248 autofix($lines); 6258 autofix($lines);
6249} 6259}
6250 6260
6251sub checkfile_patch($) { 6261sub checkfile_patch($) {
6252 my ($fname) = @_; 6262 my ($fname) = @_;
6253 my ($lines); 6263 my ($lines);
6254 my ($state, $redostate, $nextstate, $dellines, $addlines, $hunks); 6264 my ($state, $redostate, $nextstate, $dellines, $addlines, $hunks);
6255 my ($seen_comment, $current_fname, $current_ftype, $patched_files); 6265 my ($seen_comment, $current_fname, $current_ftype, $patched_files);
6256 my ($leading_context_lines, $trailing_context_lines, $context_scanning_leading); 6266 my ($leading_context_lines, $trailing_context_lines, $context_scanning_leading);
6257 6267
6258 # Abbreviations used: 6268 # Abbreviations used:
6259 # style: [c] = context diff, [u] = unified diff 6269 # style: [c] = context diff, [u] = unified diff
6260 # scope: [f] = file, [h] = hunk, [l] = line 6270 # scope: [f] = file, [h] = hunk, [l] = line
6261 # action: [d] = delete, [m] = modify, [a] = add, [c] = context 6271 # action: [d] = delete, [m] = modify, [a] = add, [c] = context
6262 use constant re_patch_rcsid => qr"^\$.*\$$"; 6272 use constant re_patch_rcsid => qr"^\$.*\$$";
6263 use constant re_patch_text => qr"^(.+)$"; 6273 use constant re_patch_text => qr"^(.+)$";
6264 use constant re_patch_empty => qr"^$"; 6274 use constant re_patch_empty => qr"^$";
6265 use constant re_patch_cfd => qr"^\*\*\*\s(\S+)(.*)$"; 6275 use constant re_patch_cfd => qr"^\*\*\*\s(\S+)(.*)$";
6266 use constant re_patch_cfa => qr"^---\s(\S+)(.*)$"; 6276 use constant re_patch_cfa => qr"^---\s(\S+)(.*)$";
6267 use constant re_patch_ch => qr"^\*{15}(.*)$"; 6277 use constant re_patch_ch => qr"^\*{15}(.*)$";
6268 use constant re_patch_chd => qr"^\*{3}\s(\d+)(?:,(\d+))?\s\*{4}$"; 6278 use constant re_patch_chd => qr"^\*{3}\s(\d+)(?:,(\d+))?\s\*{4}$";
6269 use constant re_patch_cha => qr"^-{3}\s(\d+)(?:,(\d+))?\s-{4}$"; 6279 use constant re_patch_cha => qr"^-{3}\s(\d+)(?:,(\d+))?\s-{4}$";
6270 use constant re_patch_cld => qr"^(?:-\s(.*))?$"; 6280 use constant re_patch_cld => qr"^(?:-\s(.*))?$";
6271 use constant re_patch_clm => qr"^(?:!\s(.*))?$"; 6281 use constant re_patch_clm => qr"^(?:!\s(.*))?$";
6272 use constant re_patch_cla => qr"^(?:\+\s(.*))?$"; 6282 use constant re_patch_cla => qr"^(?:\+\s(.*))?$";
6273 use constant re_patch_clc => qr"^(?:\s\s(.*))?$"; 6283 use constant re_patch_clc => qr"^(?:\s\s(.*))?$";
6274 use constant re_patch_ufd => qr"^---\s(\S+)(?:\s+(.*))?$"; 6284 use constant re_patch_ufd => qr"^---\s(\S+)(?:\s+(.*))?$";
6275 use constant re_patch_ufa => qr"^\+{3}\s(\S+)(?:\s+(.*))?$"; 6285 use constant re_patch_ufa => qr"^\+{3}\s(\S+)(?:\s+(.*))?$";
6276 use constant re_patch_uh => qr"^\@\@\s-(?:(\d+),)?(\d+)\s\+(?:(\d+),)?(\d+)\s\@\@(.*)$"; 6286 use constant re_patch_uh => qr"^\@\@\s-(?:(\d+),)?(\d+)\s\+(?:(\d+),)?(\d+)\s\@\@(.*)$";
6277 use constant re_patch_uld => qr"^-(.*)$"; 6287 use constant re_patch_uld => qr"^-(.*)$";
6278 use constant re_patch_ula => qr"^\+(.*)$"; 6288 use constant re_patch_ula => qr"^\+(.*)$";
6279 use constant re_patch_ulc => qr"^\s(.*)$"; 6289 use constant re_patch_ulc => qr"^\s(.*)$";
6280 use constant re_patch_ulnonl => qr"^\\ No newline at end of file$"; 6290 use constant re_patch_ulnonl => qr"^\\ No newline at end of file$";
6281 6291
6282 use enum qw(:PST_ 6292 use enum qw(:PST_
6283 START CENTER TEXT 6293 START CENTER TEXT
6284 CFA CH CHD CLD0 CLD CLA0 CLA 6294 CFA CH CHD CLD0 CLD CLA0 CLA
6285 UFA UH UL 6295 UFA UH UL
6286 ); 6296 );
6287 6297
6288 my @comment_explanation = ( 6298 my @comment_explanation = (
6289"Each patch must document why it is necessary. If it has been applied", 6299"Each patch must document why it is necessary. If it has been applied",
6290"because of a security issue, a reference to the CVE should be mentioned", 6300"because of a security issue, a reference to the CVE should be mentioned",
6291"as well.", 6301"as well.",
6292"", 6302"",
6293"Since it is our goal to have as few patches as possible, all patches", 6303"Since it is our goal to have as few patches as possible, all patches",
6294"should be sent to the upstream maintainers of the package. After you", 6304"should be sent to the upstream maintainers of the package. After you",
6295"have done so, you should add a reference to the bug report containing", 6305"have done so, you should add a reference to the bug report containing",
6296"the patch."); 6306"the patch.");
6297 6307
6298 my ($line, $m); 6308 my ($line, $m);
6299 6309
6300 my $check_text = sub($) { 6310 my $check_text = sub($) {
6301 my ($text) = @_; 6311 my ($text) = @_;
6302 6312
6303 if ($text =~ m"(\$(Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State|$opt_rcsidstring)(?::[^\$]*)?\$)") { 6313 if ($text =~ m"(\$(Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State|$opt_rcsidstring)(?::[^\$]*)?\$)") {
6304 my ($tag) = ($2); 6314 my ($tag) = ($2);
6305 6315
6306 if ($text =~ re_patch_uh) { 6316 if ($text =~ re_patch_uh) {
6307 $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it."); 6317 $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it.");
6308 $line->set_text($1); 6318 $line->set_text($1);
6309 } else { 6319 } else {
6310 $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it by reducing the number of context lines using pkgdiff or \"diff -U[210]\"."); 6320 $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it by reducing the number of context lines using pkgdiff or \"diff -U[210]\".");
6311 } 6321 }
6312 } 6322 }
6313 }; 6323 };
6314 6324
6315 my $check_contents = sub() { 6325 my $check_contents = sub() {
6316 6326
6317 if ($m->has(1)) { 6327 if ($m->has(1)) {
6318 $check_text->($m->text(1)); 6328 $check_text->($m->text(1));
6319 } 6329 }
6320 }; 6330 };
6321 6331
6322 my $check_added_contents = sub() { 6332 my $check_added_contents = sub() {
6323 my $text; 6333 my $text;
6324 6334
6325 return unless $m->has(1); 6335 return unless $m->has(1);
6326 $text = $m->text(1); 6336 $text = $m->text(1);
6327 checkline_cpp_macro_names($line, $text); 6337 checkline_cpp_macro_names($line, $text);
6328 checkline_spellcheck($line); 6338 checkline_spellcheck($line);
6329 6339
6330 # XXX: This check is not as accurate as the similar one in 6340 # XXX: This check is not as accurate as the similar one in
6331 # checkline_mk_shelltext(). 6341 # checkline_mk_shelltext().
6332 if (defined($current_fname)) { 6342 if (defined($current_fname)) {
6333 if ($current_ftype eq "shell" || $current_ftype eq "make") { 6343 if ($current_ftype eq "shell" || $current_ftype eq "make") {
6334 my ($mm, $rest) = match_all($text, $regex_shellword); 6344 my ($mm, $rest) = match_all($text, $regex_shellword);
6335 6345
6336 foreach my $m (@{$mm}) { 6346 foreach my $m (@{$mm}) {
6337 my $shellword = $m->text(1); 6347 my $shellword = $m->text(1);
6338 6348
6339 if ($shellword =~ m"^#") { 6349 if ($shellword =~ m"^#") {
6340 last; 6350 last;
6341 } 6351 }
6342 checkline_mk_absolute_pathname($line, $shellword); 6352 checkline_mk_absolute_pathname($line, $shellword);
6343 } 6353 }
6344 6354
6345 } elsif ($current_ftype eq "source") { 6355 } elsif ($current_ftype eq "source") {
6346 checkline_source_absolute_pathname($line, $text); 6356 checkline_source_absolute_pathname($line, $text);
6347 6357
6348 } elsif ($current_ftype eq "configure") { 6358 } elsif ($current_ftype eq "configure") {
6349 if ($text =~ m": Avoid regenerating within pkgsrc$") { 6359 if ($text =~ m": Avoid regenerating within pkgsrc$") {
6350 $line->log_error("This code must not be included in patches."); 6360 $line->log_error("This code must not be included in patches.");
6351 $line->explain_error( 6361 $line->explain_error(
6352"It is generated automatically by pkgsrc after the patch phase.", 6362"It is generated automatically by pkgsrc after the patch phase.",
6353"", 6363"",
6354"For more details, look for \"configure-scripts-override\" in", 6364"For more details, look for \"configure-scripts-override\" in",
6355"mk/configure/gnu-configure.mk."); 6365"mk/configure/gnu-configure.mk.");
6356 } 6366 }
6357 6367
6358 } elsif ($current_ftype eq "ignore") { 6368 } elsif ($current_ftype eq "ignore") {
6359 # Ignore it. 6369 # Ignore it.
6360 6370
6361 } else { 6371 } else {
6362 checkline_other_absolute_pathname($line, $text); 6372 checkline_other_absolute_pathname($line, $text);
6363 } 6373 }
6364 } 6374 }
6365 }; 6375 };
6366 6376
6367 my $check_hunk_end = sub($$$) { 6377 my $check_hunk_end = sub($$$) {
6368 my ($deldelta, $adddelta, $newstate) = @_; 6378 my ($deldelta, $adddelta, $newstate) = @_;
6369 6379
6370 if ($deldelta > 0 && $dellines == 0) { 6380 if ($deldelta > 0 && $dellines == 0) {
6371 $redostate = $newstate; 6381 $redostate = $newstate;
6372 if (defined($addlines) && $addlines > 0) { 6382 if (defined($addlines) && $addlines > 0) {
6373 $line->log_error("Expected ${addlines} more lines to be added."); 6383 $line->log_error("Expected ${addlines} more lines to be added.");
6374 } 6384 }
6375 } elsif ($adddelta > 0 && $addlines == 0) { 6385 } elsif ($adddelta > 0 && $addlines == 0) {
6376 $redostate = $newstate; 6386 $redostate = $newstate;
6377 if (defined($dellines) && $dellines > 0) { 6387 if (defined($dellines) && $dellines > 0) {
6378 $line->log_error("Expected ${dellines} more lines to be deleted."); 6388 $line->log_error("Expected ${dellines} more lines to be deleted.");
6379 } 6389 }
6380 } else { 6390 } else {
6381 if (defined($context_scanning_leading)) { 6391 if (defined($context_scanning_leading)) {
6382 if ($deldelta != 0 && $adddelta != 0) { 6392 if ($deldelta != 0 && $adddelta != 0) {
6383 if ($context_scanning_leading) { 6393 if ($context_scanning_leading) {
6384 $leading_context_lines++; 6394 $leading_context_lines++;
6385 } else { 6395 } else {
6386 $trailing_context_lines++; 6396 $trailing_context_lines++;
6387 } 6397 }
6388 } else { 6398 } else {
6389 if ($context_scanning_leading) { 6399 if ($context_scanning_leading) {
6390 $context_scanning_leading = false; 6400 $context_scanning_leading = false;
6391 } else { 6401 } else {
6392 $trailing_context_lines = 0; 6402 $trailing_context_lines = 0;
6393 } 6403 }
6394 } 6404 }
6395 } 6405 }
6396 6406
6397 if ($deldelta != 0) { 6407 if ($deldelta != 0) {
6398 $dellines -= $deldelta; 6408 $dellines -= $deldelta;
6399 } 6409 }
6400 if ($adddelta != 0) { 6410 if ($adddelta != 0) {
6401 $addlines -= $adddelta; 6411 $addlines -= $adddelta;
6402 } 6412 }
6403 if (!((defined($dellines) && $dellines > 0) || 6413 if (!((defined($dellines) && $dellines > 0) ||
6404 (defined($addlines) && $addlines > 0))) { 6414 (defined($addlines) && $addlines > 0))) {
6405 if (defined($context_scanning_leading)) { 6415 if (defined($context_scanning_leading)) {
6406 if ($leading_context_lines != $trailing_context_lines) { 6416 if ($leading_context_lines != $trailing_context_lines) {
6407 $opt_debug_patches and $line->log_warning("The hunk that ends here does not have as many leading (${leading_context_lines}) as trailing (${trailing_context_lines}) lines of context."); 6417 $opt_debug_patches and $line->log_warning("The hunk that ends here does not have as many leading (${leading_context_lines}) as trailing (${trailing_context_lines}) lines of context.");
6408 } 6418 }
6409 } 6419 }
6410 $nextstate = $newstate; 6420 $nextstate = $newstate;
6411 } 6421 }
6412 } 6422 }
6413 }; 6423 };
6414 6424
6415 # @param deldelta 6425 # @param deldelta
6416 # The number of lines that are deleted from the patched file. 6426 # The number of lines that are deleted from the patched file.
6417 # @param adddelta 6427 # @param adddelta
6418 # The number of lines that are added to the patched file. 6428 # The number of lines that are added to the patched file.
6419 # @param newstate 6429 # @param newstate
6420 # The follow-up state when this line is the last line to be 6430 # The follow-up state when this line is the last line to be
6421 # added in this hunk of the patch. 6431 # added in this hunk of the patch.
6422 # 6432 #
6423 my $check_hunk_line = sub($$$) { 6433 my $check_hunk_line = sub($$$) {
6424 my ($deldelta, $adddelta, $newstate) = @_; 6434 my ($deldelta, $adddelta, $newstate) = @_;
6425 6435
6426 $check_contents->(); 6436 $check_contents->();
6427 $check_hunk_end->($deldelta, $adddelta, $newstate); 6437 $check_hunk_end->($deldelta, $adddelta, $newstate);
6428 6438
6429 # If -Wextra is given, the context lines are checked for 6439 # If -Wextra is given, the context lines are checked for
6430 # absolute paths and similar things. If it is not given, 6440 # absolute paths and similar things. If it is not given,
6431 # only those lines that really add something to the patched 6441 # only those lines that really add something to the patched
6432 # file are checked. 6442 # file are checked.
6433 if ($adddelta != 0 && ($deldelta == 0 || $opt_warn_extra)) { 6443 if ($adddelta != 0 && ($deldelta == 0 || $opt_warn_extra)) {
6434 $check_added_contents->(); 6444 $check_added_contents->();
6435 } 6445 }
6436 }; 6446 };
6437 6447
6438 my $transitions = 6448 my $transitions =
6439 # [ from state, regex, to state, action ] 6449 # [ from state, regex, to state, action ]
6440 [ [PST_START, re_patch_rcsid, PST_CENTER, sub() { 6450 [ [PST_START, re_patch_rcsid, PST_CENTER, sub() {
6441 checkline_rcsid($line, ""); 6451 checkline_rcsid($line, "");
6442 }], [PST_START, undef, PST_CENTER, sub() { 6452 }], [PST_START, undef, PST_CENTER, sub() {
6443 checkline_rcsid($line, ""); 6453 checkline_rcsid($line, "");
6444 }], [PST_CENTER, re_patch_empty, PST_TEXT, sub() { 6454 }], [PST_CENTER, re_patch_empty, PST_TEXT, sub() {
6445 # 6455 #
6446 }], [PST_TEXT, re_patch_cfd, PST_CFA, sub() { 6456 }], [PST_TEXT, re_patch_cfd, PST_CFA, sub() {
6447 if (!$seen_comment) { 6457 if (!$seen_comment) {
6448 $line->log_error("Comment expected."); 6458 $line->log_error("Comment expected.");
6449 $line->explain_error(@comment_explanation); 6459 $line->explain_error(@comment_explanation);
6450 } 6460 }
6451 $line->log_warning("Please use unified diffs (diff -u) for patches."); 6461 $line->log_warning("Please use unified diffs (diff -u) for patches.");
6452 }], [PST_TEXT, re_patch_ufd, PST_UFA, sub() { 6462 }], [PST_TEXT, re_patch_ufd, PST_UFA, sub() {
6453 if (!$seen_comment) { 6463 if (!$seen_comment) {
6454 $line->log_error("Comment expected."); 6464 $line->log_error("Comment expected.");
6455 $line->explain_error(@comment_explanation); 6465 $line->explain_error(@comment_explanation);
6456 } 6466 }
6457 }], [PST_TEXT, re_patch_text, PST_TEXT, sub() { 6467 }], [PST_TEXT, re_patch_text, PST_TEXT, sub() {
6458 $seen_comment = true; 6468 $seen_comment = true;
6459 }], [PST_TEXT, re_patch_empty, PST_TEXT, sub() { 6469 }], [PST_TEXT, re_patch_empty, PST_TEXT, sub() {
6460 # 6470 #
6461 }], [PST_TEXT, undef, PST_TEXT, sub() { 6471 }], [PST_TEXT, undef, PST_TEXT, sub() {
6462 # 6472 #
6463 }], [PST_CENTER, re_patch_cfd, PST_CFA, sub() { 6473 }], [PST_CENTER, re_patch_cfd, PST_CFA, sub() {
6464 if ($seen_comment) { 6474 if ($seen_comment) {
6465 $opt_warn_space and $line->log_note("Empty line expected."); 6475 $opt_warn_space and $line->log_note("Empty line expected.");
6466 } else { 6476 } else {
6467 $line->log_error("Comment expected."); 6477 $line->log_error("Comment expected.");
6468 $line->explain_error(@comment_explanation); 6478 $line->explain_error(@comment_explanation);
6469 } 6479 }
6470 $line->log_warning("Please use unified diffs (diff -u) for patches."); 6480 $line->log_warning("Please use unified diffs (diff -u) for patches.");
6471 }], [PST_CENTER, re_patch_ufd, PST_UFA, sub() { 6481 }], [PST_CENTER, re_patch_ufd, PST_UFA, sub() {
6472 if ($seen_comment) { 6482 if ($seen_comment) {
6473 $opt_warn_space and $line->log_note("Empty line expected."); 6483 $opt_warn_space and $line->log_note("Empty line expected.");
6474 } else { 6484 } else {
6475 $line->log_error("Comment expected."); 6485 $line->log_error("Comment expected.");
6476 $line->explain_error(@comment_explanation); 6486 $line->explain_error(@comment_explanation);
6477 } 6487 }
6478 }], [PST_CENTER, undef, PST_TEXT, sub() { 6488 }], [PST_CENTER, undef, PST_TEXT, sub() {
6479 $opt_warn_space and $line->log_note("Empty line expected."); 6489 $opt_warn_space and $line->log_note("Empty line expected.");
6480 }], [PST_CFA, re_patch_cfa, PST_CH, sub() { 6490 }], [PST_CFA, re_patch_cfa, PST_CH, sub() {
6481 $current_fname = $m->text(1); 6491 $current_fname = $m->text(1);
6482 $current_ftype = get_filetype($line, $current_fname); 6492 $current_ftype = get_filetype($line, $current_fname);
6483 $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype"); 6493 $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype");
6484 $patched_files++; 6494 $patched_files++;
6485 $hunks = 0; 6495 $hunks = 0;
6486 }], [PST_CH, re_patch_ch, PST_CHD, sub() { 6496 }], [PST_CH, re_patch_ch, PST_CHD, sub() {
6487 $hunks++; 6497 $hunks++;
6488 }], [PST_CHD, re_patch_chd, PST_CLD0, sub() { 6498 }], [PST_CHD, re_patch_chd, PST_CLD0, sub() {
6489 $dellines = ($m->has(2)) 6499 $dellines = ($m->has(2))
6490 ? (1 + $m->text(2) - $m->text(1)) 6500 ? (1 + $m->text(2) - $m->text(1))
6491 : ($m->text(1)); 6501 : ($m->text(1));
6492 }], [PST_CLD0, re_patch_clc, PST_CLD, sub() { 6502 }], [PST_CLD0, re_patch_clc, PST_CLD, sub() {
6493 $check_hunk_line->(1, 0, PST_CLD0); 6503 $check_hunk_line->(1, 0, PST_CLD0);
6494 }], [PST_CLD0, re_patch_cld, PST_CLD, sub() { 6504 }], [PST_CLD0, re_patch_cld, PST_CLD, sub() {
6495 $check_hunk_line->(1, 0, PST_CLD0); 6505 $check_hunk_line->(1, 0, PST_CLD0);
6496 }], [PST_CLD0, re_patch_clm, PST_CLD, sub() { 6506 }], [PST_CLD0, re_patch_clm, PST_CLD, sub() {
6497 $check_hunk_line->(1, 0, PST_CLD0); 6507 $check_hunk_line->(1, 0, PST_CLD0);
6498 }], [PST_CLD, re_patch_clc, PST_CLD, sub() { 6508 }], [PST_CLD, re_patch_clc, PST_CLD, sub() {
6499 $check_hunk_line->(1, 0, PST_CLD0); 6509 $check_hunk_line->(1, 0, PST_CLD0);
6500 }], [PST_CLD, re_patch_cld, PST_CLD, sub() { 6510 }], [PST_CLD, re_patch_cld, PST_CLD, sub() {
6501 $check_hunk_line->(1, 0, PST_CLD0); 6511 $check_hunk_line->(1, 0, PST_CLD0);
6502 }], [PST_CLD, re_patch_clm, PST_CLD, sub() { 6512 }], [PST_CLD, re_patch_clm, PST_CLD, sub() {
6503 $check_hunk_line->(1, 0, PST_CLD0); 6513 $check_hunk_line->(1, 0, PST_CLD0);
6504 }], [PST_CLD, undef, PST_CLD0, sub() { 6514 }], [PST_CLD, undef, PST_CLD0, sub() {
6505 if ($dellines != 0) { 6515 if ($dellines != 0) {
6506 $line->log_warning("Invalid number of deleted lines (${dellines} missing)."); 6516 $line->log_warning("Invalid number of deleted lines (${dellines} missing).");
6507 } 6517 }
6508 }], [PST_CLD0, re_patch_cha, PST_CLA0, sub() { 6518 }], [PST_CLD0, re_patch_cha, PST_CLA0, sub() {
6509 $dellines = undef; 6519 $dellines = undef;
6510 $addlines = ($m->has(2)) 6520 $addlines = ($m->has(2))
6511 ? (1 + $m->text(2) - $m->text(1)) 6521 ? (1 + $m->text(2) - $m->text(1))
6512 : ($m->text(1)); 6522 : ($m->text(1));
6513 }], [PST_CLA0, re_patch_clc, PST_CLA, sub() { 6523 }], [PST_CLA0, re_patch_clc, PST_CLA, sub() {
6514 $check_hunk_line->(0, 1, PST_CH); 6524 $check_hunk_line->(0, 1, PST_CH);
6515 }], [PST_CLA0, re_patch_clm, PST_CLA, sub() { 6525 }], [PST_CLA0, re_patch_clm, PST_CLA, sub() {
6516 $check_hunk_line->(0, 1, PST_CH); 6526 $check_hunk_line->(0, 1, PST_CH);
6517 }], [PST_CLA0, re_patch_cla, PST_CLA, sub() { 6527 }], [PST_CLA0, re_patch_cla, PST_CLA, sub() {
6518 $check_hunk_line->(0, 1, PST_CH); 6528 $check_hunk_line->(0, 1, PST_CH);
6519 }], [PST_CLA, re_patch_clc, PST_CLA, sub() { 6529 }], [PST_CLA, re_patch_clc, PST_CLA, sub() {
6520 $check_hunk_line->(0, 1, PST_CH); 6530 $check_hunk_line->(0, 1, PST_CH);
6521 }], [PST_CLA, re_patch_clm, PST_CLA, sub() { 6531 }], [PST_CLA, re_patch_clm, PST_CLA, sub() {
6522 $check_hunk_line->(0, 1, PST_CH); 6532 $check_hunk_line->(0, 1, PST_CH);
6523 }], [PST_CLA, re_patch_cla, PST_CLA, sub() { 6533 }], [PST_CLA, re_patch_cla, PST_CLA, sub() {
6524 $check_hunk_line->(0, 1, PST_CH); 6534 $check_hunk_line->(0, 1, PST_CH);
6525 }], [PST_CLA, undef, PST_CLA0, sub() { 6535 }], [PST_CLA, undef, PST_CLA0, sub() {
6526 if ($addlines != 0) { 6536 if ($addlines != 0) {
6527 $line->log_warning("Invalid number of added lines (${addlines} missing)."); 6537 $line->log_warning("Invalid number of added lines (${addlines} missing).");
6528 } 6538 }
6529 }], [PST_CLA0, undef, PST_CH, sub() { 6539 }], [PST_CLA0, undef, PST_CH, sub() {
6530 # 6540 #
6531 }], [PST_CH, undef, PST_TEXT, sub() { 6541 }], [PST_CH, undef, PST_TEXT, sub() {
6532 # 6542 #
6533 }], [PST_UFA, re_patch_ufa, PST_UH, sub() { 6543 }], [PST_UFA, re_patch_ufa, PST_UH, sub() {
6534 $current_fname = $m->text(1); 6544 $current_fname = $m->text(1);
6535 $current_ftype = get_filetype($line, $current_fname); 6545 $current_ftype = get_filetype($line, $current_fname);
6536 $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype"); 6546 $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype");
6537 $patched_files++; 6547 $patched_files++;
6538 $hunks = 0; 6548 $hunks = 0;
6539 }], [PST_UH, re_patch_uh, PST_UL, sub() { 6549 }], [PST_UH, re_patch_uh, PST_UL, sub() {
6540 $dellines = ($m->has(1) ? $m->text(2) : 1); 6550 $dellines = ($m->has(1) ? $m->text(2) : 1);
6541 $addlines = ($m->has(3) ? $m->text(4) : 1); 6551 $addlines = ($m->has(3) ? $m->text(4) : 1);
6542 $check_text->($line->text); 6552 $check_text->($line->text);
6543 if ($line->text =~ m"\r$") { 6553 if ($line->text =~ m"\r$") {
6544 $line->log_error("The hunk header must not end with a CR character."); 6554 $line->log_error("The hunk header must not end with a CR character.");
6545 $line->explain_error( 6555 $line->explain_error(
6546"The MacOS X patch utility cannot handle these."); 6556"The MacOS X patch utility cannot handle these.");
6547 } 6557 }
6548 $hunks++; 6558 $hunks++;
6549 $context_scanning_leading = (($m->has(1) && $m->text(1) ne "1") ? true : undef); 6559 $context_scanning_leading = (($m->has(1) && $m->text(1) ne "1") ? true : undef);
6550 $leading_context_lines = 0; 6560 $leading_context_lines = 0;
6551 $trailing_context_lines = 0; 6561 $trailing_context_lines = 0;
6552 }], [PST_UL, re_patch_uld, PST_UL, sub() { 6562 }], [PST_UL, re_patch_uld, PST_UL, sub() {
6553 $check_hunk_line->(1, 0, PST_UH); 6563 $check_hunk_line->(1, 0, PST_UH);
6554 }], [PST_UL, re_patch_ula, PST_UL, sub() { 6564 }], [PST_UL, re_patch_ula, PST_UL, sub() {
6555 $check_hunk_line->(0, 1, PST_UH); 6565 $check_hunk_line->(0, 1, PST_UH);
6556 }], [PST_UL, re_patch_ulc, PST_UL, sub() { 6566 }], [PST_UL, re_patch_ulc, PST_UL, sub() {
6557 $check_hunk_line->(1, 1, PST_UH); 6567 $check_hunk_line->(1, 1, PST_UH);
6558 }], [PST_UL, re_patch_ulnonl, PST_UL, sub() { 6568 }], [PST_UL, re_patch_ulnonl, PST_UL, sub() {
6559 # 6569 #
6560 }], [PST_UL, re_patch_empty, PST_UL, sub() { 6570 }], [PST_UL, re_patch_empty, PST_UL, sub() {
6561 $opt_warn_space and $line->log_note("Leading white-space missing in hunk."); 6571 $opt_warn_space and $line->log_note("Leading white-space missing in hunk.");
6562 $check_hunk_line->(1, 1, PST_UH); 6572 $check_hunk_line->(1, 1, PST_UH);
6563 }], [PST_UL, undef, PST_UH, sub() { 6573 }], [PST_UL, undef, PST_UH, sub() {
6564 if ($dellines != 0 || $addlines != 0) { 6574 if ($dellines != 0 || $addlines != 0) {
6565 $line->log_warning("Unexpected end of hunk (-${dellines},+${addlines} expected)."); 6575 $line->log_warning("Unexpected end of hunk (-${dellines},+${addlines} expected).");
6566 } 6576 }
6567 }], [PST_UH, undef, PST_TEXT, sub() { 6577 }], [PST_UH, undef, PST_TEXT, sub() {
6568 ($hunks != 0) || $line->log_warning("No hunks for file ${current_fname}."); 6578 ($hunks != 0) || $line->log_warning("No hunks for file ${current_fname}.");
6569 }]]; 6579 }]];
6570 6580
6571 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_patch()"); 6581 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_patch()");
6572 6582
6573 checkperms($fname); 6583 checkperms($fname);
6574 if (!($lines = load_lines($fname, false))) { 6584 if (!($lines = load_lines($fname, false))) {
6575 log_error($fname, NO_LINE_NUMBER, "Could not be read."); 6585 log_error($fname, NO_LINE_NUMBER, "Could not be read.");
6576 return; 6586 return;
6577 } 6587 }
6578 if (@{$lines} == 0) { 6588 if (@{$lines} == 0) {
6579 log_error($fname, NO_LINE_NUMBER, "Must not be empty."); 6589 log_error($fname, NO_LINE_NUMBER, "Must not be empty.");
6580 return; 6590 return;
6581 } 6591 }
6582 6592
6583 $state = PST_START; 6593 $state = PST_START;
6584 $dellines = undef; 6594 $dellines = undef;
6585 $addlines = undef; 6595 $addlines = undef;
6586 $patched_files = 0; 6596 $patched_files = 0;
6587 $seen_comment = false; 6597 $seen_comment = false;
6588 $current_fname = undef; 6598 $current_fname = undef;
6589 $current_ftype = undef; 6599 $current_ftype = undef;
6590 $hunks = undef; 6600 $hunks = undef;
6591 6601
6592 for (my $lineno = 0; $lineno <= $#{$lines}; ) { 6602 for (my $lineno = 0; $lineno <= $#{$lines}; ) {
6593 $line = $lines->[$lineno]; 6603 $line = $lines->[$lineno];
6594 my $text = $line->text; 6604 my $text = $line->text;
6595 6605
6596 $opt_debug_patches and $line->log_debug("[${state} ${patched_files}/".($hunks||0)."/-".($dellines||0)."+".($addlines||0)."] $text"); 6606 $opt_debug_patches and $line->log_debug("[${state} ${patched_files}/".($hunks||0)."/-".($dellines||0)."+".($addlines||0)."] $text");
6597 6607
6598 my $found = false; 6608 my $found = false;
6599 foreach my $t (@{$transitions}) { 6609 foreach my $t (@{$transitions}) {
6600 if ($state == $t->[0]) { 6610 if ($state == $t->[0]) {
6601 if (!defined($t->[1])) { 6611 if (!defined($t->[1])) {
6602 $m = undef; 6612 $m = undef;
6603 } elsif ($text =~ $t->[1]) { 6613 } elsif ($text =~ $t->[1]) {
6604 $opt_debug_patches and $line->log_debug($t->[1]); 6614 $opt_debug_patches and $line->log_debug($t->[1]);
6605 $m = PkgLint::SimpleMatch->new($text, \@-, \@+); 6615 $m = PkgLint::SimpleMatch->new($text, \@-, \@+);
6606 } else { 6616 } else {
6607 next; 6617 next;
6608 } 6618 }
6609 $redostate = undef; 6619 $redostate = undef;
6610 $nextstate = $t->[2]; 6620 $nextstate = $t->[2];
6611 $t->[3]->(); 6621 $t->[3]->();
6612 if (defined($redostate)) { 6622 if (defined($redostate)) {
6613 $state = $redostate; 6623 $state = $redostate;
6614 } else { 6624 } else {
6615 $state = $nextstate; 6625 $state = $nextstate;
6616 if (defined($t->[1])) { 6626 if (defined($t->[1])) {
6617 $lineno++; 6627 $lineno++;
6618 } 6628 }
6619 } 6629 }
6620 $found = true; 6630 $found = true;
6621 last; 6631 last;
6622 } 6632 }
6623 } 6633 }
6624 6634
6625 if (!$found) { 6635 if (!$found) {
6626 $line->log_error("Parse error: state=${state}"); 6636 $line->log_error("Parse error: state=${state}");
6627 $state = PST_TEXT; 6637 $state = PST_TEXT;
6628 $lineno++; 6638 $lineno++;
6629 } 6639 }
6630 } 6640 }
6631 6641
6632 while ($state != PST_TEXT) { 6642 while ($state != PST_TEXT) {
6633 $opt_debug_patches and log_debug($fname, "EOF", "[${state} ${patched_files}/".($hunks||0)."/-".($dellines||0)."+".($addlines||0)."]"); 6643 $opt_debug_patches and log_debug($fname, "EOF", "[${state} ${patched_files}/".($hunks||0)."/-".($dellines||0)."+".($addlines||0)."]");
6634 6644
6635 my $found = false; 6645 my $found = false;
6636 foreach my $t (@{$transitions}) { 6646 foreach my $t (@{$transitions}) {
6637 if ($state == $t->[0] && !defined($t->[1])) { 6647 if ($state == $t->[0] && !defined($t->[1])) {
6638 my $newstate; 6648 my $newstate;
6639 6649
6640 $m = undef; 6650 $m = undef;
6641 $redostate = undef; 6651 $redostate = undef;
6642 $nextstate = $t->[2]; 6652 $nextstate = $t->[2];
6643 $t->[3]->(); 6653 $t->[3]->();
6644 $newstate = (defined($redostate)) ? $redostate : $nextstate; 6654 $newstate = (defined($redostate)) ? $redostate : $nextstate;
6645 if ($newstate == $state) { 6655 if ($newstate == $state) {
6646 log_fatal($fname, "EOF", "Internal error in the patch transition table."); 6656 log_fatal($fname, "EOF", "Internal error in the patch transition table.");
6647 } 6657 }
6648 $state = $newstate; 6658 $state = $newstate;
6649 $found = true; 6659 $found = true;
6650 last; 6660 last;
6651 } 6661 }
6652 } 6662 }
6653 6663
6654 if (!$found) { 6664 if (!$found) {
6655 log_error($fname, "EOF", "Parse error: state=${state}"); 6665 log_error($fname, "EOF", "Parse error: state=${state}");
6656 $state = PST_TEXT; 6666 $state = PST_TEXT;
6657 } 6667 }
6658 } 6668 }
6659 6669
6660 if ($patched_files > 1) { 6670 if ($patched_files > 1) {
6661 log_warning($fname, NO_LINE_NUMBER, "Contains patches for $patched_files files, should be only one."); 6671 log_warning($fname, NO_LINE_NUMBER, "Contains patches for $patched_files files, should be only one.");
6662 6672
6663 } elsif ($patched_files == 0) { 6673 } elsif ($patched_files == 0) {
6664 log_error($fname, NO_LINE_NUMBER, "Contains no patch."); 6674 log_error($fname, NO_LINE_NUMBER, "Contains no patch.");
6665 } 6675 }
6666 6676
6667 checklines_trailing_empty_lines($lines); 6677 checklines_trailing_empty_lines($lines);
6668} 6678}
6669 6679
6670sub checkfile_PLIST($) { 6680sub checkfile_PLIST($) {
6671 my ($fname) = @_; 6681 my ($fname) = @_;
6672 my ($lines, $last_file_seen); 6682 my ($lines, $last_file_seen);
6673 6683
6674 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_PLIST()"); 6684 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile_PLIST()");
6675 6685
6676 checkperms($fname); 6686 checkperms($fname);
6677 if (!($lines = load_file($fname))) { 6687 if (!($lines = load_file($fname))) {
6678 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 6688 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
6679 return; 6689 return;
6680 } 6690 }
6681 if (@{$lines} == 0) { 6691 if (@{$lines} == 0) {
6682 log_error($fname, NO_LINE_NUMBER, "Must not be empty."); 6692 log_error($fname, NO_LINE_NUMBER, "Must not be empty.");
6683 return; 6693 return;
6684 } 6694 }
6685 checkline_rcsid($lines->[0], "\@comment "); 6695 checkline_rcsid($lines->[0], "\@comment ");
6686 6696
6687 if (@$lines == 1) { 6697 if (@$lines == 1) {
6688 $lines->[0]->log_warning("PLIST files shouldn't be empty."); 6698 $lines->[0]->log_warning("PLIST files shouldn't be empty.");
6689 $lines->[0]->explain_warning( 6699 $lines->[0]->explain_warning(
6690"One reason for empty PLISTs is that this is a newly created package", 6700"One reason for empty PLISTs is that this is a newly created package",
6691"and that the author didn't run \"bmake print-PLIST\" after installing", 6701"and that the author didn't run \"bmake print-PLIST\" after installing",
6692"the files.", 6702"the files.",
6693"", 6703"",
6694"Another reason, common for Perl packages, is that the final PLIST is", 6704"Another reason, common for Perl packages, is that the final PLIST is",
6695"automatically generated. Since the source PLIST is not used at all,", 6705"automatically generated. Since the source PLIST is not used at all,",
6696"you can remove it.", 6706"you can remove it.",
6697"", 6707"",
6698"Meta packages also don't need a PLIST file."); 6708"Meta packages also don't need a PLIST file.");
6699 } 6709 }
6700 6710
6701 # Get the list of all files from the PLIST. 6711 # Get the list of all files from the PLIST.
6702 my $all_files = {}; 6712 my $all_files = {};
6703 my $all_dirs = {}; 6713 my $all_dirs = {};
6704 my $extra_lines = []; 6714 my $extra_lines = [];
6705 if (basename($fname) eq "PLIST.common_end") { 6715 if (basename($fname) eq "PLIST.common_end") {
6706 my $common_lines = load_file(dirname($fname) . "/PLIST.common"); 6716 my $common_lines = load_file(dirname($fname) . "/PLIST.common");
6707 if ($common_lines) { 6717 if ($common_lines) {
6708 $extra_lines = $common_lines; 6718 $extra_lines = $common_lines;
6709 } 6719 }
6710 } 6720 }
6711 6721
6712 foreach my $line (@{$extra_lines}, @{$lines}) { 6722 foreach my $line (@{$extra_lines}, @{$lines}) {
6713 my $text = $line->text; 6723 my $text = $line->text;
6714 6724
6715 if ($text =~ m"\$\{([\w_]+)\}(.*)") { 6725 if ($text =~ m"\$\{([\w_]+)\}(.*)") {
6716 if (defined($pkgctx_plist_subst_cond) && exists($pkgctx_plist_subst_cond->{$1})) { 6726 if (defined($pkgctx_plist_subst_cond) && exists($pkgctx_plist_subst_cond->{$1})) {
6717 $opt_debug_misc and $line->log_debug("Removed PLIST_SUBST conditional $1."); 6727 $opt_debug_misc and $line->log_debug("Removed PLIST_SUBST conditional $1.");
6718 $text = $2; 6728 $text = $2;
6719 } 6729 }
6720 } 6730 }
6721  6731
6722 if ($text =~ m"^[\w\$]") { 6732 if ($text =~ m"^[\w\$]") {
6723 $all_files->{$text} = $line; 6733 $all_files->{$text} = $line;
6724 my $dir = $text; 6734 my $dir = $text;
6725 while ($dir =~ s,/[^/]+$,,) { 6735 while ($dir =~ s,/[^/]+$,,) {
6726 $all_dirs->{$dir} = $line; 6736 $all_dirs->{$dir} = $line;
6727 } 6737 }
6728 } 6738 }
6729 if ($text =~ m"^\@exec \$\{MKDIR\} %D/(.*)$") { 6739 if ($text =~ m"^\@exec \$\{MKDIR\} %D/(.*)$") {
6730 my $dir = $1; 6740 my $dir = $1;
6731 do { 6741 do {
6732 $all_dirs->{$dir} = $line; 6742 $all_dirs->{$dir} = $line;
6733 } while ($dir =~ s,/[^/]+$,,); 6743 } while ($dir =~ s,/[^/]+$,,);
6734 } 6744 }
6735 } 6745 }
6736 6746
6737 foreach my $line (@{$lines}) { 6747 foreach my $line (@{$lines}) {
6738 my $text = $line->text; 6748 my $text = $line->text;
6739 6749
6740 if ($text =~ /\s$/) { 6750 if ($text =~ /\s$/) {
6741 $line->log_error("pkgsrc does not support filenames ending in white-space."); 6751 $line->log_error("pkgsrc does not support filenames ending in white-space.");
6742 $line->explain_error( 6752 $line->explain_error(
6743"Each character in the PLIST is relevant, even trailing white-space."); 6753"Each character in the PLIST is relevant, even trailing white-space.");
6744 } 6754 }
6745 6755
6746 # @foo directives. 6756 # @foo directives.
6747 if ($text =~ /^(?:\$\{[\w_]+\})?\@([a-z-]+)\s+(.*)/) { 6757 if ($text =~ /^(?:\$\{[\w_]+\})?\@([a-z-]+)\s+(.*)/) {
6748 my ($cmd, $arg) = ($1, $2); 6758 my ($cmd, $arg) = ($1, $2);
6749 6759
6750 if ($cmd eq "unexec" && $arg =~ m"^(rmdir|\$\{RMDIR\} \%D/)(.*)") { 6760 if ($cmd eq "unexec" && $arg =~ m"^(rmdir|\$\{RMDIR\} \%D/)(.*)") {
6751 my ($rmdir, $rest) = ($1, $2); 6761 my ($rmdir, $rest) = ($1, $2);
6752 if ($rest !~ m"(?:true|\$\{TRUE\})") { 6762 if ($rest !~ m"(?:true|\$\{TRUE\})") {
6753 $line->log_warning("Please remove this line. It is no longer necessary."); 6763 $line->log_warning("Please remove this line. It is no longer necessary.");
6754 } 6764 }
6755 6765
6756 } elsif (($cmd eq "exec" || $cmd eq "unexec")) { 6766 } elsif (($cmd eq "exec" || $cmd eq "unexec")) {
6757 if ($arg =~ /(?:install-info|\$\{INSTALL_INFO\})/) { 6767 if ($arg =~ /(?:install-info|\$\{INSTALL_INFO\})/) {
6758 $line->log_warning("\@exec/unexec install-info is deprecated."); 6768 $line->log_warning("\@exec/unexec install-info is deprecated.");
6759 6769
6760 } elsif ($arg =~ /ldconfig/ && $arg !~ m"/usr/bin/true") { 6770 } elsif ($arg =~ /ldconfig/ && $arg !~ m"/usr/bin/true") {
6761 $line->log_error("ldconfig must be used with \"||/usr/bin/true\"."); 6771 $line->log_error("ldconfig must be used with \"||/usr/bin/true\".");
6762 } 6772 }
6763 6773
6764 } elsif ($cmd eq "comment") { 6774 } elsif ($cmd eq "comment") {
6765 # nothing to do 6775 # nothing to do
6766 6776
6767 } elsif ($cmd eq "dirrm") { 6777 } elsif ($cmd eq "dirrm") {
6768 $line->log_warning("\@dirrm is obsolete. Please remove this line."); 6778 $line->log_warning("\@dirrm is obsolete. Please remove this line.");
6769 $line->explain_warning( 6779 $line->explain_warning(
6770"Directories are removed automatically when they are empty.", 6780"Directories are removed automatically when they are empty.",
6771"When a package needs an empty directory, it can use the \@pkgdir", 6781"When a package needs an empty directory, it can use the \@pkgdir",
6772"command in the PLIST"); 6782"command in the PLIST");
6773 } elsif ($cmd eq "imake-man") { 6783 } elsif ($cmd eq "imake-man") {
6774 my (@args) = split(/\s+/, $arg); 6784 my (@args) = split(/\s+/, $arg);
6775 if (@args != 3) { 6785 if (@args != 3) {
6776 $line->log_warning("Invalid number of arguments for imake-man."); 6786 $line->log_warning("Invalid number of arguments for imake-man.");
6777 } else { 6787 } else {
6778 if ($args[2] eq "\${IMAKE_MANNEWSUFFIX}") { 6788 if ($args[2] eq "\${IMAKE_MANNEWSUFFIX}") {
6779 warn_about_PLIST_imake_mannewsuffix($line); 6789 warn_about_PLIST_imake_mannewsuffix($line);
6780 } 6790 }
6781 } 6791 }
6782 6792
6783 } elsif ($cmd eq "pkgdir") { 6793 } elsif ($cmd eq "pkgdir") {
6784 # TODO: What can we check here? 6794 # TODO: What can we check here?
6785 6795
6786 } else { 6796 } else {
6787 $line->log_warning("Unknown PLIST directive \"\@$cmd\"."); 6797 $line->log_warning("Unknown PLIST directive \"\@$cmd\".");
6788 } 6798 }
6789 6799
6790 # Pathnames. 6800 # Pathnames.
6791 } elsif ($text =~ m"^([A-Za-z0-9\$].*)/([^/]+)$") { 6801 } elsif ($text =~ m"^([A-Za-z0-9\$].*)/([^/]+)$") {
6792 my ($dirname, $basename) = ($1, $2); 6802 my ($dirname, $basename) = ($1, $2);
6793 6803
6794 if ($opt_warn_plist_sort && $text =~ m"^\w" && $text !~ regex_unresolved) { 6804 if ($opt_warn_plist_sort && $text =~ m"^\w" && $text !~ regex_unresolved) {
6795 if (defined($last_file_seen)) { 6805 if (defined($last_file_seen)) {
6796 if ($last_file_seen gt $text) { 6806 if ($last_file_seen gt $text) {
6797 $line->log_warning("${text} should be sorted before ${last_file_seen}."); 6807 $line->log_warning("${text} should be sorted before ${last_file_seen}.");
6798 $line->explain_warning( 6808 $line->explain_warning(
6799"For aesthetic reasons, the files in the PLIST should be sorted", 6809"For aesthetic reasons, the files in the PLIST should be sorted",
6800"alphabetically."); 6810"alphabetically.");
6801 } elsif ($last_file_seen eq $text) { 6811 } elsif ($last_file_seen eq $text) {
6802 $line->log_warning("Duplicate filename."); 6812 $line->log_warning("Duplicate filename.");
6803 } 6813 }
6804 } 6814 }
6805 $last_file_seen = $text; 6815 $last_file_seen = $text;
6806 } 6816 }
6807 6817
6808 if ($basename =~ m"\$\{IMAKE_MANNEWSUFFIX\}") { 6818 if ($basename =~ m"\$\{IMAKE_MANNEWSUFFIX\}") {
6809 warn_about_PLIST_imake_mannewsuffix($line); 6819 warn_about_PLIST_imake_mannewsuffix($line);
6810 } 6820 }
6811 6821
6812 if ($dirname =~ m"^bin/") { 6822 if ($dirname =~ m"^bin/") {
6813 $line->log_warning("The bin/ directory should not have subdirectories."); 6823 $line->log_warning("The bin/ directory should not have subdirectories.");
6814 6824
6815 } elsif ($dirname eq "bin") { 6825 } elsif ($dirname eq "bin") {
6816 6826
6817 if (exists($all_files->{"man/man1/${basename}.1"})) { 6827 if (exists($all_files->{"man/man1/${basename}.1"})) {
6818 # Fine. 6828 # Fine.
6819 } elsif (exists($all_files->{"man/man6/${basename}.6"})) { 6829 } elsif (exists($all_files->{"man/man6/${basename}.6"})) {
6820 # Fine. 6830 # Fine.
6821 } elsif (exists($all_files->{"\${IMAKE_MAN_DIR}/${basename}.\${IMAKE_MANNEWSUFFIX}"})) { 6831 } elsif (exists($all_files->{"\${IMAKE_MAN_DIR}/${basename}.\${IMAKE_MANNEWSUFFIX}"})) {
6822 # Fine. 6832 # Fine.
6823 } else { 6833 } else {
6824 $opt_warn_extra and $line->log_warning("Manual page missing for bin/${basename}."); 6834 $opt_warn_extra and $line->log_warning("Manual page missing for bin/${basename}.");
6825 $opt_warn_extra and $line->explain_warning( 6835 $opt_warn_extra and $line->explain_warning(
6826"All programs that can be run directly by the user should have a manual", 6836"All programs that can be run directly by the user should have a manual",
6827"page for quick reference. The programs in the bin/ directory should have", 6837"page for quick reference. The programs in the bin/ directory should have",
6828"corresponding manual pages in section 1 (filename program.1), not in", 6838"corresponding manual pages in section 1 (filename program.1), not in",
6829"section 8."); 6839"section 8.");
6830 } 6840 }
6831 6841
6832 } elsif ($text =~ m"^doc/") { 6842 } elsif ($text =~ m"^doc/") {
6833 $line->log_error("Documentation must be installed under share/doc, not doc."); 6843 $line->log_error("Documentation must be installed under share/doc, not doc.");
6834 6844
6835 } elsif ($text =~ m"^etc/rc\.d/") { 6845 } elsif ($text =~ m"^etc/rc\.d/") {
6836 $line->log_error("RCD_SCRIPTS must not be registered in the PLIST. Please use the RCD_SCRIPTS framework."); 6846 $line->log_error("RCD_SCRIPTS must not be registered in the PLIST. Please use the RCD_SCRIPTS framework.");
6837 6847
6838 } elsif ($text =~ m"^etc/") { 6848 } elsif ($text =~ m"^etc/") {
6839 my $f = "mk/pkginstall/bsd.pkginstall.mk"; 6849 my $f = "mk/pkginstall/bsd.pkginstall.mk";
6840 6850
6841 assert(-f "${cwd_pkgsrcdir}/${f}", "${cwd_pkgsrcdir}/${f} is not a regular file."); 6851 assert(-f "${cwd_pkgsrcdir}/${f}", "${cwd_pkgsrcdir}/${f} is not a regular file.");
6842 $line->log_error("Configuration files must not be registered in the PLIST. Please use the CONF_FILES framework, which is described in ${f}."); 6852 $line->log_error("Configuration files must not be registered in the PLIST. Please use the CONF_FILES framework, which is described in ${f}.");
6843 6853
6844 } elsif ($text =~ m"^include/.*\.(?:h|hpp)$") { 6854 } elsif ($text =~ m"^include/.*\.(?:h|hpp)$") {
6845 # Fine. 6855 # Fine.
6846 6856
6847 } elsif ($text eq "info/dir") { 6857 } elsif ($text eq "info/dir") {
6848 $line->log_error("\"info/dir\" must not be listed. Use install-info to add/remove an entry."); 6858 $line->log_error("\"info/dir\" must not be listed. Use install-info to add/remove an entry.");
6849 6859
6850 } elsif ($text =~ m"^info/.+$") { 6860 } elsif ($text =~ m"^info/.+$") {
6851 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"INFO_FILES"})) { 6861 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"INFO_FILES"})) {
6852 $line->log_warning("Packages that install info files should set INFO_FILES."); 6862 $line->log_warning("Packages that install info files should set INFO_FILES.");
6853 } 6863 }
6854 6864
6855 } elsif (defined($effective_pkgbase) && $text =~ m"^lib/\Q${effective_pkgbase}\E/") { 6865 } elsif (defined($effective_pkgbase) && $text =~ m"^lib/\Q${effective_pkgbase}\E/") {
6856 # Fine. 6866 # Fine.
6857 6867
6858 } elsif ($text =~ m"^lib/locale/") { 6868 } elsif ($text =~ m"^lib/locale/") {
6859 $line->log_error("\"lib/locale\" must not be listed. Use \${PKGLOCALEDIR}/locale and set USE_PKGLOCALEDIR instead."); 6869 $line->log_error("\"lib/locale\" must not be listed. Use \${PKGLOCALEDIR}/locale and set USE_PKGLOCALEDIR instead.");
6860 6870
6861 } elsif ($text =~ m"^(lib/(?:.*/)*)([^/]+)\.(so|a|la)$") { 6871 } elsif ($text =~ m"^(lib/(?:.*/)*)([^/]+)\.(so|a|la)$") {
6862 my ($dir, $lib, $ext) = ($1, $2, $3); 6872 my ($dir, $lib, $ext) = ($1, $2, $3);
6863 6873
6864 if ($dir eq "lib/" && $lib !~ m"^lib") { 6874 if ($dir eq "lib/" && $lib !~ m"^lib") {
6865 $opt_warn_extra and $line->log_warning("Library filename does not start with \"lib\"."); 6875 $opt_warn_extra and $line->log_warning("Library filename does not start with \"lib\".");
6866 } 6876 }
6867 if ($ext eq "la") { 6877 if ($ext eq "la") {
6868 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"USE_LIBTOOL"})) { 6878 if (defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"USE_LIBTOOL"})) {
6869 $line->log_warning("Packages that install libtool libraries should define USE_LIBTOOL."); 6879 $line->log_warning("Packages that install libtool libraries should define USE_LIBTOOL.");
6870 } 6880 }
6871 } 6881 }
6872 6882
6873 } elsif ($text =~ m"^man/(cat|man)(\w+)/(.*?)\.(\w+)(\.gz)?$") { 6883 } elsif ($text =~ m"^man/(cat|man)(\w+)/(.*?)\.(\w+)(\.gz)?$") {
6874 my ($cat_or_man, $section, $manpage, $ext, $gz) = ($1, $2, $3, $4, $5); 6884 my ($cat_or_man, $section, $manpage, $ext, $gz) = ($1, $2, $3, $4, $5);
6875 6885
6876 if ($section !~ m"^[\dln]$") { 6886 if ($section !~ m"^[\dln]$") {
6877 $line->log_warning("Unknown section \"${section}\" for manual page."); 6887 $line->log_warning("Unknown section \"${section}\" for manual page.");
6878 } 6888 }
6879 6889
6880 if ($cat_or_man eq "cat" && !exists($all_files->{"man/man${section}/${manpage}.${section}"})) { 6890 if ($cat_or_man eq "cat" && !exists($all_files->{"man/man${section}/${manpage}.${section}"})) {
6881 $line->log_warning("Preformatted manual page without unformatted one."); 6891 $line->log_warning("Preformatted manual page without unformatted one.");
6882 } 6892 }
6883 6893
6884 if ($cat_or_man eq "cat") { 6894 if ($cat_or_man eq "cat") {
6885 if ($ext ne "0") { 6895 if ($ext ne "0") {
6886 $line->log_warning("Preformatted manual pages should end in \".0\"."); 6896 $line->log_warning("Preformatted manual pages should end in \".0\".");
6887 } 6897 }
6888 } else { 6898 } else {
6889 if ($section ne $ext) { 6899 if ($section ne $ext) {
6890 $line->log_warning("Mismatch between the section (${section}) and extension (${ext}) of the manual page."); 6900 $line->log_warning("Mismatch between the section (${section}) and extension (${ext}) of the manual page.");
6891 } 6901 }
6892 } 6902 }
6893 6903
6894 if (defined($gz)) { 6904 if (defined($gz)) {
6895 $line->log_note("The .gz extension is unnecessary for manual pages."); 6905 $line->log_note("The .gz extension is unnecessary for manual pages.");
6896 $line->explain_note( 6906 $line->explain_note(
6897"Whether the manual pages are installed in compressed form or not is", 6907"Whether the manual pages are installed in compressed form or not is",
6898"configured by the pkgsrc user. Compression and decompression takes place", 6908"configured by the pkgsrc user. Compression and decompression takes place",
6899"automatically, no matter if the .gz extension is mentioned in the PLIST", 6909"automatically, no matter if the .gz extension is mentioned in the PLIST",
6900"or not."); 6910"or not.");
6901 } 6911 }
6902 6912
6903 } elsif ($text =~ m"^man/cat") { 6913 } elsif ($text =~ m"^man/cat") {
6904 $line->log_warning("Invalid filename \"${text}\" for preformatted manual page."); 6914 $line->log_warning("Invalid filename \"${text}\" for preformatted manual page.");
6905 6915
6906 } elsif ($text =~ m"^man/man") { 6916 } elsif ($text =~ m"^man/man") {
6907 $line->log_warning("Invalid filename \"${text}\" for unformatted manual page."); 6917 $line->log_warning("Invalid filename \"${text}\" for unformatted manual page.");
6908 6918
6909 } elsif ($text =~ m"^sbin/(.*)") { 6919 } elsif ($text =~ m"^sbin/(.*)") {
6910 my ($binname) = ($1); 6920 my ($binname) = ($1);
6911 6921
6912 if (!exists($all_files->{"man/man8/${binname}.8"})) { 6922 if (!exists($all_files->{"man/man8/${binname}.8"})) {
6913 $opt_warn_extra and $line->log_warning("Manual page missing for sbin/${binname}."); 6923 $opt_warn_extra and $line->log_warning("Manual page missing for sbin/${binname}.");
6914 $opt_warn_extra and $line->explain_warning( 6924 $opt_warn_extra and $line->explain_warning(
6915"All programs that can be run directly by the user should have a manual", 6925"All programs that can be run directly by the user should have a manual",
6916"page for quick reference. The programs in the sbin/ directory should have", 6926"page for quick reference. The programs in the sbin/ directory should have",
6917"corresponding manual pages in section 8 (filename program.8), not in", 6927"corresponding manual pages in section 8 (filename program.8), not in",
6918"section 1."); 6928"section 1.");
6919 } 6929 }
6920 6930
6921 } elsif ($text =~ m"^share/applications/.*\.desktop$") { 6931 } elsif ($text =~ m"^share/applications/.*\.desktop$") {
6922 my $f = "../../sysutils/desktop-file-utils/desktopdb.mk"; 6932 my $f = "../../sysutils/desktop-file-utils/desktopdb.mk";
6923 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { 6933 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) {
6924 $line->log_warning("Packages that install a .desktop entry may .include \"$f\"."); 6934 $line->log_warning("Packages that install a .desktop entry may .include \"$f\".");
6925 $line->explain_warning( 6935 $line->explain_warning(
6926"If *.desktop files contain MimeType keys, global MIME Type registory DB", 6936"If *.desktop files contain MimeType keys, global MIME Type registory DB",
6927"must be updated by desktop-file-utils.", 6937"must be updated by desktop-file-utils.",
6928"Otherwise, this warning is harmless."); 6938"Otherwise, this warning is harmless.");
6929 } 6939 }
6930 6940
6931 } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor(?:$|/)") { 6941 } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor(?:$|/)") {
6932 my $f = "../../graphics/hicolor-icon-theme/buildlink3.mk"; 6942 my $f = "../../graphics/hicolor-icon-theme/buildlink3.mk";
6933 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { 6943 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) {
6934 $line->log_error("Please .include \"$f\""); 6944 $line->log_error("Please .include \"$f\" in the Makefile");
6935 $line->explain_error( 6945 $line->explain_error(
6936"If hicolor icon themes are installed, icon theme cache must be maintained."); 6946"If hicolor icon themes are installed, icon theme cache must be",
 6947"maintained. The hicolor-icon-theme package takes care of that.");
6937 } 6948 }
6938 6949
6939 } elsif ($pkgpath ne "graphics/gnome-icon-theme" && $text =~ m"^share/icons/gnome(?:$|/)") { 6950 } elsif ($pkgpath ne "graphics/gnome-icon-theme" && $text =~ m"^share/icons/gnome(?:$|/)") {
6940 my $f = "../../graphics/gnome-icon-theme/buildlink3.mk"; 6951 my $f = "../../graphics/gnome-icon-theme/buildlink3.mk";
6941 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { 6952 if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) {
6942 $line->log_error("Please .include \"$f\""); 6953 $line->log_error("Please .include \"$f\"");
6943 $line->explain_error( 6954 $line->explain_error(
6944"If Gnome icon themes are installed, icon theme cache must be maintained."); 6955"If Gnome icon themes are installed, icon theme cache must be maintained.");
6945 } 6956 }
6946 } elsif ($dirname eq "share/aclocal" && $basename =~ m"\.m4$") { 6957 } elsif ($dirname eq "share/aclocal" && $basename =~ m"\.m4$") {
6947 # Fine. 6958 # Fine.
6948 6959
6949 } elsif ($text =~ m"^share/doc/html/") { 6960 } elsif ($text =~ m"^share/doc/html/") {
6950 $opt_warn_plist_depr and $line->log_warning("Use of \"share/doc/html\" is deprecated. Use \"share/doc/\${PKGBASE}\" instead."); 6961 $opt_warn_plist_depr and $line->log_warning("Use of \"share/doc/html\" is deprecated. Use \"share/doc/\${PKGBASE}\" instead.");
6951 6962
6952 } elsif (defined($effective_pkgbase) && $text =~ m"^share/doc/\Q${effective_pkgbase}\E/") { 6963 } elsif (defined($effective_pkgbase) && $text =~ m"^share/doc/\Q${effective_pkgbase}\E/") {
6953 # Fine. 6964 # Fine.
6954 6965
6955 } elsif (defined($effective_pkgbase) && $text =~ m"^share/examples/\Q${effective_pkgbase}\E/") { 6966 } elsif (defined($effective_pkgbase) && $text =~ m"^share/examples/\Q${effective_pkgbase}\E/") {
6956 # Fine. 6967 # Fine.
6957 6968
6958 } elsif (defined($effective_pkgbase) && $text =~ m"^share/\Q${effective_pkgbase}\E/") { 6969 } elsif (defined($effective_pkgbase) && $text =~ m"^share/\Q${effective_pkgbase}\E/") {
6959 # Fine. 6970 # Fine.
6960 6971
6961 } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor/icon-theme\.cache") { 6972 } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor/icon-theme\.cache") {
6962 $line->log_error("Please .include \"../../graphics/hicolor-icon-theme/buildlink3.mk\" and remove this line."); 6973 $line->log_error("Please .include \"../../graphics/hicolor-icon-theme/buildlink3.mk\" and remove this line.");
6963 6974
6964 } elsif ($text =~ m"^share/info/") { 6975 } elsif ($text =~ m"^share/info/") {
6965 $line->log_warning("Info pages should be installed into info/, not share/info/."); 6976 $line->log_warning("Info pages should be installed into info/, not share/info/.");
6966 $line->explain_warning( 6977 $line->explain_warning(
6967"To fix this, you should add INFO_FILES=yes to the package Makefile."); 6978"To fix this, you should add INFO_FILES=yes to the package Makefile.");
6968 6979
6969 } elsif ($text =~ m"^share/locale/[\w\@_]+/LC_MESSAGES/[^/]+\.mo$") { 6980 } elsif ($text =~ m"^share/locale/[\w\@_]+/LC_MESSAGES/[^/]+\.mo$") {
6970 # Fine. 6981 # Fine.
6971 6982
6972 } elsif ($text =~ m"^share/man/") { 6983 } elsif ($text =~ m"^share/man/") {
6973 $line->log_warning("Man pages should be installed into man/, not share/man/."); 6984 $line->log_warning("Man pages should be installed into man/, not share/man/.");
6974 6985
6975 } else { 6986 } else {
6976 $opt_debug_unchecked and $line->log_debug("Unchecked pathname \"${text}\"."); 6987 $opt_debug_unchecked and $line->log_debug("Unchecked pathname \"${text}\".");
6977 } 6988 }
6978 6989
6979 if ($text =~ /\${PKGLOCALEDIR}/ && defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"USE_PKGLOCALEDIR"})) { 6990 if ($text =~ /\${PKGLOCALEDIR}/ && defined($pkgctx_vardef) && !exists($pkgctx_vardef->{"USE_PKGLOCALEDIR"})) {
6980 $line->log_warning("PLIST contains \${PKGLOCALEDIR}, but USE_PKGLOCALEDIR was not found."); 6991 $line->log_warning("PLIST contains \${PKGLOCALEDIR}, but USE_PKGLOCALEDIR was not found.");
6981 } 6992 }
6982 6993
6983 if ($text =~ m"/CVS/") { 6994 if ($text =~ m"/CVS/") {
6984 $line->log_warning("CVS files should not be in the PLIST."); 6995 $line->log_warning("CVS files should not be in the PLIST.");
6985 } 6996 }
6986 if ($text =~ m"\.orig$") { 6997 if ($text =~ m"\.orig$") {
6987 $line->log_warning(".orig files should not be in the PLIST."); 6998 $line->log_warning(".orig files should not be in the PLIST.");
6988 } 6999 }
6989 if ($text =~ m"/perllocal\.pod$") { 7000 if ($text =~ m"/perllocal\.pod$") {
6990 $line->log_warning("perllocal.pod files should not be in the PLIST."); 7001 $line->log_warning("perllocal.pod files should not be in the PLIST.");
6991 $line->explain_warning( 7002 $line->explain_warning(
6992"This file is handled automatically by the INSTALL/DEINSTALL scripts,", 7003"This file is handled automatically by the INSTALL/DEINSTALL scripts,",
6993"since its contents changes frequently."); 7004"since its contents changes frequently.");
6994 } 7005 }
6995 7006
6996 if ($text =~ m"^(.*)(\.a|\.so[0-9.]*)$") { 7007 if ($text =~ m"^(.*)(\.a|\.so[0-9.]*)$") {
6997 my ($basename, $ext) = ($1, $2); 7008 my ($basename, $ext) = ($1, $2);
6998 7009
6999 if (exists($all_files->{"${basename}.la"})) { 7010 if (exists($all_files->{"${basename}.la"})) {
7000 $line->log_warning("Redundant library found. The libtool library is in line " . $all_files->{"${basename}.la"}->lines . "."); 7011 $line->log_warning("Redundant library found. The libtool library is in line " . $all_files->{"${basename}.la"}->lines . ".");
7001 } 7012 }
7002 } 7013 }
7003 7014
7004 } elsif ($text =~ m"^\$\{[\w_]+\}$") { 7015 } elsif ($text =~ m"^\$\{[\w_]+\}$") {
7005 # A variable on its own line. 7016 # A variable on its own line.
7006 7017
7007 } else { 7018 } else {
7008 $line->log_error("Unknown line type."); 7019 $line->log_error("Unknown line type.");
7009 } 7020 }
7010 } 7021 }
7011 checklines_trailing_empty_lines($lines); 7022 checklines_trailing_empty_lines($lines);
7012 autofix($lines); 7023 autofix($lines);
7013} 7024}
7014 7025
7015sub checkfile($) { 7026sub checkfile($) {
7016 my ($fname) = @_; 7027 my ($fname) = @_;
7017 my ($st, $basename); 7028 my ($st, $basename);
7018 7029
7019 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile()"); 7030 $opt_debug_trace and log_debug($fname, NO_LINES, "checkfile()");
7020 7031
7021 $basename = basename($fname); 7032 $basename = basename($fname);
7022 if ($basename =~ m"^(?:work.*|.*~|.*\.orig|.*\.rej)$") { 7033 if ($basename =~ m"^(?:work.*|.*~|.*\.orig|.*\.rej)$") {
7023 if ($opt_import) { 7034 if ($opt_import) {
7024 log_error($fname, NO_LINE_NUMBER, "Must be cleaned up before committing the package."); 7035 log_error($fname, NO_LINE_NUMBER, "Must be cleaned up before committing the package.");
7025 } 7036 }
7026 return; 7037 return;
7027 } 7038 }
7028 7039
7029 if (!($st = lstat($fname))) { 7040 if (!($st = lstat($fname))) {
7030 log_error($fname, NO_LINE_NUMBER, "$!"); 7041 log_error($fname, NO_LINE_NUMBER, "$!");
7031 return; 7042 return;
7032 } 7043 }
7033 if (S_ISDIR($st->mode)) { 7044 if (S_ISDIR($st->mode)) {
7034 if ($basename eq "files" || $basename eq "patches" || $basename eq "CVS") { 7045 if ($basename eq "files" || $basename eq "patches" || $basename eq "CVS") {
7035 # Ok 7046 # Ok
7036 7047
7037 } elsif (!is_emptydir($fname)) { 7048 } elsif (!is_emptydir($fname)) {
7038 log_warning($fname, NO_LINE_NUMBER, "Unknown directory name."); 7049 log_warning($fname, NO_LINE_NUMBER, "Unknown directory name.");
7039 } 7050 }
7040 7051
7041 } elsif (S_ISLNK($st->mode)) { 7052 } elsif (S_ISLNK($st->mode)) {
7042 if ($basename !~ m"^work") { 7053 if ($basename !~ m"^work") {
7043 log_warning($fname, NO_LINE_NUMBER, "Unknown symlink name."); 7054 log_warning($fname, NO_LINE_NUMBER, "Unknown symlink name.");
7044 } 7055 }
7045 7056
7046 } elsif (!S_ISREG($st->mode)) { 7057 } elsif (!S_ISREG($st->mode)) {
7047 log_error($fname, NO_LINE_NUMBER, "Only files and directories are allowed in pkgsrc."); 7058 log_error($fname, NO_LINE_NUMBER, "Only files and directories are allowed in pkgsrc.");
7048 7059
7049 } elsif ($basename eq "ALTERNATIVES") { 7060 } elsif ($basename eq "ALTERNATIVES") {
7050 $opt_check_ALTERNATIVES and checkfile_ALTERNATIVES($fname); 7061 $opt_check_ALTERNATIVES and checkfile_ALTERNATIVES($fname);
7051 7062
7052 } elsif ($basename eq "buildlink3.mk") { 7063 } elsif ($basename eq "buildlink3.mk") {
7053 $opt_check_bl3 and checkfile_buildlink3_mk($fname); 7064 $opt_check_bl3 and checkfile_buildlink3_mk($fname);
7054 7065
7055 } elsif ($basename =~ m"^DESCR") { 7066 } elsif ($basename =~ m"^DESCR") {
7056 $opt_check_DESCR and checkfile_DESCR($fname); 7067 $opt_check_DESCR and checkfile_DESCR($fname);
7057 7068
7058 } elsif ($basename =~ m"^distinfo") { 7069 } elsif ($basename =~ m"^distinfo") {
7059 $opt_check_distinfo and checkfile_distinfo($fname); 7070 $opt_check_distinfo and checkfile_distinfo($fname);
7060 7071
7061 } elsif ($basename eq "DEINSTALL" || $basename eq "INSTALL") { 7072 } elsif ($basename eq "DEINSTALL" || $basename eq "INSTALL") {
7062 $opt_check_INSTALL and checkfile_INSTALL($fname); 7073 $opt_check_INSTALL and checkfile_INSTALL($fname);
7063 7074
7064 } elsif ($basename =~ m"^MESSAGE") { 7075 } elsif ($basename =~ m"^MESSAGE") {
7065 $opt_check_MESSAGE and checkfile_MESSAGE($fname); 7076 $opt_check_MESSAGE and checkfile_MESSAGE($fname);
7066 7077
7067 } elsif ($basename =~ m"^patch-[-A-Za-z0-9_\.~]*$") { 7078 } elsif ($basename =~ m"^patch-[-A-Za-z0-9_\.~]*$") {
7068 $opt_check_patches and checkfile_patch($fname); 7079 $opt_check_patches and checkfile_patch($fname);
7069 7080
7070 } elsif ($fname =~ m"(?:^|/)patches/manual-[^/]*$") { 7081 } elsif ($fname =~ m"(?:^|/)patches/manual-[^/]*$") {
7071 $opt_debug_unchecked and log_debug($fname, NO_LINE_NUMBER, "Unchecked file \"${fname}\"."); 7082 $opt_debug_unchecked and log_debug($fname, NO_LINE_NUMBER, "Unchecked file \"${fname}\".");
7072 7083
7073 } elsif ($fname =~ m"(?:^|/)patches/[^/]*$") { 7084 } elsif ($fname =~ m"(?:^|/)patches/[^/]*$") {
7074 log_warning($fname, NO_LINE_NUMBER, "Patch files should be named \"patch-\", followed by letters, '-', '_', '.', and digits only."); 7085 log_warning($fname, NO_LINE_NUMBER, "Patch files should be named \"patch-\", followed by letters, '-', '_', '.', and digits only.");
7075 7086
7076 } elsif ($basename =~ m"^(?:.*\.mk|Makefile.*)$" and not $fname =~ m,files/, and not $fname =~ m,patches/,) { 7087 } elsif ($basename =~ m"^(?:.*\.mk|Makefile.*)$" and not $fname =~ m,files/, and not $fname =~ m,patches/,) {
7077 $opt_check_mk and checkfile_mk($fname); 7088 $opt_check_mk and checkfile_mk($fname);
7078 7089
7079 } elsif ($basename =~ m"^PLIST") { 7090 } elsif ($basename =~ m"^PLIST") {
7080 $opt_check_PLIST and checkfile_PLIST($fname); 7091 $opt_check_PLIST and checkfile_PLIST($fname);
7081 7092
7082 } elsif ($basename eq "TODO" || $basename eq "README") { 7093 } elsif ($basename eq "TODO" || $basename eq "README") {
7083 # Ok 7094 # Ok
7084 7095
7085 } elsif ($basename =~ m"^CHANGES-.*") { 7096 } elsif ($basename =~ m"^CHANGES-.*") {
7086 load_doc_CHANGES($fname); 7097 load_doc_CHANGES($fname);
7087 7098
7088 } elsif (!-T $fname) { 7099 } elsif (!-T $fname) {
7089 log_warning($fname, NO_LINE_NUMBER, "Unexpectedly found a binary file."); 7100 log_warning($fname, NO_LINE_NUMBER, "Unexpectedly found a binary file.");
7090 7101
7091 } else { 7102 } else {
7092 log_warning($fname, NO_LINE_NUMBER, "Unexpected file found."); 7103 log_warning($fname, NO_LINE_NUMBER, "Unexpected file found.");
7093 $opt_check_extra and checkfile_extra($fname); 7104 $opt_check_extra and checkfile_extra($fname);
7094 } 7105 }
7095} 7106}
7096 7107
7097sub my_split($$) { 7108sub my_split($$) {
7098 my ($delimiter, $s) = @_; 7109 my ($delimiter, $s) = @_;
7099 my ($pos, $next, @result); 7110 my ($pos, $next, @result);
7100 7111
7101 $pos = 0; 7112 $pos = 0;
7102 for ($pos = 0; $pos != -1; $pos = $next) { 7113 for ($pos = 0; $pos != -1; $pos = $next) {
7103 $next = index($s, $delimiter, $pos); 7114 $next = index($s, $delimiter, $pos);
7104 push @result, (($next == -1) ? substr($s, $pos) : substr($s, $pos, $next - $pos)); 7115 push @result, (($next == -1) ? substr($s, $pos) : substr($s, $pos, $next - $pos));
7105 if ($next != -1) { 7116 if ($next != -1) {
7106 $next += length($delimiter); 7117 $next += length($delimiter);
7107 } 7118 }
7108 } 7119 }
7109 return @result; 7120 return @result;
7110} 7121}
7111 7122
7112# Checks that the files in the directory are in sync with CVS's status. 7123# Checks that the files in the directory are in sync with CVS's status.
7113# 7124#
7114sub checkdir_CVS($) { 7125sub checkdir_CVS($) {
7115 my ($fname) = @_; 7126 my ($fname) = @_;
7116 7127
7117 my $cvs_entries = load_file("$fname/CVS/Entries"); 7128 my $cvs_entries = load_file("$fname/CVS/Entries");
7118 my $cvs_entries_log = load_file("$fname/CVS/Entries.Log"); 7129 my $cvs_entries_log = load_file("$fname/CVS/Entries.Log");
7119 return unless $cvs_entries; 7130 return unless $cvs_entries;
7120 7131
7121 foreach my $line (@$cvs_entries) { 7132 foreach my $line (@$cvs_entries) {
7122 my ($type, $fname, $mtime, $date, $keyword_mode, $tag, $undef) = my_split("/", $line->text); 7133 my ($type, $fname, $mtime, $date, $keyword_mode, $tag, $undef) = my_split("/", $line->text);
7123 next if ($type eq "D" && !defined($fname)); 7134 next if ($type eq "D" && !defined($fname));
7124 assert($type eq "" || $type eq "D", "Unknown line format: " . $line->text); 7135 assert($type eq "" || $type eq "D", "Unknown line format: " . $line->text);
7125 assert(defined($tag), "Unknown line format: " . $line->text); 7136 assert(defined($tag), "Unknown line format: " . $line->text);
7126 assert(defined($keyword_mode), "Unknown line format: " . $line->text); 7137 assert(defined($keyword_mode), "Unknown line format: " . $line->text);
7127 assert(!defined($undef), "Unknown line format: " . $line->text); 7138 assert(!defined($undef), "Unknown line format: " . $line->text);
7128 } 7139 }
7129} 7140}
7130 7141
7131# 7142#
7132# Procedures to check a directory including the files in it. 7143# Procedures to check a directory including the files in it.
7133# 7144#
7134 7145
7135sub checkdir_root() { 7146sub checkdir_root() {
7136 my ($fname) = "${current_dir}/Makefile"; 7147 my ($fname) = "${current_dir}/Makefile";
7137 my ($lines, $prev_subdir, @subdirs); 7148 my ($lines, $prev_subdir, @subdirs);
7138 7149
7139 $opt_debug_trace and log_debug($fname, NO_LINES, "checkdir_root()"); 7150 $opt_debug_trace and log_debug($fname, NO_LINES, "checkdir_root()");
7140 7151
7141 if (!($lines = load_lines($fname, true))) { 7152 if (!($lines = load_lines($fname, true))) {
7142 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 7153 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
7143 return; 7154 return;
7144 } 7155 }
7145 7156
7146 parselines_mk($lines); 7157 parselines_mk($lines);
7147 if (0 <= $#{$lines}) { 7158 if (0 <= $#{$lines}) {
7148 checkline_rcsid_regex($lines->[0], qr"#\s+", "# "); 7159 checkline_rcsid_regex($lines->[0], qr"#\s+", "# ");
7149 } 7160 }
7150 7161
7151 foreach my $line (@{$lines}) { 7162 foreach my $line (@{$lines}) {
7152 if ($line->text =~ m"^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$") { 7163 if ($line->text =~ m"^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$") {
7153 my ($comment_flag, $indentation, $subdir, $comment) = ($1, $2, $3, $4); 7164 my ($comment_flag, $indentation, $subdir, $comment) = ($1, $2, $3, $4);
7154 7165
7155 if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) { 7166 if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) {
7156 $line->log_warning("${subdir} commented out without giving a reason."); 7167 $line->log_warning("${subdir} commented out without giving a reason.");
7157 } 7168 }
7158 7169
7159 if ($indentation ne "\t") { 7170 if ($indentation ne "\t") {
7160 $line->log_warning("Indentation should be a single tab character."); 7171 $line->log_warning("Indentation should be a single tab character.");
7161 } 7172 }
7162 7173
7163 if ($subdir =~ m"\$" || !-f "${current_dir}/${subdir}/Makefile") { 7174 if ($subdir =~ m"\$" || !-f "${current_dir}/${subdir}/Makefile") {
7164 next; 7175 next;
7165 } 7176 }
7166 7177
7167 if (defined($prev_subdir) && $subdir eq $prev_subdir) { 7178 if (!defined($prev_subdir) || $subdir gt $prev_subdir) {
 7179 # correctly ordered
 7180 } elsif ($subdir eq $prev_subdir) {
7168 $line->log_error("${subdir} must only appear once."); 7181 $line->log_error("${subdir} must only appear once.");
7169 } elsif (defined($prev_subdir) && $subdir lt $prev_subdir) { 7182 } elsif ($prev_subdir eq "x11" && $subdir eq "archivers") {
7170 $line->log_warning("${subdir} should come before ${prev_subdir}."); 7183 # ignore that one, since it is documented in the top-level Makefile
7171 } else { 7184 } else {
7172 # correctly ordered 7185 $line->log_warning("${subdir} should come before ${prev_subdir}.");
7173 } 7186 }
7174 7187
7175 $prev_subdir = $subdir; 7188 $prev_subdir = $subdir;
7176 7189
7177 if ($comment_flag eq "") { 7190 if ($comment_flag eq "") {
7178 push(@subdirs, "${current_dir}/${subdir}"); 7191 push(@subdirs, "${current_dir}/${subdir}");
7179 } 7192 }
7180 } 7193 }
7181 } 7194 }
7182 7195
7183 checklines_mk($lines); 7196 checklines_mk($lines);
7184 7197
7185 if ($opt_recursive) { 7198 if ($opt_recursive) {
7186 push(@todo_items, @subdirs); 7199 push(@todo_items, @subdirs);
7187 } 7200 }
7188} 7201}
7189 7202
7190sub checkdir_category() { 7203sub checkdir_category() {
7191 my $fname = "${current_dir}/Makefile"; 7204 my $fname = "${current_dir}/Makefile";
7192 my ($lines, $lineno); 7205 my ($lines, $lineno);
7193 7206
7194 $opt_debug_trace and log_debug($fname, NO_LINES, "checkdir_category()"); 7207 $opt_debug_trace and log_debug($fname, NO_LINES, "checkdir_category()");
7195 7208
7196 if (!($lines = load_lines($fname, true))) { 7209 if (!($lines = load_lines($fname, true))) {
7197 log_error($fname, NO_LINE_NUMBER, "Cannot be read."); 7210 log_error($fname, NO_LINE_NUMBER, "Cannot be read.");
7198 return; 7211 return;
7199 } 7212 }
7200 parselines_mk($lines); 7213 parselines_mk($lines);
7201 7214
7202 $lineno = 0; 7215 $lineno = 0;
7203 7216
7204 # The first line must contain the RCS Id 7217 # The first line must contain the RCS Id
7205 if ($lineno <= $#{$lines} && checkline_rcsid_regex($lines->[$lineno], qr"#\s+", "# ")) { 7218 if ($lineno <= $#{$lines} && checkline_rcsid_regex($lines->[$lineno], qr"#\s+", "# ")) {
7206 $lineno++; 7219 $lineno++;
7207 } 7220 }
7208 7221
7209 # Then, arbitrary comments may follow 7222 # Then, arbitrary comments may follow
7210 while ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ m"^#") { 7223 while ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ m"^#") {
7211 $lineno++; 7224 $lineno++;
7212 } 7225 }
7213 7226
7214 # Then we need an empty line 7227 # Then we need an empty line
7215 expect_empty_line($lines, \$lineno); 7228 expect_empty_line($lines, \$lineno);
7216 7229
7217 # Then comes the COMMENT line 7230 # Then comes the COMMENT line
7218 if ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ m"^COMMENT=\t*(.*)") { 7231 if ($lineno <= $#{$lines} && $lines->[$lineno]->text =~ m"^COMMENT=\t*(.*)") {
7219 my ($comment) = ($1); 7232 my ($comment) = ($1);
7220 7233
7221 checkline_valid_characters_in_variable($lines->[$lineno], qr"[-\040'(),/0-9A-Za-z]"); 7234 checkline_valid_characters_in_variable($lines->[$lineno], qr"[-\040'(),/0-9A-Za-z]");
7222 $lineno++; 7235 $lineno++;
7223 } else { 7236 } else {
7224 $lines->[$lineno]->log_error("COMMENT= line expected."); 7237 $lines->[$lineno]->log_error("COMMENT= line expected.");
7225 } 7238 }
7226 7239
7227 # Then we need an empty line 7240 # Then we need an empty line
7228 expect_empty_line($lines, \$lineno); 7241 expect_empty_line($lines, \$lineno);
7229 7242
7230 # And now to the most complicated part of the category Makefiles, 7243 # And now to the most complicated part of the category Makefiles,
7231 # the (hopefully) sorted list of SUBDIRs. The first step is to 7244 # the (hopefully) sorted list of SUBDIRs. The first step is to
7232 # collect the SUBDIRs in the Makefile and in the file system. 7245 # collect the SUBDIRs in the Makefile and in the file system.
7233 7246
7234 my (@f_subdirs, @m_subdirs); 7247 my (@f_subdirs, @m_subdirs);
7235 7248
7236 @f_subdirs = sort(get_subdirs($current_dir)); 7249 @f_subdirs = sort(get_subdirs($current_dir));
7237 7250
7238 my $prev_subdir = undef; 7251 my $prev_subdir = undef;
7239 while ($lineno <= $#{$lines}) { 7252 while ($lineno <= $#{$lines}) {
7240 my $line = $lines->[$lineno]; 7253 my $line = $lines->[$lineno];
7241 7254
7242 if ($line->text =~ m"^(#?)SUBDIR\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$") { 7255 if ($line->text =~ m"^(#?)SUBDIR\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$") {
7243 my ($comment_flag, $indentation, $subdir, $comment) = ($1, $2, $3, $4); 7256 my ($comment_flag, $indentation, $subdir, $comment) = ($1, $2, $3, $4);
7244 7257
7245 if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) { 7258 if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) {
7246 $line->log_warning("${subdir} commented out without giving a reason."); 7259 $line->log_warning("${subdir} commented out without giving a reason.");
7247 } 7260 }
7248 7261
7249 if ($indentation ne "\t") { 7262 if ($indentation ne "\t") {
7250 $line->log_warning("Indentation should be a single tab character."); 7263 $line->log_warning("Indentation should be a single tab character.");
7251 } 7264 }
7252 7265
7253 if (defined($prev_subdir) && $subdir eq $prev_subdir) { 7266 if (defined($prev_subdir) && $subdir eq $prev_subdir) {
7254 $line->log_error("${subdir} must only appear once."); 7267 $line->log_error("${subdir} must only appear once.");
7255 } elsif (defined($prev_subdir) && $subdir lt $prev_subdir) { 7268 } elsif (defined($prev_subdir) && $subdir lt $prev_subdir) {
7256 $line->log_warning("${subdir} should come before ${prev_subdir}."); 7269 $line->log_warning("${subdir} should come before ${prev_subdir}.");
7257 } else { 7270 } else {
7258 # correctly ordered 7271 # correctly ordered
7259 } 7272 }
7260 7273
7261 push(@m_subdirs, [$subdir, $line, $comment_flag ? false : true]); 7274 push(@m_subdirs, [$subdir, $line, $comment_flag ? false : true]);
7262 $prev_subdir = $subdir; 7275 $prev_subdir = $subdir;
7263 $lineno++; 7276 $lineno++;
7264 7277
7265 } else { 7278 } else {
7266 if ($line->text ne "") { 7279 if ($line->text ne "") {
7267 $line->log_error("SUBDIR+= line or empty line expected."); 7280 $line->log_error("SUBDIR+= line or empty line expected.");
7268 } 7281 }
7269 last; 7282 last;
7270 } 7283 }
7271 } 7284 }
7272 7285
7273 # To prevent unnecessary warnings about subdirectories that are 7286 # To prevent unnecessary warnings about subdirectories that are
7274 # in one list, but not in the other, we generate the sets of 7287 # in one list, but not in the other, we generate the sets of
7275 # subdirs of each list. 7288 # subdirs of each list.
7276 my (%f_check, %m_check); 7289 my (%f_check, %m_check);
7277 foreach my $f (@f_subdirs) { $f_check{$f} = true; } 7290 foreach my $f (@f_subdirs) { $f_check{$f} = true; }
7278 foreach my $m (@m_subdirs) { $m_check{$m->[0]} = true; } 7291 foreach my $m (@m_subdirs) { $m_check{$m->[0]} = true; }
7279 7292
7280 my ($f_index, $f_atend, $f_neednext, $f_current) = (0, false, true, undef, undef); 7293 my ($f_index, $f_atend, $f_neednext, $f_current) = (0, false, true, undef, undef);
7281 my ($m_index, $m_atend, $m_neednext, $m_current) = (0, false, true, undef, undef); 7294 my ($m_index, $m_atend, $m_neednext, $m_current) = (0, false, true, undef, undef);
7282 my ($line, $m_recurse); 7295 my ($line, $m_recurse);
7283 my (@subdirs); 7296 my (@subdirs);
7284 7297
7285 while (!($m_atend && $f_atend)) { 7298 while (!($m_atend && $f_atend)) {
7286 7299
7287 if (!$m_atend && $m_neednext) { 7300 if (!$m_atend && $m_neednext) {
7288 $m_neednext = false; 7301 $m_neednext = false;
7289 if ($m_index > $#m_subdirs) { 7302 if ($m_index > $#m_subdirs) {
7290 $m_atend = true; 7303 $m_atend = true;
7291 $line = $lines->[$lineno]; 7304 $line = $lines->[$lineno];
7292 next; 7305 next;
7293 } else { 7306 } else {
7294 $m_current = $m_subdirs[$m_index]->[0]; 7307 $m_current = $m_subdirs[$m_index]->[0];
7295 $line = $m_subdirs[$m_index]->[1]; 7308 $line = $m_subdirs[$m_index]->[1];
7296 $m_recurse = $m_subdirs[$m_index]->[2]; 7309 $m_recurse = $m_subdirs[$m_index]->[2];
7297 $m_index++; 7310 $m_index++;
7298 } 7311 }
7299 } 7312 }
7300 7313
7301 if (!$f_atend && $f_neednext) { 7314 if (!$f_atend && $f_neednext) {
7302 $f_neednext = false; 7315 $f_neednext = false;
7303 if ($f_index > $#f_subdirs) { 7316 if ($f_index > $#f_subdirs) {
7304 $f_atend = true; 7317 $f_atend = true;
7305 next; 7318 next;
7306 } else { 7319 } else {
7307 $f_current = $f_subdirs[$f_index++]; 7320 $f_current = $f_subdirs[$f_index++];
7308 } 7321 }
7309 } 7322 }
7310 7323
7311 if (!$f_atend && ($m_atend || $f_current lt $m_current)) { 7324 if (!$f_atend && ($m_atend || $f_current lt $m_current)) {
7312 if (!exists($m_check{$f_current})) { 7325 if (!exists($m_check{$f_current})) {
7313 $line->log_error("${f_current} exists in the file system, but not in the Makefile."); 7326 $line->log_error("${f_current} exists in the file system, but not in the Makefile.");
7314 $line->append_before("SUBDIR+=\t${f_current}"); 7327 $line->append_before("SUBDIR+=\t${f_current}");
7315 } 7328 }
7316 $f_neednext = true; 7329 $f_neednext = true;
7317 7330
7318 } elsif (!$m_atend && ($f_atend || $m_current lt $f_current)) { 7331 } elsif (!$m_atend && ($f_atend || $m_current lt $f_current)) {
7319 if (!exists($f_check{$m_current})) { 7332 if (!exists($f_check{$m_current})) {
7320 $line->log_error("${m_current} exists in the Makefile, but not in the file system."); 7333 $line->log_error("${m_current} exists in the Makefile, but not in the file system.");
7321 $line->delete(); 7334 $line->delete();
7322 } 7335 }
7323 $m_neednext = true; 7336 $m_neednext = true;
7324 7337
7325 } else { # $f_current eq $m_current 7338 } else { # $f_current eq $m_current
7326 $f_neednext = true; 7339 $f_neednext = true;
7327 $m_neednext = true; 7340 $m_neednext = true;
7328 if ($m_recurse) { 7341 if ($m_recurse) {
7329 push(@subdirs, "${current_dir}/${m_current}"); 7342 push(@subdirs, "${current_dir}/${m_current}");
7330 } 7343 }
7331 } 7344 }
7332 } 7345 }
7333 7346
7334 # the wip category Makefile may have its own targets for generating 7347 # the wip category Makefile may have its own targets for generating
7335 # indexes and READMEs. Just skip them. 7348 # indexes and READMEs. Just skip them.
7336 if ($is_wip) { 7349 if ($is_wip) {
7337 while ($lineno <= $#{$lines} - 2) { 7350 while ($lineno <= $#{$lines} - 2) {
7338 $lineno++; 7351 $lineno++;
7339 } 7352 }
7340 } 7353 }
7341 7354
7342 expect_empty_line($lines, \$lineno); 7355 expect_empty_line($lines, \$lineno);
7343 7356
7344 # And, last but not least, the .include line 7357 # And, last but not least, the .include line
7345 my $final_line = ".include \"../mk/bsd.pkg.subdir.mk\""; 7358 my $final_line = ".include \"../mk/bsd.pkg.subdir.mk\"";
7346 expect($lines, \$lineno, qr"\Q$final_line\E") 7359 expect($lines, \$lineno, qr"\Q$final_line\E")
7347 || expect_text($lines, \$lineno, ".include \"../mk/misc/category.mk\""); 7360 || expect_text($lines, \$lineno, ".include \"../mk/misc/category.mk\"");
7348 7361
7349 if ($lineno <= $#{$lines}) { 7362 if ($lineno <= $#{$lines}) {
7350 $lines->[$lineno]->log_error("The file should end here."); 7363 $lines->[$lineno]->log_error("The file should end here.");
7351 } 7364 }
7352 7365
7353 checklines_mk($lines); 7366 checklines_mk($lines);
7354 7367
7355 autofix($lines); 7368 autofix($lines);
7356 7369
7357 if ($opt_recursive) { 7370 if ($opt_recursive) {
7358 unshift(@todo_items, @subdirs); 7371 unshift(@todo_items, @subdirs);
7359 } 7372 }
7360} 7373}
7361 7374
7362sub checkdir_package() { 7375sub checkdir_package() {
7363 my ($lines, $have_distinfo, $have_patches); 7376 my ($lines, $have_distinfo, $have_patches);
7364 7377
7365 # Initialize global variables 7378 # Initialize global variables
7366 $pkgdir = undef; 7379 $pkgdir = undef;
7367 $filesdir = "files"; 7380 $filesdir = "files";
7368 $patchdir = "patches"; 7381 $patchdir = "patches";
7369 $distinfo_file = "distinfo"; 7382 $distinfo_file = "distinfo";
7370 $effective_pkgname = undef; 7383 $effective_pkgname = undef;
7371 $effective_pkgbase = undef; 7384 $effective_pkgbase = undef;
7372 $effective_pkgversion = undef; 7385 $effective_pkgversion = undef;
7373 $effective_pkgname_line = undef; 7386 $effective_pkgname_line = undef;
7374 $seen_bsd_prefs_mk = false; 7387 $seen_bsd_prefs_mk = false;
7375 $pkgctx_vardef = {%{get_userdefined_variables()}}; 7388 $pkgctx_vardef = {%{get_userdefined_variables()}};
7376 $pkgctx_varuse = {}; 7389 $pkgctx_varuse = {};
7377 $pkgctx_bl3 = {}; 7390 $pkgctx_bl3 = {};
7378 $pkgctx_plist_subst_cond = {}; 7391 $pkgctx_plist_subst_cond = {};
7379 $pkgctx_included = {}; 7392 $pkgctx_included = {};
7380 $seen_Makefile_common = false; 7393 $seen_Makefile_common = false;
7381 7394
7382 # we need to handle the Makefile first to get some variables 7395 # we need to handle the Makefile first to get some variables
7383 if (!load_package_Makefile("${current_dir}/Makefile", \$lines)) { 7396 if (!load_package_Makefile("${current_dir}/Makefile", \$lines)) {
7384 log_error("${current_dir}/Makefile", NO_LINE_NUMBER, "Cannot be read."); 7397 log_error("${current_dir}/Makefile", NO_LINE_NUMBER, "Cannot be read.");
7385 goto cleanup; 7398 goto cleanup;
7386 } 7399 }
7387 7400
7388 my @files = <${current_dir}/*>; 7401 my @files = <${current_dir}/*>;
7389 if ($pkgdir ne ".") { 7402 if ($pkgdir ne ".") {
7390 push(@files, <${current_dir}/${pkgdir}/*>); 7403 push(@files, <${current_dir}/${pkgdir}/*>);
7391 } 7404 }
7392 if ($opt_check_extra) { 7405 if ($opt_check_extra) {
7393 push(@files, <${current_dir}/${filesdir}/*>); 7406 push(@files, <${current_dir}/${filesdir}/*>);
7394 } 7407 }
7395 push(@files, <${current_dir}/${patchdir}/*>); 7408 push(@files, <${current_dir}/${patchdir}/*>);
7396 if ($distinfo_file !~ m"^(?:\./)?distinfo$") { 7409 if ($distinfo_file !~ m"^(?:\./)?distinfo$") {
7397 push(@files, "${current_dir}/${distinfo_file}"); 7410 push(@files, "${current_dir}/${distinfo_file}");
7398 } 7411 }
7399 $have_distinfo = false; 7412 $have_distinfo = false;
7400 $have_patches = false; 7413 $have_patches = false;
7401 7414
7402 # Determine the used variables before checking any of the 7415 # Determine the used variables before checking any of the
7403 # Makefile fragments. 7416 # Makefile fragments.
7404 foreach my $fname (@files) { 7417 foreach my $fname (@files) {
7405 if (($fname =~ m"^((?:.*/)?Makefile\..*|.*\.mk)$") 7418 if (($fname =~ m"^((?:.*/)?Makefile\..*|.*\.mk)$")
7406 && (not $fname =~ m"patch-") 7419 && (not $fname =~ m"patch-")
7407 && (not $fname =~ m"${pkgdir}/") 7420 && (not $fname =~ m"${pkgdir}/")
7408 && (not $fname =~ m"${filesdir}/") 7421 && (not $fname =~ m"${filesdir}/")
7409 && (defined(my $lines = load_lines($fname, true)))) { 7422 && (defined(my $lines = load_lines($fname, true)))) {
7410 parselines_mk($lines); 7423 parselines_mk($lines);
7411 determine_used_variables($lines); 7424 determine_used_variables($lines);
7412 } 7425 }
7413 } 7426 }
7414 7427
7415 foreach my $fname (@files) { 7428 foreach my $fname (@files) {
7416 if ($fname eq "${current_dir}/Makefile") { 7429 if ($fname eq "${current_dir}/Makefile") {
7417 $opt_check_Makefile and checkfile_package_Makefile($fname, $lines); 7430 $opt_check_Makefile and checkfile_package_Makefile($fname, $lines);
7418 } else { 7431 } else {
7419 checkfile($fname); 7432 checkfile($fname);
7420 } 7433 }
7421 if ($fname =~ m"/patches/patch-*$") { 7434 if ($fname =~ m"/patches/patch-*$") {
7422 $have_patches = true; 7435 $have_patches = true;
7423 } elsif ($fname =~ m"/distinfo$") { 7436 } elsif ($fname =~ m"/distinfo$") {
7424 $have_distinfo = true; 7437 $have_distinfo = true;
7425 } 7438 }
7426 } 7439 }
7427 7440
7428 if ($opt_check_distinfo && $opt_check_patches) { 7441 if ($opt_check_distinfo && $opt_check_patches) {
7429 if ($have_patches && ! $have_distinfo) { 7442 if ($have_patches && ! $have_distinfo) {
7430 log_warning("${current_dir}/$distinfo_file", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makepatchsum'."); 7443 log_warning("${current_dir}/$distinfo_file", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makepatchsum'.");
7431 } 7444 }
7432 } 7445 }
7433 7446
7434 if (!is_emptydir("${current_dir}/scripts")) { 7447 if (!is_emptydir("${current_dir}/scripts")) {
7435 log_warning("${current_dir}/scripts", NO_LINE_NUMBER, "This directory and its contents are deprecated! Please call the script(s) explicitly from the corresponding target(s) in the pkg's Makefile."); 7448 log_warning("${current_dir}/scripts", NO_LINE_NUMBER, "This directory and its contents are deprecated! Please call the script(s) explicitly from the corresponding target(s) in the pkg's Makefile.");
7436 } 7449 }
7437 7450
7438cleanup: 7451cleanup:
7439 # Clean up global variables. 7452 # Clean up global variables.
7440 $pkgdir = undef; 7453 $pkgdir = undef;
7441 $filesdir = undef; 7454 $filesdir = undef;
7442 $patchdir = undef; 7455 $patchdir = undef;
7443 $distinfo_file = undef; 7456 $distinfo_file = undef;
7444 $effective_pkgname = undef; 7457 $effective_pkgname = undef;
7445 $effective_pkgbase = undef; 7458 $effective_pkgbase = undef;
7446 $effective_pkgversion = undef; 7459 $effective_pkgversion = undef;
7447 $effective_pkgname_line = undef; 7460 $effective_pkgname_line = undef;
7448 $seen_bsd_prefs_mk = undef; 7461 $seen_bsd_prefs_mk = undef;
7449 $pkgctx_vardef = undef; 7462 $pkgctx_vardef = undef;
7450 $pkgctx_varuse = undef; 7463 $pkgctx_varuse = undef;
7451 $pkgctx_bl3 = undef; 7464 $pkgctx_bl3 = undef;
7452 $pkgctx_plist_subst_cond = undef; 7465 $pkgctx_plist_subst_cond = undef;
7453 $pkgctx_included = undef; 7466 $pkgctx_included = undef;
7454 $seen_Makefile_common = undef; 7467 $seen_Makefile_common = undef;
7455} 7468}
7456 7469
7457# 7470#
7458# Selecting the proper checking procedures for a directory entry. 7471# Selecting the proper checking procedures for a directory entry.
7459# 7472#
7460 7473
7461sub checkitem($) { 7474sub checkitem($) {
7462 my ($item) = @_; 7475 my ($item) = @_;
7463 my ($st, $is_dir, $is_reg); 7476 my ($st, $is_dir, $is_reg);
7464 7477
7465 if (!($st = lstat($item))) { 7478 if (!($st = lstat($item))) {
7466 log_error($item, NO_LINE_NUMBER, "Does not exist."); 7479 log_error($item, NO_LINE_NUMBER, "Does not exist.");
7467 return; 7480 return;
7468 } 7481 }
7469 7482
7470 $is_dir = S_ISDIR($st->mode); 7483 $is_dir = S_ISDIR($st->mode);
7471 $is_reg = S_ISREG($st->mode); 7484 $is_reg = S_ISREG($st->mode);
7472 if (!$is_reg && !$is_dir) { 7485 if (!$is_reg && !$is_dir) {
7473 log_error($item, NO_LINE_NUMBER, "Must be a file or directory."); 7486 log_error($item, NO_LINE_NUMBER, "Must be a file or directory.");
7474 return; 7487 return;
7475 } 7488 }
7476 7489
7477 $current_dir = $is_dir ? $item : dirname($item); 7490 $current_dir = $is_dir ? $item : dirname($item);
7478 my $abs_current_dir = Cwd::abs_path($current_dir); 7491 my $abs_current_dir = Cwd::abs_path($current_dir);
7479 $is_wip = !$opt_import && ($abs_current_dir =~ m"/wip(?:/|$)"); 7492 $is_wip = !$opt_import && ($abs_current_dir =~ m"/wip(?:/|$)");
7480 $is_internal = ($abs_current_dir =~ m"/mk(?:/|$)"); 7493 $is_internal = ($abs_current_dir =~ m"/mk(?:/|$)");
7481 7494
7482 # Determine the root directory of pkgsrc. By only overwriting 7495 # Determine the root directory of pkgsrc. By only overwriting
7483 # the global variable $cwd_pkgsrcdir when we are checking inside 7496 # the global variable $cwd_pkgsrcdir when we are checking inside
7484 # a pkgsrc tree, the user can specify a tree with the 7497 # a pkgsrc tree, the user can specify a tree with the
7485 # --pkgsrcdir option and then check files (but not directories) 7498 # --pkgsrcdir option and then check files (but not directories)
7486 # outside of any pkgsrc tree. 7499 # outside of any pkgsrc tree.
7487 $cur_pkgsrcdir = undef; 7500 $cur_pkgsrcdir = undef;
7488 $pkgpath = undef; 7501 $pkgpath = undef;
7489 foreach my $d (".", "..", "../..", "../../..") { 7502 foreach my $d (".", "..", "../..", "../../..") {
7490 if (-f "${current_dir}/${d}/mk/bsd.pkg.mk") { 7503 if (-f "${current_dir}/${d}/mk/bsd.pkg.mk") {
7491 $cur_pkgsrcdir = $d; 7504 $cur_pkgsrcdir = $d;
7492 $pkgpath = relative_path("${current_dir}/${d}", $current_dir); 7505 $pkgpath = relative_path("${current_dir}/${d}", $current_dir);
7493 } 7506 }
7494 } 7507 }
7495 if (!defined($cwd_pkgsrcdir) && defined($cur_pkgsrcdir)) { 7508 if (!defined($cwd_pkgsrcdir) && defined($cur_pkgsrcdir)) {
7496 $cwd_pkgsrcdir = "${current_dir}/${cur_pkgsrcdir}"; 7509 $cwd_pkgsrcdir = "${current_dir}/${cur_pkgsrcdir}";
7497 } 7510 }
7498 7511
7499 if (!defined($cwd_pkgsrcdir)) { 7512 if (!defined($cwd_pkgsrcdir)) {
7500 log_error($item, NO_LINE_NUMBER, "Cannot determine the pkgsrc root directory."); 7513 log_error($item, NO_LINE_NUMBER, "Cannot determine the pkgsrc root directory.");
7501 return; 7514 return;
7502 } 7515 }
7503 7516
7504 check_pkglint_version(); # (needs $cwd_pkgsrcdir) 7517 check_pkglint_version(); # (needs $cwd_pkgsrcdir)
7505 7518
7506 return if $is_dir && is_emptydir($item); 7519 return if $is_dir && is_emptydir($item);
7507 7520
7508 if ($is_dir) { 7521 if ($is_dir) {
7509 checkdir_CVS($item); 7522 checkdir_CVS($item);
7510 } 7523 }
7511 7524
7512 if ($is_reg) { 7525 if ($is_reg) {
7513 checkfile($item); 7526 checkfile($item);
7514 7527
7515 } elsif (!defined($cur_pkgsrcdir)) { 7528 } elsif (!defined($cur_pkgsrcdir)) {
7516 log_error($item, NO_LINES, "Cannot check directories outside a pkgsrc tree."); 7529 log_error($item, NO_LINES, "Cannot check directories outside a pkgsrc tree.");
7517 7530
7518 } elsif ($cur_pkgsrcdir eq "../..") { 7531 } elsif ($cur_pkgsrcdir eq "../..") {
7519 checkdir_package(); 7532 checkdir_package();
7520 7533
7521 } elsif ($cur_pkgsrcdir eq "..") { 7534 } elsif ($cur_pkgsrcdir eq "..") {
7522 checkdir_category(); 7535 checkdir_category();
7523 7536
7524 } elsif ($cur_pkgsrcdir eq ".") { 7537 } elsif ($cur_pkgsrcdir eq ".") {
7525 checkdir_root(); 7538 checkdir_root();
7526 7539
7527 } else { 7540 } else {
7528 log_error($item, NO_LINE_NUMBER, "Don't know how to check this directory."); 7541 log_error($item, NO_LINE_NUMBER, "Don't know how to check this directory.");
7529 } 7542 }
7530} 7543}
7531 7544
7532# 7545#
7533# The main program 7546# The main program
7534# 7547#
7535 7548
7536sub main() { 7549sub main() {
7537 7550
7538 $| = true; 7551 $| = true;
7539 parse_command_line(); 7552 parse_command_line();
7540 7553
7541 @todo_items = (@ARGV != 0) ? @ARGV : ("."); 7554 @todo_items = (@ARGV != 0) ? @ARGV : (".");
7542 while (@todo_items != 0) { 7555 while (@todo_items != 0) {
7543 checkitem(shift(@todo_items)); 7556 checkitem(shift(@todo_items));
7544 } 7557 }
7545 7558
7546 PkgLint::Logging::print_summary_and_exit($opt_quiet); 7559 PkgLint::Logging::print_summary_and_exit($opt_quiet);
7547} 7560}
7548 7561
7549main() unless caller(); 7562main() unless caller();

cvs diff -r1.1 -r1.2 pkgsrc/pkgtools/pkglint/files/PkgLint/Attic/Line.pm (switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/PkgLint/Attic/Line.pm 2013/03/26 15:08:29 1.1
+++ pkgsrc/pkgtools/pkglint/files/PkgLint/Attic/Line.pm 2013/08/31 18:14:28 1.2
@@ -1,214 +1,215 @@ @@ -1,214 +1,215 @@
1#========================================================================== 1#==========================================================================
2# When files are read in by pkglint, they are interpreted in terms of 2# When files are read in by pkglint, they are interpreted in terms of
3# lines. For Makefiles, line continuations are handled properly, allowing 3# lines. For Makefiles, line continuations are handled properly, allowing
4# multiple physical lines to end in a single logical line. For other files 4# multiple physical lines to end in a single logical line. For other files
5# there is a 1:1 translation. 5# there is a 1:1 translation.
6# 6#
7# A difference between the physical and the logical lines is that the 7# A difference between the physical and the logical lines is that the
8# physical lines include the line end sequence, whereas the logical lines 8# physical lines include the line end sequence, whereas the logical lines
9# do not. 9# do not.
10# 10#
11# A logical line is a class having the read-only fields C<file>, 11# A logical line is a class having the read-only fields C<file>,
12# C<lines>, C<text>, C<physlines> and C<is_changed>, as well as some 12# C<lines>, C<text>, C<physlines> and C<is_changed>, as well as some
13# methods for printing diagnostics easily. 13# methods for printing diagnostics easily.
14# 14#
15# Some other methods allow modification of the physical lines, but leave 15# Some other methods allow modification of the physical lines, but leave
16# the logical line (the C<text>) untouched. These methods are used in the 16# the logical line (the C<text>) untouched. These methods are used in the
17# --autofix mode. 17# --autofix mode.
18# 18#
19# A line can have some "extra" fields that allow the results of parsing to 19# A line can have some "extra" fields that allow the results of parsing to
20# be saved under a name. 20# be saved under a name.
21#========================================================================== 21#==========================================================================
22package PkgLint::Line; 22package PkgLint::Line;
23 23
24BEGIN { 24BEGIN {
25 import PkgLint::Util qw( 25 import PkgLint::Util qw(
26 false true 26 false true
27 assert 27 assert
28 ); 28 );
29} 29}
30 30
31use enum qw(FNAME LINES TEXT PHYSLINES CHANGED BEFORE AFTER EXTRA); 31use enum qw(FNAME LINES TEXT PHYSLINES CHANGED BEFORE AFTER EXTRA);
32 32
33sub new($$$$) { 33sub new($$$$) {
34 my ($class, $fname, $lines, $text, $physlines) = @_; 34 my ($class, $fname, $lines, $text, $physlines) = @_;
35 my ($self) = ([$fname, $lines, $text, $physlines, false, [], [], {}]); 35 my ($self) = ([$fname, $lines, $text, $physlines, false, [], [], {}]);
36 bless($self, $class); 36 bless($self, $class);
37 return $self; 37 return $self;
38} 38}
39 39
40sub fname($) { return shift()->[FNAME]; } 40sub fname($) { return shift()->[FNAME]; }
41sub lines($) { return shift()->[LINES]; } 41sub lines($) { return shift()->[LINES]; }
42sub text($) { return shift()->[TEXT]; } 42sub text($) { return shift()->[TEXT]; }
43# Note: physlines is _not_ a simple getter method. 43# Note: physlines is _not_ a simple getter method.
44sub is_changed($) { return shift()->[CHANGED]; } 44sub is_changed($) { return shift()->[CHANGED]; }
45 45
46# querying, getting and setting the extra values. 46# querying, getting and setting the extra values.
47sub has($$) { 47sub has($$) {
48 my ($self, $name) = @_; 48 my ($self, $name) = @_;
49 return exists($self->[EXTRA]->{$name}); 49 return exists($self->[EXTRA]->{$name});
50} 50}
51sub get($$) { 51sub get($$) {
52 my ($self, $name) = @_; 52 my ($self, $name) = @_;
53 assert(exists($self->[EXTRA]->{$name}), "Field ${name} does not exist."); 53 assert(exists($self->[EXTRA]->{$name}), "Field ${name} does not exist.");
54 return $self->[EXTRA]->{$name}; 54 return $self->[EXTRA]->{$name};
55} 55}
56sub set($$$) { 56sub set($$$) {
57 my ($self, $name, $value) = @_; 57 my ($self, $name, $value) = @_;
58 assert(!exists($self->[EXTRA]->{$name}), "Field ${name} already exists."); 58 assert(!exists($self->[EXTRA]->{$name}), "Field ${name} already exists.");
59 59
60 # Make sure that the line does not become a cyclic data structure. 60 # Make sure that the line does not become a cyclic data structure.
61 my $type = ref($value); 61 my $type = ref($value);
62 if ($type eq "") { 62 if ($type eq "") {
63 # ok 63 # ok
64 } elsif ($type eq "ARRAY") { 64 } elsif ($type eq "ARRAY") {
65 foreach my $element (@{$value}) { 65 foreach my $element (@{$value}) {
66 my $element_type = ref($element); 66 my $element_type = ref($element);
67 assert($element_type eq "" || $element_type eq "PkgLint::SimpleMatch", 67 assert($element_type eq "" || $element_type eq "PkgLint::SimpleMatch",
68 "Invalid array data type: name=${name}, type=${element_type}."); 68 "Invalid array data type: name=${name}, type=${element_type}.");
69 } 69 }
70 } else { 70 } else {
71 assert(false, "Invalid data: name=${name}, value=${value}."); 71 assert(false, "Invalid data: name=${name}, value=${value}.");
72 } 72 }
73 73
74 $self->[EXTRA]->{$name} = $value; 74 $self->[EXTRA]->{$name} = $value;
75} 75}
76 76
77sub physlines($) { 77sub physlines($) {
78 my ($self) = @_; 78 my ($self) = @_;
79 return [@{$self->[BEFORE]}, @{$self->[PHYSLINES]}, @{$self->[AFTER]}]; 79 return [@{$self->[BEFORE]}, @{$self->[PHYSLINES]}, @{$self->[AFTER]}];
80} 80}
81 81
82# Only for PkgLint::String support 82# Only for PkgLint::String support
83sub substring($$$$) { 83sub substring($$$$) {
84 my ($self, $line, $start, $end) = @_; 84 my ($self, $line, $start, $end) = @_;
85 85
86 return substr($self->[PHYSLINES]->[$line]->[1], $start, $end); 86 return substr($self->[PHYSLINES]->[$line]->[1], $start, $end);
87} 87}
88 88
89sub show_source($$) { 89sub show_source($$) {
90 my ($self, $out) = @_; 90 my ($self, $out) = @_;
91 91
92 if (PkgLint::Logging::get_show_source_flag()) { 92 if (PkgLint::Logging::get_show_source_flag()) {
 93 print $out ("\n");
93 foreach my $line (@{$self->physlines}) { 94 foreach my $line (@{$self->physlines}) {
94 print $out ("> " . $line->[1]); 95 print $out ("> " . $line->[1]);
95 } 96 }
96 } 97 }
97} 98}
98 99
99sub log_fatal($$) { 100sub log_fatal($$) {
100 my ($self, $text) = @_; 101 my ($self, $text) = @_;
101 102
102 $self->show_source(*STDERR); 103 $self->show_source(*STDERR);
103 PkgLint::Logging::log_fatal($self->fname, $self->[LINES], $text); 104 PkgLint::Logging::log_fatal($self->fname, $self->[LINES], $text);
104} 105}
105sub log_error($$) { 106sub log_error($$) {
106 my ($self, $text) = @_; 107 my ($self, $text) = @_;
107 108
108 $self->show_source(*STDOUT); 109 $self->show_source(*STDOUT);
109 PkgLint::Logging::log_error($self->fname, $self->[LINES], $text); 110 PkgLint::Logging::log_error($self->fname, $self->[LINES], $text);
110} 111}
111sub log_warning($$) { 112sub log_warning($$) {
112 my ($self, $text) = @_; 113 my ($self, $text) = @_;
113 114
114 $self->show_source(*STDOUT); 115 $self->show_source(*STDOUT);
115 PkgLint::Logging::log_warning($self->fname, $self->[LINES], $text); 116 PkgLint::Logging::log_warning($self->fname, $self->[LINES], $text);
116} 117}
117sub log_note($$) { 118sub log_note($$) {
118 my ($self, $text) = @_; 119 my ($self, $text) = @_;
119 120
120 $self->show_source(*STDOUT); 121 $self->show_source(*STDOUT);
121 PkgLint::Logging::log_note($self->fname, $self->[LINES], $text); 122 PkgLint::Logging::log_note($self->fname, $self->[LINES], $text);
122} 123}
123sub log_debug($$) { 124sub log_debug($$) {
124 my ($self, $text) = @_; 125 my ($self, $text) = @_;
125 126
126 $self->show_source(*STDOUT); 127 $self->show_source(*STDOUT);
127 PkgLint::Logging::log_debug($self->fname, $self->[LINES], $text); 128 PkgLint::Logging::log_debug($self->fname, $self->[LINES], $text);
128} 129}
129sub explain_error($@) { 130sub explain_error($@) {
130 my ($self, @texts) = @_; 131 my ($self, @texts) = @_;
131 132
132 PkgLint::Logging::explain_error($self->fname, $self->[LINES], @texts); 133 PkgLint::Logging::explain_error($self->fname, $self->[LINES], @texts);
133} 134}
134sub explain_warning($@) { 135sub explain_warning($@) {
135 my ($self, @texts) = @_; 136 my ($self, @texts) = @_;
136 137
137 PkgLint::Logging::explain_warning($self->fname, $self->[LINES], @texts); 138 PkgLint::Logging::explain_warning($self->fname, $self->[LINES], @texts);
138} 139}
139sub explain_note($@) { 140sub explain_note($@) {
140 my ($self, @texts) = @_; 141 my ($self, @texts) = @_;
141 142
142 PkgLint::Logging::explain_note($self->fname, $self->[LINES], @texts); 143 PkgLint::Logging::explain_note($self->fname, $self->[LINES], @texts);
143} 144}
144sub explain_info($@) { 145sub explain_info($@) {
145 my ($self, @texts) = @_; 146 my ($self, @texts) = @_;
146 147
147 PkgLint::Logging::explain_info($self->fname, $self->[LINES], @texts); 148 PkgLint::Logging::explain_info($self->fname, $self->[LINES], @texts);
148} 149}
149 150
150sub to_string($) { 151sub to_string($) {
151 my ($self) = @_; 152 my ($self) = @_;
152 153
153 return $self->fname . ":" . $self->[LINES] . ": " . $self->[TEXT]; 154 return $self->fname . ":" . $self->[LINES] . ": " . $self->[TEXT];
154} 155}
155 156
156sub prepend_before($$) { 157sub prepend_before($$) {
157 my ($self, $text) = @_; 158 my ($self, $text) = @_;
158 159
159 unshift(@{$self->[BEFORE]}, [0, "$text\n"]); 160 unshift(@{$self->[BEFORE]}, [0, "$text\n"]);
160 $self->[CHANGED] = true; 161 $self->[CHANGED] = true;
161} 162}
162sub append_before($$) { 163sub append_before($$) {
163 my ($self, $text) = @_; 164 my ($self, $text) = @_;
164 165
165 push(@{$self->[BEFORE]}, [0, "$text\n"]); 166 push(@{$self->[BEFORE]}, [0, "$text\n"]);
166 $self->[CHANGED] = true; 167 $self->[CHANGED] = true;
167} 168}
168sub prepend_after($$) { 169sub prepend_after($$) {
169 my ($self, $text) = @_; 170 my ($self, $text) = @_;
170 171
171 unshift(@{$self->[AFTER]}, [0, "$text\n"]); 172 unshift(@{$self->[AFTER]}, [0, "$text\n"]);
172 $self->[CHANGED] = true; 173 $self->[CHANGED] = true;
173} 174}
174sub append_after($$) { 175sub append_after($$) {
175 my ($self, $text) = @_; 176 my ($self, $text) = @_;
176 177
177 push(@{$self->[AFTER]}, [0, "$text\n"]); 178 push(@{$self->[AFTER]}, [0, "$text\n"]);
178 $self->[CHANGED] = true; 179 $self->[CHANGED] = true;
179} 180}
180sub delete($) { 181sub delete($) {
181 my ($self) = @_; 182 my ($self) = @_;
182 183
183 $self->[PHYSLINES] = []; 184 $self->[PHYSLINES] = [];
184 $self->[CHANGED] = true; 185 $self->[CHANGED] = true;
185} 186}
186sub replace($$$) { 187sub replace($$$) {
187 my ($self, $from, $to) = @_; 188 my ($self, $from, $to) = @_;
188 my $phys = $self->[PHYSLINES]; 189 my $phys = $self->[PHYSLINES];
189 190
190 foreach my $i (0..$#{$phys}) { 191 foreach my $i (0..$#{$phys}) {
191 if ($phys->[$i]->[0] != 0 && $phys->[$i]->[1] =~ s/\Q$from\E/$to/g) { 192 if ($phys->[$i]->[0] != 0 && $phys->[$i]->[1] =~ s/\Q$from\E/$to/g) {
192 $self->[CHANGED] = true; 193 $self->[CHANGED] = true;
193 } 194 }
194 } 195 }
195} 196}
196sub replace_regex($$$) { 197sub replace_regex($$$) {
197 my ($self, $from_re, $to) = @_; 198 my ($self, $from_re, $to) = @_;
198 my $phys = $self->[PHYSLINES]; 199 my $phys = $self->[PHYSLINES];
199 200
200 foreach my $i (0..$#{$phys}) { 201 foreach my $i (0..$#{$phys}) {
201 if ($phys->[$i]->[0] != 0 && $phys->[$i]->[1] =~ s/$from_re/$to/) { 202 if ($phys->[$i]->[0] != 0 && $phys->[$i]->[1] =~ s/$from_re/$to/) {
202 $self->[CHANGED] = true; 203 $self->[CHANGED] = true;
203 } 204 }
204 } 205 }
205} 206}
206sub set_text($$) { 207sub set_text($$) {
207 my ($self, $text) = @_; 208 my ($self, $text) = @_;
208 $self->[PHYSLINES] = [[0, "$text\n"]]; 209 $self->[PHYSLINES] = [[0, "$text\n"]];
209 $self->[CHANGED] = true; 210 $self->[CHANGED] = true;
210} 211}
211 212
212#== End of PkgLint::Line ================================================== 213#== End of PkgLint::Line ==================================================
213 214
2141; 2151;