pkgsrc-wip/pkg_summary-utils/files/pkg_src_fetch_var.in
Aleksey Cheusov 4eb64c0b76 the same as previous commit but for PKGREVISION=.
`nb' should added to PKGNAME
2008-10-13 19:17:23 +00:00

367 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.
# 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
for (i=1; i <= ARGC; ++i){
if (ARGV [i] ~ /^(--help|-h)$/){
usage()
exit 0
}
if (ARGV [i] ~ /^(--fields|-f|--vars|-v)$/){
fields = ARGV [i+1]
ARGV [i+1] = ARGV [i] = ""
++i
continue
}
if (ARGV [i] ~ /^(--fields|-f|--vars|-v)/){
fields = ARGV [i]
sub(/^[^=]*=/, "", fields)
ARGV [i] = ""
continue
}
}
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
}