;;; commands for manipulating space-separated lists of index-data pairs.
; $Id: pairlist.tf,v 1.1 1996/11/20 15:01:15 asm21 Exp $
;;; Note that this means you can't have multiple-word keys or values.
/~loaded pairlist.tf
;; get the associated data for a particular index.
;; all the following functions assume that the given key name is unique, and
;; their behaviour is undefined if this is not the case. :P
;; /getpair [-i]
;; where is the start of the key you want the value of, and
;; is the name of the variable containing the list.
;;
;; If you specify the -i flag, the search will be case-insensitive.
;;
;; returns (using /echo) ERR on an error, or the data value otherwise.
;; /addpair
;; Adds a pair to the list
;; /listpairs
;; Lists the pairs contained in the list
;; /removepair
;; Removes the specified pair from the list. This function requires the
;; *exact* keyname, both in length and in case.
/def -i getpair= \
/if (%1 =~ "-i") \
/let case=no%; \
/shift%; \
/else \
/let case=yes%; \
/endif%; \
/if (%# == 2) \
/let idx=%1%; \
/if (case =~ "no") /let idx=$[tolower(idx)]%; /endif%; \
/let data=%2%; \
/let data=$(/eval /eval /echo %%{%{data}})%; \
/let rv=%; \
/while (data !~ "") \
/let sp=$[strchr(data, " ")]%; \
/let key=$[substr(data, 0, sp)]%; \
/if (case =~ "no") /let key=$[tolower(key)]%; /endif%; \
/let data=$[substr(data, sp + 1)]%; \
/let sp=$[strchr(data, " ")]%; \
/if (sp == -1) /let sp=$[strlen(data)]%; /endif%; \
/let dat=$[substr(data, 0, sp)]%; \
/let data=$[substr(data, sp + 1)]%; \
; if this is an exact match, stop.
/if (key =~ idx) \
/let rv=%{dat}%; \
/let data=%; \
/endif%; \
; if it is a perfix match, record it, but carry on anyway.
/if (substr(key, 0, strlen(idx)) =~ idx) \
/let rv=%{dat}%; \
/endif%; \
/done%; \
/eval /echo - %{rv-ERR}%; \
/else \
/echo ERR%; \
/endif
/def -i addpair= \
/if (%# == 3) \
/eval /eval /set %1=%%{%1} %2 %3%; \
/else \
/echo % Incorrect Parameters.%; \
/endif
/def -i getfullkeyname = \
/if (%1 =~ "-i") \
/let case=no%; \
/shift%; \
/else \
/let case=yes%; \
/endif%; \
/if (%# == 2) \
/let idx=%2%; \
/if (case =~ "no") /let idx=$[tolower(idx)]%; /endif%; \
/let data=%1%; \
/let data=$(/eval /eval /echo %%{%{data}})%; \
/let rv=%; \
/while (data !~ "") \
/let sp=$[strchr(data, " ")]%; \
/let key=$[substr(data, 0, sp)]%; \
/let prettykey=%{key}%; \
/if (case =~ "no") /let key=$[tolower(key)]%; /endif%; \
/let data=$[substr(data, sp + 1)]%; \
/let sp=$[strchr(data, " ")]%; \
/if (sp == -1) /let sp=$[strlen(data)]%; /endif%; \
/let data=$[substr(data, sp + 1)]%; \
; if this is an exact match, stop.
/if (key =~ idx) \
/let rv=%{prettykey}%; \
/let data=%; \
/endif%; \
; if it is a prefix match, record it, but carry on anyway.
/if (substr(key, 0, strlen(idx)) =~ idx) \
/let rv=%{prettykey}%; \
/endif%; \
/done%; \
/eval /echo %{rv}%; \
/endif
/def -i removepair = \
/if (%# == 2) \
/let idx=%2%; \
/let data=%1%; \
/let data=$(/eval /eval /echo %%{%{data}})%; \
/let newdata=%; \
/let removed=0%; \
/while (data !~ "") \
/let sp=$[strchr(data, " ")]%; \
/let key=$[substr(data, 0, sp)]%; \
/let data=$[substr(data, sp + 1)]%; \
/let sp=$[strchr(data, " ")]%; \
/if (sp == -1) /let sp=$[strlen(data)]%; /endif%; \
/let dat=$[substr(data, 0, sp)]%; \
/let data=$[substr(data, sp + 1)]%; \
/if (key !~ idx) \
/let newdata=%{newdata} %{key} %{dat}%; \
/else \
/let removed=1%; \
/endif%; \
/done%; \
/if (removed) \
; we get a leading space, so...
/if (newdata !~ "") /let newdata=$[substr(newdata, 1)]%; /endif%; \
/set %1=%{newdata}%; \
/else \
/eval /echo %% Keyname %2 not found!%; \
/endif%; \
/else \
/echo % Incorrect number of arguments.%; \
/endif
/def -i listpairs = \
/let data=%1%; \
/let data=$(/eval /eval /echo %%{%{data}})%; \
/let max=0%; \
/while (data !~ "") \
/let sp=$[strchr(data, " ")]%; \
/if (sp > max) /let max=%{sp}%; /endif%; \
/let data=$[substr(data, sp + 1)]%; \
/let sp=$[strchr(data, " ")]%; \
/if (sp == -1) /let sp=$[strlen(data)]%; /endif%; \
/let data=$[substr(data, sp + 1)]%; \
/done%; \
/foreachpair %1 /echo - %%{key}$$[strrep(" ", max - strlen(key))] --> %%{dat}
;; ========== Helper macros
;; /foreachpair
;; calls once for each pair, with the key in %{key} and
;; the data in %{dat}.
;; *** REMEMBER to double all symbols like % and $ ***
;; Note that /let, being scoped, doesn't work that well within this
;; construct.
/def -i foreachpair = \
/let data=%1%; \
/shift%; \
/let data=$(/eval /eval /echo %%{%{data}})%; \
/while (data !~ "") \
/let sp=$[strchr(data, " ")]%; \
/let key=$[substr(data, 0, sp)]%; \
/let data=$[substr(data, sp + 1)]%; \
/let sp=$[strchr(data, " ")]%; \
/if (sp == -1) /let sp=$[strlen(data)]%; /endif%; \
/let dat=$[substr(data, 0, sp)]%; \
/let data=$[substr(data, sp + 1)]%; \
/eval %*%; \
/done
               (
geocities.com/goldmooneachna)