368 lines
7.7 KiB
Text
Executable file
368 lines
7.7 KiB
Text
Executable file
#!/usr/bin/env runawk
|
|
|
|
# Copyright (c) 2007-2008 Aleksey Cheusov <vle@gmx.net>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining
|
|
# a copy of this software and associated documentation files (the
|
|
# "Software"), to deal in the Software without restriction, including
|
|
# without limitation the rights to use, copy, modify, merge, publish,
|
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
# permit persons to whom the Software is furnished to do so, subject to
|
|
# the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
###############################################################
|
|
|
|
#use "alt_getopt.awk"
|
|
|
|
###############################################################
|
|
# output format:
|
|
# for success:
|
|
# + <TAB> FIELD1 <TAB> FIELD2 ...FIELD-N
|
|
# for failure:
|
|
# - <TAB> RAW_FIELD1 <TAB> RAW_FIELD2 ... RAW_FIELD-N PKGPATH
|
|
# PKGNAME means PKGNAME[nbPKGREVISION]
|
|
|
|
BEGIN {
|
|
good_pkgname_re = "^[^${}()]+$" #"^[[:alnum:]_-]+-[[:digit:]]+([.][[:digit:]]+)*$"
|
|
}
|
|
|
|
function get_var_value (varname, value, pkgrev){
|
|
value = ""
|
|
|
|
if (varname == "PKGNAME"){
|
|
if (read_error == 0 && ! ("PKGNAME" in badvar)){
|
|
if ("PKGNAME" in var)
|
|
value = check("PKGNAME")
|
|
else if ("DISTNAME" in var)
|
|
value = check("DISTNAME")
|
|
}
|
|
|
|
if (value == ""){
|
|
error = 1
|
|
return "<badvalue>"
|
|
}
|
|
|
|
pkgrev = ""
|
|
if ("PKGREVISION" in var){
|
|
pkgrev_ = var ["PKGREVISION"]
|
|
if (pkgrev_ != "0" && pkgrev_ != "")
|
|
pkgrev = "nb" pkgrev_
|
|
}
|
|
return value pkgrev
|
|
}else if (varname == "PKGPATH"){
|
|
return pkgpath
|
|
}else{
|
|
if (read_error == 0 && ! (varname in badvar)){
|
|
return check(varname)
|
|
}else{
|
|
error = 1
|
|
return "<badvalue>"
|
|
}
|
|
}
|
|
}
|
|
|
|
function usage (){
|
|
printf "\
|
|
pkg_src_fetch_var - hack for obtaining variable values from package,\n\
|
|
(partially(!!!) emulates bmake)\n\
|
|
\n\
|
|
usage: pkg_src_fetch_var [OPTIONS] [files...]\n\
|
|
OPTIONS:\n\
|
|
-h|--help display this help message\n\
|
|
-v|-f|--vars|--fields <varnames>\n\
|
|
-v|-f|--vars|--fields=<varnames> list of variable names\n\
|
|
separated by space.\n\
|
|
PKGNAME and PKGPATH are fetched by default\n\
|
|
PKGPATHs are read from files or stdin, one PKGPATH per line\n\
|
|
" > "/dev/stderr"
|
|
}
|
|
|
|
BEGIN {
|
|
# options and fields
|
|
long_opts ["help"] = "h"
|
|
long_opts ["fields"] = "f"
|
|
long_opts ["vars"] = "v"
|
|
|
|
while (getopt("hf:v:")){
|
|
if (optopt == "h"){
|
|
usage()
|
|
exit 0
|
|
}else if (optopt == "f" || optopt == "v"){
|
|
fields = optarg
|
|
}else{
|
|
abort()
|
|
}
|
|
}
|
|
|
|
if (fields == "")
|
|
fields = "PKGNAME PKGPATH"
|
|
|
|
varnames_count = split(fields, varnames)
|
|
|
|
# pkgsrcdir
|
|
pkgsrcdir = ENVIRON ["PKGSRCDIR"]
|
|
if (pkgsrcdir == "")
|
|
pkgsrcdir = "/usr/pkgsrc"
|
|
}
|
|
|
|
function print_bad_vars ( j){
|
|
for (j=1; j <= varnames_count; ++j){
|
|
printf "\t%s", var [varnames [j]]
|
|
}
|
|
printf "\t%s", pkgpath
|
|
printf "\n"
|
|
}
|
|
|
|
function print_good_vars ( j){
|
|
for (j=1; j <= varnames_count; ++j){
|
|
printf "\t%s", good_var [varnames [j]]
|
|
}
|
|
printf "\n"
|
|
}
|
|
|
|
function calc_and_print ( i, varname, value){
|
|
error = 0
|
|
for (i=1; i <= varnames_count; ++i){
|
|
varname = varnames [i]
|
|
good_var [varname] = value = get_var_value(varname)
|
|
if (error){
|
|
error = 0
|
|
printf "-"
|
|
print_bad_vars()
|
|
return
|
|
}
|
|
}
|
|
|
|
printf "+"
|
|
print_good_vars()
|
|
}
|
|
|
|
# try to get a real PKGNAME...
|
|
function check (variable,
|
|
|
|
value,left,right,subvarname,subvalue,repl,old_string,new_string)
|
|
{
|
|
# fast checks
|
|
|
|
# PKGNAME was assigned more than once, i.e. badname?
|
|
if (variable in badvar)
|
|
return ""
|
|
|
|
value = var [variable]
|
|
# not set?
|
|
if (value == "")
|
|
return ""
|
|
|
|
# try replacements...
|
|
while (match(value, /[$][{][[:alnum:]_.]+(:S\/[^\/]*\/[^\/]*\/)?[}]/)){
|
|
left = substr(value, 1, RSTART-1)
|
|
right = substr(value, RSTART+RLENGTH)
|
|
|
|
# ${VARNAME} found?
|
|
if (value !~ /:S\//){
|
|
# yes!
|
|
subvarname = substr(value, RSTART + 2, RLENGTH - 3)
|
|
subvalue = check(subvarname)
|
|
|
|
if (subvalue == ""){
|
|
return ""
|
|
}
|
|
|
|
value = left subvalue right
|
|
continue
|
|
}
|
|
|
|
# ${VARNAME:S/old_substr/new_substr/} found!
|
|
repl = substr(value, RSTART + 2, RLENGTH - 4)
|
|
subvarname = repl
|
|
sub(/:.*$/, "", subvarname)
|
|
sub(/^[^:]+:S\//, "", repl)
|
|
|
|
subvalue = check(subvarname)
|
|
if (subvalue == ""){
|
|
return ""
|
|
}
|
|
|
|
# print "left=" left
|
|
# print "right=" right
|
|
# print "varname=" varname
|
|
# print "repl=" repl
|
|
# print "----"
|
|
|
|
match(repl, "/")
|
|
old_string = substr(repl, 1, RSTART-1)
|
|
new_string = substr(repl, RSTART+1)
|
|
|
|
# complex old_string?
|
|
if (old_string ~ /[$^\[\]\\]/){
|
|
# yes :-(
|
|
return ""
|
|
}
|
|
|
|
# string to regexp
|
|
gsub(/[?{}|()*+.]/, "[&]", old_string)
|
|
|
|
# old_string to new_string
|
|
sub(old_string, new_string, subvalue)
|
|
# print "result of substritution: var [" varname "]=" var [varname]
|
|
#
|
|
value = left subvalue right
|
|
}
|
|
|
|
# final check
|
|
if (value ~ good_pkgname_re){
|
|
return value
|
|
}
|
|
|
|
# :-(
|
|
return ""
|
|
}
|
|
|
|
function trim (s){
|
|
sub(/^[ \t]+/, "", s)
|
|
sub(/[ \t]+$/, "", s)
|
|
|
|
return s
|
|
}
|
|
|
|
function dirname (fn){
|
|
if (sub(/\/[^\/]+$/, "", fn))
|
|
return fn
|
|
else
|
|
return "."
|
|
}
|
|
|
|
function process_include (fn, inc, cond_cnt, ret,varname){
|
|
if (inc ~ /^\//)
|
|
fn = inc
|
|
else
|
|
fn = dirname(fn) "/" inc
|
|
|
|
# print "incl:" fn
|
|
|
|
while ((ret = getline < fn) > 0){
|
|
# in: <spaces>VAR=...
|
|
# out: VAR=...
|
|
sub(/^[ \t]+/, "")
|
|
|
|
# in: VAR=123 # assignment
|
|
# out: VAR=123
|
|
sub(/#.*$/, "")
|
|
|
|
# in: VAR=...<spaces>
|
|
# out: VAR=...
|
|
sub(/[ \t]+$/, "")
|
|
|
|
if ($1 ~ /^[[:alnum:]_.]+$/ && $2 ~ /=/){
|
|
# in: VAR =...
|
|
# out: VAR=...
|
|
sub(/[ \t]+/, "")
|
|
}
|
|
|
|
if ($1 ~ /[[:alnum:]_.]+[!+?]=/){
|
|
# in: VAR=123
|
|
# out: VAR= 123
|
|
sub(/=/, "= ")
|
|
}
|
|
|
|
if ($1 ~ /^[.]if/) {
|
|
++cond_cnt
|
|
continue
|
|
}
|
|
|
|
if ($1 == ".endif") {
|
|
--cond_cnt
|
|
continue
|
|
}
|
|
|
|
if ($1 ~ /^[[:alnum:]_.]+!=$/){
|
|
varname = $1
|
|
sub(/!=$/, "", varname)
|
|
badvar [varname] = 1
|
|
}
|
|
|
|
if ($1 == ".undef"){
|
|
badvar [$2] = 1
|
|
}
|
|
|
|
if (match ($1, /^[[:alnum:]_.]+[?:]?=/)) {
|
|
varname = $1
|
|
sub(/[?:]?=.*$/, "", varname)
|
|
|
|
sub(/^[^=]+=/, "", $0)
|
|
$0 = trim($0)
|
|
|
|
if (cond_cnt != 0 || (varname in var) && var [varname] != $0){
|
|
# double assignment? -> badvar
|
|
badvar [varname] = 1
|
|
}else{
|
|
# conditional assignments are not remembered
|
|
var [varname] = $0
|
|
# print varname " ---> " var [varname]
|
|
}
|
|
continue
|
|
}
|
|
|
|
if (match ($1, /^[[:alnum:]_.]+[+]=/)) {
|
|
varname = $1
|
|
sub(/[+]=.*$/, "", varname)
|
|
|
|
sub(/^[^=]+=/, "", $0)
|
|
$0 = trim($0)
|
|
|
|
if (cond_cnt != 0){
|
|
# double assignment? -> badvar
|
|
badvar [varname] = 1
|
|
}else{
|
|
# conditional assignments are not remembered
|
|
var [varname] = (var [varname] " " $0)
|
|
# print varname " ---> " var [varname]
|
|
}
|
|
continue
|
|
}
|
|
|
|
if ($1 == ".include" &&
|
|
$2 !~ /buildlink3.mk"$/ && $2 !~ /^"[.][.]\/[.][.]\/mk/)
|
|
{
|
|
# recursive .include processing
|
|
if (cond_cnt > 0)
|
|
new_cnt = 10000 # unbalanced .if/.endif? who knows
|
|
else
|
|
new_cnt = 0
|
|
|
|
inc = substr($2, 2, length($2)-2)
|
|
sub(/[$][{][.]CURDIR[}]/, top_dir, inc)
|
|
process_include(fn, inc, new_cnt)
|
|
}
|
|
}
|
|
|
|
close(fn)
|
|
|
|
if (ret < 0){
|
|
read_error = 1
|
|
}
|
|
}
|
|
|
|
{
|
|
pkgpath = $1
|
|
last_fn = pkgsrcdir "/" $1 "/Makefile"
|
|
|
|
top_dir = dirname(last_fn)
|
|
read_error = 0
|
|
process_include(".", last_fn, 0)
|
|
calc_and_print()
|
|
|
|
delete var
|
|
delete badvar
|
|
}
|