#! /bin/sh # use-before-set - find some uses of shell vars before setting them # Copyright (C) 2005 # Ralf Wildenhues # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This script assumes GNU sed, and mostly POSIX shell. # TODO: parse multiple assignments per line # TODO: parse multiple for loops per line (or don't) # TODO: parse ${foo:=bar} (not portable, so no issue in configure scripts) # # NOTE: This script does not understand 'eval', nor does it follow # "interesting" quotation or escaping mechanisms. # NOTE: This script has no idea of shell functions or any other # nonlinear execution paths. Use `sh -u'. # Set this to '#' if you want the second sed script # to see single-quoted content. (You do, trust me.) skip_single_quoted='#' # Ignore these variables, they are user-provided. # Note: separate with spaces, no newlines in here! skip_vars="SHELL CPPFLAGS LDFLAGS" # These variables are user-provided; it's ok to use them # provided the first use looks like the Autoconf-precious-vars test. # Note: separate with spaces, no newlines in here! precious_vars="\ CC CPP CFLAGS CXX CXXCPP CXXFLAGS CXXCPPFLAGS LD LDCXX LIBS \ F77 FFLAGS FC FCFLAGS GCJ GCJFLAGS RC \ AWK EGREP GREP INSTALL MAKE \ AR AS DLLTOOL NM OBJDUMP RANLIB STRIP" ### should not need to modify anything below this line ### # fail on first error set -e set -u # we rely on ASCII sorting; and please: make it fast LC_ALL=C export LC_ALL if test $# -lt 1 then echo >&2 "usage: $0 script-to-check" exit 1 fi last_param= # Find all probable assignments, # pair them up with corresponding line numbers. # sort the resulting list by parameter name, then line # (in order to pick only the first one later). sed -n < "$1" ' # skip comments /^[ ]*#/b next # parse "foo=bar" /[a-zA-Z_][a-zA-Z_0-9]*=/ { s/.*[^a-zA-Z_]\([a-zA-Z_][a-zA-Z_0-9]*\)=.*/\1/ s/^\([a-zA-Z_][a-zA-Z_0-9]*\)=.*/\1/ p;= } # parse for loop variable assignment /\\)\|\(\\\${#\{0,1\}$param[#%+-:}]\)/ { # for precious variables: end searching without error, # when the specific autoconf snippet is found ${skip_precious} /\