Galvin's Virtual Array

From Gwen Morse's Wiki
Jump to: navigation, search

Tinyfugue doesn't have any sort of built-in array functions. However, "Galvin" very kindly assembled this package. This array code is duplicated in Utilities (used to be "Mylib.tf").

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Virtual Array
;;;
;;; Originally submitted to the Tinyfugue mailing list by Galvin <kairo at mediaone dot net>
;;; Modfied by Michael Hunger <mh14 at inf.tu-dresden dot de>
;;; Modified by Regan @ Many MU's
;;; Possibly modified by other members of the Tinyfugue mailing list.
;;;
;;;
;;; You may store anything to be abbreviated in these lists, e.g. weapons,
;;; friends, npcs, scores etc.
;;;
;;; If you use text not containing other characters than letters, numbers and _
;;; you may also use this as an simple key-value hash list
;;; e.g. /set_array weapon s1 sword_with_a_very_long_id
;;;
;;; /def wield = /get_array weapon %1%;wield %?
;;;
;;; Usage:
;;; instead of: wield sword_with_a_very_long_id
;;; just use: /wield s1
;;;
;;; Some Examples:
;;; /test put_array('test_array', 1, 367382)
;;; /test put_array('test_array', 2, 'a string')
;;; /test echo(get_array('test_array', 1))
;;; /test echo(get_array('test_array', 2))
;;;
;;; You should see 367382 and a string echoed to your screen.
;;;
;;; Passing an array to a function
;;;
;;; /def function_array = \
;;; /test array1 := get_array({*}, 1) %;\
;;; /test array2 := get_array({*}, 2) %;\
;;; /test echo(strcat(array1, ':', array2))
;;;
;;; /test function_array('test_array')
;;;
;;; What I wrote here was just some stuff off the top of my head real quick.  Hope it helps.
;;; Oh and /listarray is a real good debuging tool, I use this as well. SO /listarray test_array should return:
;;; test_array[1]:=367382
;;; test_array[2]:=a string
;;; test_array[3]:=
;;;
;;; /listarray only lists up till a blank entry, I thought about using entry 0 as the # of elements but decided
;;; that some people may want to start arrays from 0 and not 1.
;;;
;;; Some get_array_count examples:
;
; /test put_array('halloween', 1, 'skeleton')
; /test put_array('halloween', 2, 'owls')
; /test put_array('halloween', 3, 'boo!')
;
; /test echo(get_array_count('halloween', 1))
; returns 3
; /test echo(get_array_count('halloween', 2))
; returns 2
;
; /test put_2array('double', 1, 1 , 'hmm')
; /test put_2array('double, 1, 2, 'burp!')
; /test put_2array('double, 1, 3, 'damn')
; /test echo(get_2array_count('double', 1, 1)
;
;;; Notes from Galvin
;
; I made some changes and added some new functions to arrays, 
; I overhauled the code as well.
;
; new functions
;
; tfwrite_array() : write an array to disk
; tfread_array() : read an array from disk
; strstr_array() : search for a string in an array
; list_array() was listarray() : good for debugging, lists arrays.
;
; changes:
;  strstr_array() replaces get_array_count()
;   x := (strstr_array("my array", 0, 1000, '"") -1) will do the same
;   thing as:
;   get_array_count("my array", 0)
;   strstr_array() returns -1 if it doesn't find the element
;
;  list_array now uses /listvar to get the data to list, it 
;  reformats it to make it look like the old listarray.
;
;------------------------------------------------------------------------
;Get array / get 2array : A virtual array function to similate a real array
;usage:
;get_array("Array name here", I) & get_2array("array name", I, I2)
;example get_array("Dir_Array", 43) returns the 43rd element from "Dir_Stack"
;
;------------------------------------------------------------------------
/def get_array = \
 /return _array_%1_%2

/def get_2array = \
 /return _array_%1_%2_%3

;------------------------------------------------------------------------
;PUT array / put 2array: A virtual array function to similate a real array
;usage:
;put_array("Array name here", I, st) & put_2array("array name", I, I2, st)
;example put_array("Dir_Array", 43, "sw") puts "sw" at element 43 in
;"Dir_Array"
;------------------------------------------------------------------------
/def put_array = \
 /IF (strlen({3}) > 0) \
   /set _array_%1_%2=%3%;\
 /ELSE \
   /unset _array_%1_%2%;\
 /ENDIF%;\

/def put_2array = \
 /IF (strlen({4}) > 0) \
   /set _array_%1_%2_%3=%4%;\
 /ELSE \
   /unset _array_%1_%2_%3%;\
 /ENDIF%;\

;------------------------------------------------------------------------
;PURGE array : Purges a virtual array made by get_array & put_array
;usage:
;purge_array("Array name here")
;example purge_array("Dir_Array"), deletes the whole array from memory
;NOTE: Purge array starts from element 0
;NOTE: this can also purge double dimensioned arrays too.
;------------------------------------------------------------------------
/def purge_array = \
 /quote -S /unset `/listvar -s _array_%1_*

;--------------------------------------------------------------------------
;listarray / list2array
;USAGE:
;/listarray array_name <num> & /list2array array_name <num> <num2>
;Will list the whole array of array_name starting from element <num>
;/list2array only lists the second dimension from <start>
;--------------------------------------------------------------------------
/def listarray = \
 /test LA_Count := %2 - 1%;\
 /test LA_Element := " "%;\
 /while (strlen(LA_Element) > 0) \
   /test ++LA_Count%;\
   /test LA_Element := get_array({1}, LA_Count)%;\
   /test echo(strcat({1}, "[", LA_Count, "]:=", LA_Element))%;\
 /DONE

/def list2array = \
 /test LA2_Count := -1%;\
 /test LA2_Element := " "%;\
 /while (LA2_Count < 255) \
   /test ++LA2_Count%;\
   /test LA2_Element := get_2array({1}, {2}, LA2_Count)%;\
   /IF (strlen(LA2_Element) > 0) \
     /test echo(strcat({1}, "[", {2}, "][", LA2_Count, "]:=", LA2_Element))%;\
   /ENDIF%;\
 /DONE

;--------------------------------------------------------------------------
; list_array() / list_2array()
;
; List an array in an easy to read format.
; USAGE:
; list_array("array_name", startindex)
; list_2array("array_name", startindex1, startindex2)
; /list_array <array_name> <startindex>
; /list_2array <array_name> <startindex1> <startindex2>
;
; "array_name" : Name of the array you want to list. (function form only)
; startindex   : Starting element you want to list from.
; startindex1  : Starting element of startindex2 you want to list from.
; startindex2  : Starting element of startindex1
;--------------------------------------------------------------------------
/def list_array = \
  /def list_array2 = \
    /test la_rawname := {1} %%;\
    /test la_name := {2} %%;\
    /test la_index := substr(la_rawname, strlen(la_name) + 8, 256) %%;\
    /IF (la_index >= {3}) \
      /test echo(strcat(la_name, '[', la_index, '] :=', get_array(la_name, la_index))) %%;\
    /ENDIF %;\
  /quote -S /test list_array2("`"/listvar -s _%1_array_*"", {1}, {2}) %;\
  /undef list_array2

/def list_2array = \
  /test la2_i2F := 0 %;\
  /def list_2array2 = \
    /test la2_rawname := {1} %%;\
    /test la2_name := {2} %%;\
    /test la2_rawindex := substr(la2_rawname, strlen(la2_name) + 8, 256) %%;\
    /test la2_pos := strstr(la2_rawindex, '_') %%;\
    /test la2_index1 := substr(la2_rawindex, 0, la2_pos) %%;\
    /test la2_index2 := substr(la2_rawindex, la2_pos + 1, 255) %%;\
    /IF (la2_index1 >= {3}) \
      /IF ( (la2_i2F = 0) & (la2_index2 >= {4}) )\
        /test la2_i2F := 1 %%;\
      /ENDIF %%;\
      /IF (la2_i2F = 1) \
        /test echo(strcat(la2_name, '[', la2_index1, '][', la2_index2, '] :=', get_2array(la2_name, la2_index1, la2_index2))) %%;\
      /ENDIF %%;\
    /ENDIF %;\
  /quote -S /test list_2array2("`"/listvar -s _%1_array_*"", {1}, {2}, {3}) %;\
  /undef list_2array2

;--------------------------------------------------------------------------
;GET array count / GET 2array count
; Written by: Ian Leisk who may actually be "Galvin", but, may not (kairo at attbi dot com)!
;usage:
;get_array_count("Array name here", start)
;get_2array_count("Array name here", index, start)
;
;NOTE:
;These will count the number of elements starting at "start" till the first
;empty element.
;Get_array2_count will count the number of elements starting at index
;from "start"
;--------------------------------------------------------------------------

/def get_array_count = \
  /test GA_Name := {1} %;\
  /test GA_Count := {2} - 1 %;\
  /test GA_Element := " " %;\
  /while (strlen(GA_Element) > 0) \
    /test ++GA_Count %;\
    /test GA_Element := get_array(GA_Name, GA_Count) %;\
  /DONE %;\
  /return GA_Count - 1

/def get_2array_count = \
  /test GA2_Name := {1} %;\
  /test GA2_Index := {2} %;\
  /test GA2_Count := {3} -1 %;\
  /test GA2_Element := " " %;\
  /while (strlen(GA2_Element) > 0) \
     /test ++GA2_Count %;\
     /test GA2_Element := get_2array(GA2_Name, GA2_Index, GA2_Count) %;\
  /DONE %;\
  /return GA2_Count - 1

;========================================================================
; tfwrite_array() / tfwrite_2array()
;
; Writes a virtual array to a disk file.
; USAGE:
; tfwrite_array(file_variable, "array_name", start_index, size)
; tfwrite_2array(file_variable, "array_name", index, start_index, size)
;
; file_variable : File variable of a tfopened file.
; "array_name"  : Name of the array.
; start_index   : The element you want to start writing from.
; index         : Start_index of index [first dimension] (tfwrite_2array only)
; Size          : Number of elements to write.
;
; NOTES: tfwrite_2array() can't write the whole array to disk.  You must
;        write each dimension at a time.
;========================================================================
/def tfwrite_array = \
  /let file_ %{1} %;\
  /let array_ %{2} %;\
  /let start_ %{3} %;\
  /let size_ %{4} %;\
  /let count_ 0 %;\
  /WHILE (++count_ <= size_) \
    /test tfwrite(file_, get_array(array_, start_)) %;\
    /test ++start_ %;\
  /DONE

/def tfwrite_2array = \
  /let file_ %{1} %;\
  /let array_ %{2} %;\
  /let index_ %{3} %;\
  /let start_ %{4} %;\
  /let size_ %{5} %;\
  /let count_ 0 %;\
  /WHILE (++count_ <= size_) \
    /test tfwrite(file_, get_2array(array_, index_, start_)) %;\
    /test ++start_ %;\
  /DONE

;========================================================================
; tfread_array() / tfread_2array()
;
; reads an array file from disk
; USAGE:
; x := tfread_array(file_variable, "array_name", start_index, size)
; x := tfread_2array(file_variable, "array_name", index, start_index, size)
;
; x             : Number of records read.
; file_variable : File variable of a tfopened file.
; "array_name"  : Name of the array.
; start_index   : Starting element you want to read into.
; index         : Start_index of index [first dimension] (tfread_2array only)
; size          : Number of elements to read.
;========================================================================
/def tfread_array = \
  /let file_ %{1} %;\
  /let array_ %{2} %;\
  /let start_ %{3} %;\
  /let size_ %{4} %;\
  /let count_ 0 %;\
  /let done_ 0 %;\
  /let err_ 0 %;\
  /let st_ 0 %;\
  /test st_ := '' %;\
  /WHILE (!done_) \
    /test err_ := tfread(file_, st_) %;\
    /IF ( (err_ != -1) & (count_ < size_) ) \
      /test put_array(array_, start_, st_) %;\
      /test ++count_ %;\
      /test ++start_ %;\
    /ELSE \
      /test done_ := 1 %;\
    /ENDIF %;\
  /DONE %;\
  /RETURN count_

/def tfread_2array = \
  /let file_ %{1} %;\
  /let array_ %{2} %;\
  /let index_ %{3} %;\
  /let start_ %{4} %;\
  /let size_ %{5} %;\
  /let count_ 0 %;\
  /let done_ 0 %;\
  /let err_ 0 %;\
  /let st_ 0 %;\
  /test st_ := '' %;\
  /WHILE (!done_) \
    /test err_ := tfread(file_, st_) %;\
    /IF ( (err_ != -1) & (count_ < size_) ) \
      /test put_2array(array_, index_, start_, st_) %;\
      /test ++count_ %;\
      /test ++start_ %;\
    /ELSE \
      /test done_ := 1 %;\
    /ENDIF %;\
  /DONE %;\
  /RETURN count_

;========================================================================
; strstr_array() / strstr_2array()
;
; Searches for a value in a virtual array and returns what element its found in.
; USAGE:
; x := strstr_array("array_name", start_index, size, value)
; x := strstr_2array("array_name", index, start_index, size, value)
;
; x             : Element of "array_name" that value was found in.
;                 -1 is returned if value was not found.
; "array_name"  : Name of the array.
; start_index   : Element to start searching at
; index         : Start_index of index [first dimension] (strstr_2arrat only).
; size          : Number of elements to search.
; value         : The item your searching for.
;
; NOTES: Strstr_2array can't search all dimensions, you must search each dimension
;        at a time.
;        If value = "" then it will return the first element that is blank.
;========================================================================
/def strstr_array = \
  /let array_ %{1} %;\
  /let start_ %{2} %;\
  /let size_ %{3} %;\
  /let value_ 0 %;\
  /test value_ := {4} %;\
  /let count_ 0 %;\
  /let pos_ 0 %;\
  /let st_ 0 %;\
  /test st_ := '' %;\
  /let element_ -1 %;\
  /WHILE ( (++count_ <= size_) & (element_ = -1) ) \
    /test st_ := get_array(array_, start_) %;\
    /IF (value_ =~ '') \
      /IF (st_ =~ '') \
        /test element_ := start_ %;\
      /ENDIF %;\
    /ELSE \
      /test pos_ := strstr(st_, value_) %;\
      /IF (pos_ > -1) \
        /test element_ := start_ %;\
      /ENDIF %;\
    /ENDIF %;\
    /test ++start_ %;\
  /DONE %;\
  /RETURN element_

/def strstr_2array = \
  /let array_ %{1} %;\
  /let index_ %{2} %;\
  /let start_ %{3} %;\
  /let size_ %{4} %;\
  /let value_ 0 %;\
  /test value_ := {5} %;\
  /let count_ 0 %;\
  /let pos_ 0 %;\
  /let st_ 0 %;\
  /let element_ -1 %;\
  /test st_ := '' %;\
  /WHILE ( (++count_ <= size_) & (element_ = -1) ) \
    /test st_ := get_2array(array_, index_, start_) %;\
    /IF (value_ =~ '') \
      /IF (st_ =~ '') \
        /test element_ := start_ %;\
      /ENDIF %;\
    /ELSE \
      /test pos_ := strstr(st_, value_) %;\
      /IF (pos_ > -1) \
        /test element_ := start_ %;\
      /ENDIF %;\
    /ENDIF %;\
    /test ++start_ %;\
  /DONE %;\
  /RETURN element_

;========================================================================
; searchstr_2array()
;
; Searches for a value in all dimensions of a virtual array and returns
; each element its found in. Multiple matches are put into a space-delimited
; list
; Modified by Regan @ Many MU's
;
; USAGE:
; x := searchstr_2array("array_name", index, start_index, size, value)
;
; x             : Element of "array_name" that value was found in.
;                 -1 is returned if value was not found.
; "array_name"  : Name of the array.
; start_index   : Element to start searching at
; index         : Start_index of index [first dimension] (strstr_2arrat only).
; size          : Number of elements to search.
; value         : The item your searching for.
;
;        If value = "" then it will return the first element that is blank.
;========================================================================

/def searchstr_2array = \
  /let array_ %{1} %;\
  /let index_ %{2} %;\
  /let start_ %{3} %;\
  /let size_ %{4} %;\
  /let value_ 0 %;\
  /test value_ := {5} %;\
  /let count_ 0 %;\
  /let pos_ 0 %;\
  /let st_ 0 %;\
  /let element_ -1 %;\
  /test blank_ := ' ' %;\
  /test list_ := '' %;\
  /test st_ := '' %;\
  /WHILE (++count_ <= size_) \
    /test st_ := get_2array(array_, start_, index_) %;\
    /IF (value_ =~ '') \
      /IF (st_ =~ '') \
        /test element_ := start_ %;\
        /IF (list_ =~ '') \
          /test list_ := element_ %;\
        /ELSE \
          /test temp_ := strcat(list_, blank_) %:\
          /test list_ := strcat(temp_, element_) %;\
        /ENDIF %;\
      /ENDIF %;\
    /ELSE \
      /test pos_ := strstr(st_, value_) %;\
      /IF (pos_ > -1) \
        /test element_ := start_ %;\
        /IF (list_ =~ '') \
          /test list_ := element_ %;\
        /ELSE \
          /test temp_ := strcat(list_, blank_) %;\
          /test list_ := strcat(temp_, element_) %;\
        /ENDIF %;\
      /ENDIF %;\
    /ENDIF %;\
    /test ++start_ %;\
  /DONE %;\
  /RETURN list_

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;