#!/bin/sh -e # __ini_value/explorer/state # Check the state of the key-value pair in the ini file # # There are following states: # - present # - wrongvalue # - wrongformat # - commented # - absent # - nosuchfile # Using ' \t' for matching spaces as char classes not implemented in mawk # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=65617#40 # Parameters # (maybe multi-variable object id for this ..) #state_should="$(cat "$__object/parameter/state")" file="$(cat "$__object/parameter/file")" # abort if no file exist if ! [ -f "$file" ]; then echo absent exit fi # run awk awk -f - "$file" <<'AWK' function trim(var) { sub(/^[ \t]*/, "", var) sub(/[ \t]*$/, "", var) return var } function check_spaces(var) { return match(var, /^[ \t]*$/) == 1 } function state(val) { print val exit } BEGIN { _param = (ENVIRON["__object"] "/parameter/") getline state_should < (_param "state") getline section < (_param "section") getline key < (_param "key") getline delimiter < (_param "delimiter") getline value < (_param "value") getline indentation < (_param "indentation") getline delimiter_space < (_param "delimiter-space") do_normalization = (system("test -f " (_param "normalize")) == 0) i=0; _comm_param = (_param "comment-sign"); while((getline tmp < _comm_param) > 0) { comment_signs[i++] = tmp } if(system("test -f " (_param "quote")) == 0) { # quote it now that it only wins checks against quoted values value = ("\"" value "\"") } found=0 curr_section="" if(section == "") found_section=1 else found_section=0 } # catch sections /^[ \t]*\[.*\][ \t]*$/ { curr_section = trim($0) if(found_section) exit # game over, section ends if(section == curr_section) found_section=1 next } # only interesting if a delimiter was found found_section { line = $0 # index 1 cause of trimmed string if((idel = index(line, delimiter)) && (ikey = index(line, key))) { is_com=0 if(ikey > 1) { # maybe comment character or only spaces start_string = substr(line, 1, ikey - 1) # something inside rather than a space -> comment if((icom = match(start_string, /[^ \t]+/)) > 0) { # icom = RSTART # only one free-standing char or directly before the key if(RLENGTH == 1 || icom == ikey - 1) { start_sign = substr(line, RSTART, 1) for(i in comment_signs) { if(start_sign == comment_signs[i]) { is_com = 1; break; } } if(!is_com) next else { aftercom_length = ikey - icom - 1 if(!check_spaces(substr(line, icom + 1, aftercom_length))) next start_spaces = (icom - 1) + aftercom_length } } else next } # must only contain spaces else start_spaces = ikey - 1 } idelspace_start = ikey + length(key) idelspace_length = idel - idelspace_start # check for delimiter is only preceded with spaces if(idelspace_length == 0 || check_spaces(substr(line, idelspace_start, idelspace_length))) { found = 1 # short-circuit on state absent to just delete if(state_should == "absent") state("present"); # extract the value found_value = substr(line, idel + length(delimiter)) is_value = trim(found_value) # check if value is incorrect if(value != is_value) state("wrongvalue") else { # check if the format is important if(do_normalization) { if(match(found_value, /^[ \t]+/) == 1) { found_value = substr(found_value, 1 + RLENGTH) del_val_spacelen = RLENGTH } else del_val_spacelen = 0 # the format must exactly match, else it is incorrect if(start_spaces != indentation || found_value != is_value || idelspace_length != delimiter_space || del_val_spacelen != delimiter_space) state("wrongformat") } if(is_com) state("commented") else state("present") } # this will never be reached } } } # in the end, check if it is absent END { if(!found) state("absent") } AWK