help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

request for feedback: bashlink2: links files content by file path as bas


From: Alex fxmbsw7 Ratchev
Subject: request for feedback: bashlink2: links files content by file path as bash features such as functions and vars
Date: Wed, 21 Jul 2021 14:02:54 +0200

so i wrote a more or less simple piece of thing, somewhen when i write
my httpd again to be on there, so anyway public domain open source
the content of the files 'doc' 'xbl.bash' and bin/xbl.gawk follow

-- doc --

this is another attempt to explain this includes system

an, public domain open source, coding facility

it, checks for files in supported dirs under specified dirs, and binds
them to bash runtime via bash code according to their
which-supported-dir they're in

this is done in three parts, one major bash session in which it
searches for files, filters dirs out, and passes them via stdin null
separated to g\awk, which reads em and processes em, and makes in the
END the bash code sourced by the main first bash instance

supported are

eval1/*   to instantly as read\recieved executed ( printed by gawk
firstly, the content of the files, without mods ) - the rest is
computed to be printed at end of gawk reading the each projects files
separately ..

set/{on,off}   set on or off set opts ( set +off -on )
shopt/{on,off} set on or off shopt opts ( shopt -u off ; shopt -s on )

declare/-*/*[/*]   } ( declare -* *=<content> )
declare/*/*         } declare vars, no - means dont use declare for
'direct' var assigning code
declare/*          } ( *=<content> ; <arr>[element]=<content> )

alias/*   define aliases ( alias -- *=<content> )
function/*   define as function, ( *() { <content> \n } )

keyword/*   define assoc array eval elements
override/keyword/{kwns,code,takes,kws}/*   more complex override
values for the keywords, than just the content

eval2/*   eval'ed at end of all this

bin/   when available will be linked into PATH

so.. you place a function/foo with the content 'echo bar', after the
bash part runs ( via bash or source ) foo() { echo bar; } will be
available
plz check if your editor ends files with newline, important when
defining aliases or variables, to have such off

inside extra/ there are a very few things, 'demo' and 'skel_full' in
particular, the demo defines few basics stuffs and runs en at the end,
the full skel is all dirs supported without files in

cd bashlink2
bash xbl.bash extra/demo
cat extra/demo/eval2/5.the_demo
--
declare -p arrtest assoctest vartest
altest functest
kws ae1 ae3
bintest
declare -p PATH
--
welcome to xmb ware
declare -a arrtest=([0]="success" [1]="second arr element content")
declare -A assoctest=([one/element/test]="success assoc array content" )
declare -- vartest="var content success"
aliases work
functions work
success via kws
success again via assoc keywords
binaries also work
declare -x 
PATH="/root/ogt/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/ogt/bin:/root/bashlink2/bin:/root/bashlink2/extra/demo/bin"
byyee
--

it supports few runtime modes, in default it normally processes each
arg as a project root tree, to look for supported dirs in, then bind
them
ran with xblp= ( p for print ) it prints what it would source\eval
with xblp= and xblf= ( f for files ) gawk prints outs the files
instead of processing

xblpe=<code> ( pe for pre eval ) code to eval before processing
everything at all
xble=<code> ( e for eval ) code to eval in the end

bash xbl.bash # run xmb bashlink[2] with only itselfs stuff, no other
project trees
. xbl.bash # source it in current bash shell session instead of new one

# todo: prompt modement as it used to be

# request for feedback

peace, xmb <onlygoodtext@gmail.com>, +41 78 929 27 10


-- bash part xbl.bash --

#!/bin/bash

rhere=$( realpath "$BASH_SOURCE" )
[[ $rhere ]] && rheredir=${rhere%/*} ||
here=${BASH_SOURCE##/*} here=${here:+$PWD/$here}
here=${here:-$BASH_SOURCE} heredir=${here%/*} \
rhere=$here rheredir=$heredir \
supported='@(eval[12]|set|shopt|declare|alias|function|override)'
#exclude='!(.@(off|xbloff?(.*)|sw[a-z])'

shopt -s nullglob dotglob globstar extglob expand_aliases

set -- "$rheredir" "$@"

[[ -v xblpe ]] && eval -- "$xblpe"

${xblp+${ye=}cat} ${ye-.} <(
for project ; do
 [[ ! -d $project ]] && continue
 project=$( realpath "$project" )
  if [[ -v xblf ]] ; then
   tr \\0 \\n
  else
   [[ -d "$project"/bin ]] && xblm="mkPATH
'${project//\'/\'\\\'\'}'"/bin || xblm=
   gawk ${xgp+-W profile} -v xblm="$xblm" -f "$rheredir"/bin/xbl.gawk
  fi < <(
   files=( ) ; declare -A dirs=( )
   for dir in "$project"/$supported/**/ ; do
    dirs[${dir%/}]=
   done
   for all in "$project"/$supported/**/* ; do
    [[ ! -v dirs[${all%/}] ]] && files+=( "$all" )
   done
   printf %s\\0 "$project" "${files[@]}"
 )
done
)

[[ -v xble ]] &&
 eval -- "$xble"



-- gawk part bin/xbl.gawk --

#!/usr/bin/gawk -f

BEGIN {
 RS = "\0"
 FS = "/+"
 ORS = "\n\n"
 OFS = " "

 exclude = "^(.*\\.(sw[a-z]|off|xbloff.*))$"

 getline base
 gsub( /./, "[&]", base )

 e = split( "eval1 set shopt declare alias function override keyword
eval2", sup, " " )
 while ( ++i <= e ) supported[sup[i]]

 set__["on"] = "-"
 set__["off"] = "+"
}

{
 if ( $0 ~ exclude ) next
 if ( /\/\// ) gsub( "//+", "/" )
 if ( ( origfile = $0 ) ~ /\/$/ ) { dir[ $0 ] ; next }
 file[++_file] = $0
}

function cat( f  ,r,t ) {
 while ( getline t <f ) r = r t RT
 close( f )
 return r
}

function q( s, ss ) {
 gsub( "'", "'\\''", s )
 if ( ss ) return "'" s "'"
 else return s
}

function override_(   which,kw,kk,kkk,n ) {
 if ( $1 != "keyword" ) return
 sub( "[^/]+/", "" )
 which = $1
 sub( "[^/]+/", "" )
 kw = $0
 if ( which == "kws" ) {
  split( a["c"] , kkk , "\0" )
  while ( ++n in kkk ) kk = kk q( kkk[n], 1 ) " "
  a["c"] = kk
 } else if ( which == "code" ) k[kw] = a["c"]
 o[kw, which] = a["c"]
}

function keyword_() {
 s["kw"]++
 k[$0] = a["c"]
}

function declare_( t,v,e ) {
 if ( $1 ~ "^-" ) { t = $1 ; sub( "[^/]+/", "" ); ++_dec }
 if ( NF > 1 ) {
  e = gensub( "[^/]+/(.*)", "\\1", 1 )
  if ( t ) dec_[t, ++dec__[t]] = $1 "[" q( e, 1 ) "]=" q( a["c"], 1 )
  else dec = dec $1 "[" ( (e ~ /^[0-9]+$/) ? q( e, 0 ) : q( e, 1 ) )
"]=" q( a["c"], 1 ) " "
 } else if ( t )
  dec_[t, ++dec__[t]] = $1 "=" q( a["c"], 1 ) ""
 else
  dec = dec $1 "=" q( a["c"], 1 ) " "
}

function eval1_() {
 res = res a["c"] ORS
}

function eval2_() {
 eval2 = eval2 a["c"] ORS
}

function function_() {
 func_ = func_ a["t"] "() { " a["c"] "\n}" ORS
}

function alias_() {
 al = al a["t"] "=" q( a["c"], 1 )  " "
}

function set_() {
 $0 = a["t"]
 if ( $1 in set__ ) _set = _set set__[$1] $2 " "
}

function shopt_() {
 $0 = a["t"]
 if ( $1 == "on" ) shopt_on = shopt_on $2 " "
 else if ( $1 == "off" ) shopt_off = shopt_off $2 " "
}

END { i = 0
 while ( ++i <= _file ) {
  if ( ( file[i] "/" ) in dir ) continue
  $0 = origfile = file[i]

  sub( "^" base "/", "" )
  if ( ! ( $1 in supported ) ) continue
  E = $1 "_"
  sub( "[^/]+/", "" )
  a["t"] = $0
  a["c"] = cat( origfile )

  @E()
 }

 if ( _set != "" ) res = res "set " _set ORS
 if ( shopt_on ) res = res "shopt -s " shopt_on ORS
 if ( shopt_off ) res = res "shopt -u " shopt_off ORS
 if ( _dec ) {
  for ( r in dec__ ) {
   res = res "declare " r " "
   i = 0 ; while ( ++i <= dec__[r] ) res = res dec_[r, i] " "
   res = res ORS
  }
 }
 if ( dec != "" ) res = res dec ORS
 if ( al != "" ) res = res "alias -- " al ORS
 if ( func_ != "" ) res = res func_
 if ( s["kw"] > 0 ) {
  for (kw in k) {
   if ( ( ( t=kwSUBSEP"kwns") in o ) ) kws = kws "kwns=" q( o[t], 1 ) " "
   kws = kws "takes=" q( o[kw,"takes"], 1 ) " "
   kws = kws "code=" q( ( (t=kw SUBSEP"code") in o ) ? o[t] : k[kw] , 1 ) " "
   kws = kws "+kw " ( ( ( t=kw SUBSEP "kws" ) in o ) ? o[t] : q( kw, 1 ) )
   kws = kws ORS
  }
  res = res kws
 }
 if ( xblm != "" ) res = res xblm ORS
 if ( eval2 != "" ) res = res eval2 ORS

 if ( res != "" ) { printf "%s", res; fflush() }
 exit(0)
}


-- end -- i hope for at least one comment :pp



reply via email to

[Prev in Thread] Current Thread [Next in Thread]