#!/bin/bash # $HeadURL$ $LastChangedRevision$ # Modules . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } # Configurable stuff # Other globals main() { local MY_ARGS local REAL_FUNCTION PRESENT BEFORE AFTER TEXT FILE REPLACE STATE # Defaults for options LOGIC=true PRESENT=unset BEFORE=unset AFTER=unset REPLACE=unset TEXT=unset FILE=unset # Process options special_opts_handler() { case $1 in --present=*) PRESENT="${1#*=}" ;; --before=*) BEFORE="${1#*=}" ;; --after=*) AFTER="${1#*=}" ;; --replace=*) REPLACE="${1#*=}" ;; --text=*) TEXT="${1#*=}" ;; --file=*) FILE=${1#*=} ;; *) return 1 ;; esac } miniade_process_options --help-handler=help --special-opts-handler=special_opts_handler MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations check_not_unset TEXT FILE check_all_but_one_unset AFTER BEFORE REPLACE if [[ $PRESENT = unset ]]; then PRESENT=$TEXT PRESENT="${PRESENT//./\\.}" PRESENT="${PRESENT//\*/\\*}" PRESENT="${PRESENT//\+/\\+}" PRESENT="${PRESENT//\(/\\\(}" PRESENT="${PRESENT//\)/\\\)}" PRESENT="^$PRESENT\$" miniade_debug 4 "main: PRESENT not defined; converted [$TEXT] safe regexp [$PRESENT]" fi if [ "X$BEFORE" = XSOF ]; then miniade_warning "please use 'BOF' instead of 'SOF'" BEFORE=BOF fi # Get state if [ ! -f $FILE -o ! -r $FILE ]; then STATE=unconfigured elif perlgrep "$PRESENT" $FILE; then STATE=configured else STATE=unconfigured fi # If already in desired state, do nothing if $LOGIC && [ $STATE = configured ]; then return 0 elif ! $LOGIC && [ $STATE = unconfigured ]; then return 0 # Make changes elif ! $LOGIC && [ $STATE = configured ]; then miniade_internal "not implemented" elif $LOGIC && [ $STATE = unconfigured ]; then mkdir -p $(dirname $FILE) touch $FILE if [[ $AFTER =~ ^EOF$ ]]; then echo "$TEXT" >> $FILE elif [[ $BEFORE =~ ^BOF$ ]]; then TMP_FILE=$(mktemp) { echo "$TEXT"; cat $FILE; } > $TMP_FILE cat $TMP_FILE > $FILE rm -f $TMP_FILE elif [[ $AFTER != unset ]] && perlgrep "$AFTER" $FILE; then perl -0777 -pi -e 'BEGIN { sub r { ($s)=@_; $s =~ s/\\\\/\\/g; $s =~ s/\\n/\n/g; $s =~ s/\\t/\t/g; return $s; } $desired_after = &r(shift); $desired_text = &r(shift); } s/($desired_after)/$1$desired_text/ms;' "$AFTER" "$TEXT" $FILE elif [[ $AFTER != unset ]]; then miniade_error "$FILE: $AFTER: not found in file (1)" elif [[ $BEFORE != unset ]] && perlgrep "$BEFORE" $FILE; then perl -0777 -pi -e 'BEGIN { sub r { ($s)=@_; $s =~ s/\\\\/\\/g; $s =~ s/\\n/\n/g; $s =~ s/\\t/\t/g; return $s; } $desired_before = &r(shift); $desired_text = &r(shift); } s/($desired_before)/$desired_text$1/ms;' "$BEFORE" "$TEXT" $FILE elif [[ $BEFORE != unset ]]; then miniade_error "$FILE: $BEFORE: not found in file (2)" elif [[ $BEFORE != unset ]] && perlgrep "$BEFORE" $FILE; then perl -0777 -pi -e 'BEGIN { sub r { ($s)=@_; $s =~ s/\\\\/\\/g; $s =~ s/\\n/\n/g; $s =~ s/\\t/\t/g; return $s; } $desired_before = &r(shift); $desired_text = &r(shift); } s/($desired_before)/$desired_text$1/ms;' "$BEFORE" "$TEXT" $FILE elif [[ $BEFORE != unset ]]; then miniade_error "$FILE: $BEFORE: not found in file (3)" elif [[ $REPLACE != unset ]] && perlgrep "$REPLACE" $FILE; then perl -0777 -pi -e 'BEGIN { sub r { ($s)=@_; $s =~ s/\\\\/\\/g; $s =~ s/\\n/\n/g; $s =~ s/\\t/\t/g; return $s; } $desired_replace = &r(shift); $desired_text = &r(shift); } s/$desired_replace/$desired_text/ms;' "$REPLACE" "$TEXT" $FILE elif [[ $REPLACE != unset ]]; then miniade_error "$FILE: $REPLACE: not found in file (4)" else miniade_internal "this should not happen" fi fi } perlgrep() { local PATTERN FILE RC PATTERN="$1" FILE="$2" RC=0 perl -0777 -ne 'BEGIN { sub r { ($s)=@_; $s =~ s/\\\\/\\/g; $s =~ s/\\n/\n/g; $s =~ s/\\t/\t/g; return $s; } $rc = 1; $pattern = &r(shift); } END { exit $rc; } if (/$pattern/ms) { $rc=0; last; }' "$PATTERN" "$FILE" || RC=$? return $RC } check_not_unset() { local VAR VAL for VAR in "$@"; do eval "VAL=\"\$$VAR\"" miniade_debug 20 "check_not_unset: VAR=$VAR, VAL=$VAL" [ "X$VAL" != Xunset ] || miniade_bad_usage done } check_all_but_one_unset() { local SET_COUNT UNSET_COUNT SET_COUNT=0 UNSET_COUNT=0 for VAR in "$@"; do eval "VAL=\$$VAR" miniade_debug 10 "check_all_but_one_unset: $VAR=$VAL" case $VAL in unset) ((++UNSET_COUNT)) ;; *) ((++SET_COUNT)) ;; esac done [ $SET_COUNT = 1 ] || miniade_bad_usage } help() { local PROGNAME miniade_get_progname PROGNAME echo "Usage: $PROGNAME [ ] --text= --file= [ --present= ] --{before|after|replace}=" exit 0 } main "$@"