STR
***
This is FASMLIB string library. It is rewrite of Fresh's string library (by
JohnFound, decard and roticv). It is intended to ease working with strings (one
of main drawbacks of low-level lanuages like asm or C)

I have decided to make this library required part of fasmlib, eg. it has to be
included and initalized for other modules to work. This is because many modules
work with strings, and without this we would need to check if library is
initalized in each such routine. And every bigger FASMLIB project would use it
anyway. In extreme case you CAN use some parts of FASMLIB without it (as much
of it as possible until efficient :] ), but lot of things won't works.

"string pointer" means "pointer to null-terminated ASCII string" in FASMLIB.

This library works with "string handles", which are not string pointers. String
handles are (dword) numbers from 0 to FFFFh returned by "str.new" and
"str.dup".  Higher numbers are treated as string pointers (discussion by the
EOF).  Advantage of this approach is that string buffers doesn't have maxmimal
size).  Disadvantage is that you have to call "str.ptr" to get string pointer
from string handle.

All strings represented by string handles are allocated using "mem" module.
Pointer to them are kept in table ("str.table"), which is allocated too. This
means you are not limited in number or size of strings.

NOTE: "mem" module should be initalized during entire usage of "str". it's
dependencies are not listed.



const STR_MINCOUNT
==================
desc:	minimum (and initial) number of strings in table
	default = 10
note:	- set it about minimum number of strings your program will use, if you
	know how much it is
	- each time there is need for more strings than can fit into table,
	then it is enlarged by 50%. Table never shrink again <TODO - call> 
	until you call "str.uninit"

const STR_MINSTRLEN
===================
desc:	minimum (and initial) string length
	default = 16
note:	- if you often use bigger strings than increase this value
	- each time string buffer needs to be larger, it is enlarged to needed
	size, but never shrinks again until you resize or delete it <TODO>

proc str.init
=============
desc:	initializes "str" module, creates string table (with place for 
	STR_MINCOUNT strings)
args:	none
ret:	CF = 1 on error
note:	- "mem" module must be already intialized

proc str.uninit
===============
desc:	uninitializes "str" module, deletes all created strings
args:	none
ret:	CF = 1 on error

proc str.new
============
desc:	creates new empty string
args:	none
ret:	CF = 1 on error, otherwise
	EAX = handle to new string
note:	don't forget to str.del returned string!

proc str.del        
============
desc:	deletes string
args:	hstring	- handle to string to delete
ret:	CF = 1 on error

proc str.ptr
============
desc:	gets pointer to string (string buffer) from handle, or returns 
	argument if it already is pointer
args:	string	- handle or pointer to string
ret:	CF = 1 on error, otherwise
	EAX = pointer to string
note:	- if your procedure takes string as argument, use this call to allow
	string handles too
	- works for string pointers even when "str" module isn't initialized

proc  str.len    
=============
desc:	returns length of string
args:	string	- handle or pointer to string
ret:	CF = 1 on error, otherwise
	EAX = length of string (not including ending zero byte, of course)
note:	works for string pointers even when "str" module isn't initalized

proc str.setlen 
===============
desc:	sets length of string buffer (not string)
args:	hstring	- handle to string (not pointer!)
	length	- new length of string
ret:	CF = 1 on error, otherwise
	EAX = pointer to resized string buffer (not string handle!)
note:	- pointer to string buffer is returned because you usually want to
	change string after resizing it

proc str.copy
=============
desc:	copies string handle or pointer into string handle
args:	hdest	- handle to destination string
	source	- handle or pointer to string which will be copied into hdest
ret:	CF = 1 on error, otherwise
	EAX = hdest (for use with nested macros)

proc str.dup
============
desc:	creates duplicate of string
args:	string	- handle or pointer to string to duplicate
ret:	CF = 1 on error, otherwise
	EAX = handle to newly created duplicate of string
note:	don't forget to str.del returned handle!

; proc  str.cat         hdest, source
; proc  str.catchar     hdest, char
; proc  str.insert      hdest, source, pos
; proc  str.inschar     hdest, char, pos
; proc  str.Lcase       string
; proc  str.Ucase       string
;
; proc  str.cmp         str1, str2
; proc  str.pos         string, pattern
; proc  str.charpos     string, char








DISCUSSION: Pointers in range 0-FFFFh cannot act as string pointers
-------------------------------------------------------------------
- there has to be way to internally differentiate handle from pointer
- mem.alloc always returns higher values
- code is run higher in memory on most systems.

Only problem is DOS, where data (theoretically) can be under 10000h, whether
placed in code or allocated using MS-DOS allocation. So to write code which
runs fine in DOS stick to following rules:
- preferably place inputed strings into buffers returned by mem.alloc before
  using them with str module
- don't place string constants into code (note that constant strings declared
  as arguments to libcall are created in data section (using "idata"))

DOS support isn't running now anyway, and i believe we will have this solved
somehow (there will have to be some mode_init routine anyway which will start
unreal mode there, so that one can copy data somewhere to >1Mb region if it is
under, or something).
