Contained here are the Korn shell 93 functions that comprise the frenchMenus library. Make not these functions are Korn Shell 93 compliant and will not work with Korn shell 88.




################################################################
cnt_sleep()
{
   move ${MAX_LINES} 1
   clrtoeol
   attrset blink
   attrset rev
   addstr "Sleeping for ${1} second(s)"
   attroff
   refresh
   SLEEP_CNT="0"
   while (( ${SLEEP_CNT} < ${1} ))
   do
       SLEEP_CNT="$(( ${SLEEP_CNT} + 1 ))"
       addstr "."
       refresh
       sleep 1
   done
   mvclrtoeol ${MAX_LINES} 1
   refresh
}

################################################################
drawEntry()
{
    CNT_DRAW=0
    while LAB_RAW="$( getstr )"
    do
        CNT_DRAW="$(( ${CNT_DRAW} + 1 ))"
        LAB_FILL="${LAB_RAW%%\|*}"
        E_TMP="${LAB_RAW#*\|}"
        E_TMP="${E_TMP%\|*}"
        eval E_DFLT="\"${E_TMP}\""
        eval E_${LABEL}_${CNT_DRAW}=\"\${E_DFLT}\"
        LAB_PROMPT=$( fillcol "${LAB_FILL}" "${E_DFLT}" 37 )
        COL_DRAW="2"
        (( ${CNT_DRAW} >= 10 )) && COL_DRAW="1"
        mvaddstr "$(( 4 + ${CNT_DRAW} ))" ${COL_DRAW} "${CNT_DRAW}: ${LAB_PROMPT}:"
    done < ${DD_TOPDIR}/entry${1}.shtml
    NBR_LINES="${CNT_DRAW}"
    CNT_DRAW="$(( ${NBR_LINES} + 1 ))"
    COL_DRAW="2"
    (( ${CNT_DRAW} >= 10 )) && COL_DRAW="1"
    CNT_LINE="$(( ${NBR_LINES} + 6 ))"
    eval mvaddstr \${CNT_LINE} \${COL_DRAW} \"$( fillcol "${CNT_DRAW}: Line to Change" "0" 40 ):\"
    clrtoeol
    putMessage
    return ${NBR_LINES}
}

################################################################
drawMenu()
{
    CNT_DRAW=0
    CNT_LINE=0
    while LAB_RAW="$( getstr )"
    do
        CNT_DRAW="$(( ${CNT_DRAW} + 1 ))"
        LAB_FILL="${LAB_RAW%%\|*}"
        M_DFLT="${LAB_RAW#*\|}"
        M_DFLT="${M_DFLT%\|*}"

        eval M_${LABEL}_${CNT_DRAW}="\"${M_DFLT}\""
        CNT_LINE="$(( ${CNT_DRAW} * 2 ))"
        COL_DRAW="26"
        (( ${CNT_DRAW} >= 10 )) && COL_DRAW="25"
        mvaddstr "$(( 3 + ${CNT_LINE} ))" ${COL_DRAW} "${CNT_DRAW} = ${LAB_FILL}"
    done < ${DD_TOPDIR}/menu${1}.shtml
    LAB_PROMPT=$( fillcol "Select Menu Option" "0" 32 )
    mvaddstr "$(( ${CNT_LINE} + 6 ))" 5 "${LAB_PROMPT}:"
    clrtoeol
    refresh
    return ${CNT_DRAW}
}

################################################################
entryScreen()
{
    eval BUF_TMP=\"\${e${LABEL}:=\"\"}\"
    if [[ -n "${BUF_TMP}" ]]
    then
        refresh "e${LABEL}"
        NBR_LINES="${LIN_[${LABEL}]}"
     else
        putMessage "Assembling data entry screen..."
        savescr ${DEV_NULL}
        clear
        header
        drawEntry "${1}"
        NBR_LINES="${?}"
        LIN_[${LABEL}]="${NBR_LINES}"
        savescr e${LABEL}
    fi
    getAnswer ${NBR_LINES} && resetAnswer ${NBR_LINES}
    putMessage
    return 0
}

################################################################
errend()
{
   move "$(( ${MAX_LINES} - 1 ))"  1
   clrtoeol
   addstr "ERROR: ${1}"
   scrnend
}

################################################################
fillcol()
{
    LEN_DIFF="$(( ${3} - ${#1} - ${#2} ))"
    typeset -L${LEN_DIFF} DOTS="................................................................................"
#     ${CMD_ECHO} "${1}${DOTS}(${2})"
    eval \${CMD_ECHO} ${OPT_ECHO} \"\${1}\${DOTS}\(\${2}\)\"
}

################################################################
frenchMenus()
{
    initscr
    MENULEV="0"
    LABEL=""
    SERVER=""
    SCRDATE=""
    HDRSAV0=${HDRLIN2}

    eval MENUANS${MENULEV}=""

    SH_MENU="${DD_TOPDIR}/menu${LABEL}.sh"
    [[ -f ${SH_MENU} ]] && . ${SH_MENU} ${LABEL}

    while :
    do
        putMessage "Assembling menu screen..."
        eval BUF_TMP=\"\${m${LABEL}:=\"\"}\"
        if [[ -n "${BUF_TMP}" ]]
        then
            refresh "m${LABEL}"
            STATUS="${LIN_[${LABEL}]}"
         else
            savescr ${DEV_NULL}
            clear
            header
            drawMenu "${LABEL}"
            STATUS=${?}
            LIN_[${LABEL}]="${STATUS}"
            savescr "m${LABEL}"
        fi
        getMenu ${STATUS}
        (( ${MENULEV} < 0 )) && break
        SH_MENU="${DD_TOPDIR}/menu${LABEL}.sh"
        SH_ENTRY="${DD_TOPDIR}/entry${LABEL}.sh"
        TXT_MENU="${DD_TOPDIR}/menu${LABEL}.shtml"
        TXT_ENTRY="${DD_TOPDIR}/entry${LABEL}.shtml"
        [[ -f ${SH_MENU} ]] && . ${SH_MENU} ${LABEL}
        [[ -f ${TXT_MENU} ]] && continue
        [[ -f ${TXT_ENTRY} ]] && entryScreen "${LABEL}"
        [[ -s ${SH_ENTRY} ]] && . ${SH_ENTRY}
        reset_level
    done

    putMessage
}    

################################################################
getAnswer()
{
    STATUS="0"
    eval FUNCTION="\${M_${LABDAT}_${LTC}}"
    if [[ "${FUNCTION}" = @(modify|config|delete) ]]
    then
        selectRecord "${1}"
        STATUS="${?}"
        return ${STATUS}
    fi                

    CNT_ANS="0"
    while (( ${CNT_ANS} < ${1} ))
    do
        CNT_ANS="$(( ${CNT_ANS} + 1 ))"
        move "$(( 4 + ${CNT_ANS} ))" 46
        refresh
        ANS="$( getstr )"
        eval ANS\[\${CNT_ANS}\]=\"${ANS}\"
    done
    return ${STATUS}
}

################################################################
getMenu()
{
    while :
    do
        CNT_ANS="0"
        move "$(( ${1} * 2 + 6 ))" 41
        clrtoeol
        refresh
        LTC="$( getstr )"
        [[ "_${LTC}" = "_" ]] && LTC="0"
        [[ "_${LTC}" = "_0" ]] && reset_level && return ${LTC}
        [[ "_${LTC}" = *[!0-9]* ]] || continue
        (( ${LTC} < 0 )) && cnt_sleep "$(( ${LTC} * -1 ))"
        (( ${LTC} < 0 )) ||
          (( ${LTC} > ${1} )) &&
          continue
        break
    done
    set_level ${LTC}
    return ${LTC}
}

################################################################
getRecord()
{
    putMessage "Retrieving data record..."
    RECORD=""
    CNT_ANS="0"

    IFS="${FIELDDELIM:=|}"
    set -- ${1}
    IFS="${IFS_NORM}"
    for FIELD in "${@}"
    do
        CNT_ANS="$(( ${CNT_ANS} + 1 ))"
        ANS[${CNT_ANS}]="${FIELD}"
    done

    putMessage
    return ${CNT_ANS}
}

################################################################
header()
{
   SCRNUM="${LABEL}"
   [[ "_${SCRDATE}" = "_" ]] && SCRDATE=$( date +"%m/%d/%y" )
   [[ "_${SERVER}" = "_" ]] && SERVER="${LOGNAME}@$( uname -n )"
   attrset rev
   mvaddstr 1 1 "PGM${PRGNUM}"
   justifyCenter 1 "${HDRLIN1}"
   justifyLeft 1 "${SERVER}"
   mvaddstr 2 1 "SCR${SCRNUM}"
   justifyCenter 2 "${HDRLIN2}"
   justifyLeft 2 "${SCRDATE}"
   attroff
}

################################################################
invalidKey()
{
    putMessage "ERROR: Invalid keystroke..."
    sleep 2
    return 0
}

################################################################
justifyCenter()
{
    mvaddstr ${1} "$(( ( ${MAX_COLS} - ${#2} ) / 2 ))" "${2}"
}

################################################################
justifyLeft()
{
    mvaddstr ${1} "$(( ${MAX_COLS} - ${#2} ))" "${2}"
}

################################################################
mkrecord()
{
    putMessage "Assembling data record..."
    RECORD=""
    CNT_ANS="0"
    while (( ${CNT_ANS} < ${1} ))
    do
        CNT_ANS="$(( ${CNT_ANS} + 1 ))"
        ANS="${ANS[${CNT_ANS}]}"
        eval E_DFLT=\"\${E_${LABEL}_${CNT_ANS}}\"
        [[ "_${ANS}" = "_" ]] && ANS="${E_DFLT}"
        RECORD="${RECORD}${ANS}${FIELDDELIM:=|}"
    done
    putMessage
}

################################################################
putAnswer()
{
    putMessage "Processing user data..."
    CNT_ANS="0"
    while (( ${CNT_ANS} < ${1} ))
    do
        CNT_ANS="$(( ${CNT_ANS} + 1 ))"
        move "$(( 4 + ${CNT_ANS} ))" 46
        clrtoeol
        addstr "${ANS[${CNT_ANS}]}"
        refresh
    done
    putMessage
}

################################################################
putMessage()
{
    move $(( ${MAX_LINES} - 1 )) 1
    clrtoeol
    attrset blink
    addstr "${1}"
    attroff
    addstr "${2}"
    refresh
}

################################################################
removeRecord()
{
#     RECORD=$( ${CMD_ECHO} "${RECORD}" | tr '/' "${DIRSEP:=!}" )
#     RECORD=$( ${CMD_ECHO} "${RECORD}" | sed -e "s/\//${DIRSEP:=!}/g;s/ /_/g" )
    RECORD="${RECORD//\//${DIRSEP:=!}}"
    RECORD="${RECORD// /_}"
    rm -f "${DD_DATABASE}${1}/${RECORD}"
    STATUS="${?}"
    return ${STATUS}
}

################################################################
resetAnswer()
{
    mkrecord "${1}"
    if [[ "_${FUNCTION}" = "_delete" ]]
    then
        removeRecord "table${LABDAT}0"
        return 0
    fi
    RECORD_OLD="${RECORD}"
    while :
    do
        mvclrtoeol "$(( ${1} + 6 ))" 46
        refresh
        LTC="$( getstr )"
        [[ "_${LTC}" = "_" ]] && LTC="0"
        [[ "_${LTC}" = "_0" ]] && mkrecord "${1}" && break
        [[ "_${LTC}" = *[!0-9]* ]] || continue
        if (( ${LTC} == -1 ))
        then
            LTC="$(( ${1} + 1 ))"
            refresh "e${LABEL}"
            putAnswer ${1}
        fi
        (( ${LTC} >= 1 )) &&
          (( ${LTC} <= ${1} )) &&
          mvclrtoeol "$(( 4 + ${LTC} ))" 46 &&
          refresh &&
          ANS="$( getstr )" &&
          eval ANS\[\${LTC}\]=\"${ANS}\"
    done
    if [[ "_${RECORD}" != "_${RECORD_OLD}" ||
          "${FUNCTION}" != @(modify|config) ]]
    then
        if saveRecord "table${LABDAT}0"
        then
            RECORD="${RECORD_OLD}"
            [[ "${FUNCTION}" = @(modify|config) ]] &&
                removeRecord "table${LABDAT}0"
        fi
    else
	attrset rev
	attrset blink
        mvaddstr ${MAX_LINES} 1 "Record is unchanged"
        refresh
        sleep 2
	attroff
        refresh
    fi
    return 0
}

################################################################
reset_level()
{
   MENULEV="$(( ${MENULEV} - 1 ))"
   MENUPREV="$(( ${MENULEV} -  1 ))"
   MENUNEXT="$(( ${MENULEV} + 1 ))"
   (( ${MENUPREV} <= 0 )) && MENUPREV="0"
   set_label
   return 0
}

################################################################
saveRecord()
{
  STATUS=1
  YORNMSG="Save Record"
  [[ "_${FUNCTION}" = "_transient" ]] && YORNMSG="Process Record"
  if yesOrNo "${YORNMSG}"
  then
    if [[ "_${FUNCTION}" != "_transient" ]]
    then
      [[ ! -d ${DD_DATABASE}${1} ]] &&
        mkdir ${DD_DATABASE}${1} &&
        chmod 777 ${DD_DATABASE}${1}
#       RECORD=$( ${CMD_ECHO} "${RECORD}" | tr '/' "${DIRSEP:=!}" )
#       RECORD=$( ${CMD_ECHO} "${RECORD}" | sed -e "s/\//${DIRSEP:=!}/g;s/ /_/g" )
      RECORD="${RECORD//\//${DIRSEP:=!}}"
      RECORD="${RECORD// /_}"
      [[ "_${FUNCTION}" = "_config" ]] && rm -f ${DD_DATABASE}${1}/*
      touch "${DD_DATABASE}${1}/${RECORD}"
      STATUS="${?}"
    else
      STATUS="0"
    fi
  fi
  return ${STATUS}
}

################################################################
scrnend()
{
   move ${MAX_LINES} 1
   clrtoeol
   attrset blink
   attrset rev
   addstr "Press  to contine"
   attroff
   refresh
   SCRNEND="$( getch )"
}

################################################################
selectRecord()
{
    STATUS="1"
    putMessage "Retrieving list of data records..."
    IFS="${IFS_CR}"
#     for RECORD in $( ls -1 ${DD_DATABASE}table${LABDAT}0 )
    for RECORD in ${DD_DATABASE}table${LABDAT}0/*
    do
        RECORD="${RECORD#${DD_DATABASE}table${LABDAT}0/}"
        RECORD="${RECORD//${DIRSEP:=!}//}"
#         RECORD=$( ${CMD_ECHO} "${RECORD}" | sed -e "s/${DIRSEP:=!}/\//g" )

        IFS="${IFS_NORM}"
        getRecord "${RECORD}"
        putAnswer "${1}"
        [[ "${FUNCTION}" = @(modify|config) ]] && TMP="Modify"
        [[ "${FUNCTION}" = "delete" ]] && TMP="Delete"
        if yesOrNo "${TMP} this record"
        then
            STATUS="0"
            break
        fi
        IFS=${IFS_CR}
    done
    IFS=${IFS_NORM}

    putMessage
    return ${STATUS}
}

################################################################
set_label()
{
   LABEL=""
   LABDAT=""
   ISFL=0
   if (( ${MENULEV} >= 1 ))
   then
      while (( ${ISFL} <= ${MENUPREV} ))
      do
         ISFL="$(( ${ISFL} + 1 ))"
         LABEL="${LABEL}${MENUANS[${ISFL}]}"
         (( ${ISFL} <= ${MENUPREV} )) && LABDAT="${LABEL}"
      done
   fi
}

################################################################
set_level()
{
   MENUPREV=${MENULEV}
   MENULEV="$(( ${MENULEV} + 1 ))"
   MENUNEXT="$(( ${MENULEV} + 1 ))"
   MENUANS[${MENULEV}]="${1}"
   set_label
   return 0
}

################################################################
yesOrNo()
{
    TORF="0"
    putMessage "${1}..." "(Y/N)?"
    YORN="$( getch )"
    case _${YORN} in
        "_Y") TORF="0";;
        "_y") TORF="0";;
        "_N") TORF="1";;
        "_n") TORF="1";;
           *) TORF="1";;
    esac
    putMessage
    return ${TORF}
}
################################################################



   cnt_sleep
   drawEntry
   drawMenu
   entryScreen
   errend
   fillcol
   frenchMenus
   getAnswer
   getMenu
   getRecord
   header
   invalidKey
   justifyCenter
   justifyLeft
   mkrecord
   putAnswer
   putMessage
   removeRecord
   resetAnswer
   reset_level
   saveRecord
   scrnend
   selectRecord
   set_label
   set_level
   yesOrNo