Re: Standard toolkit
- Posted by akusaya at gmx.net Jul 02, 2005
- 581 views
J> Can anyone tell me what (non-RDS) library files besides J> Win32Lib that they use regularly in their projects? I'm mostly J> asking about utility functions, not graphics libraries and such. J> Stuff like print.e, sprint.e, tk_*.e, etc. Include your own J> libraries that you may not have released to the archive. J> Some other questions: J> * If this library is in the archive and you're a registered J> user, have you voted microbucks for it? J> * If this library is not in the archive, why not? Having used Eu for 5 years, nearly all projects I made always include a file I made as standard library. So I think Eu standard library is very important. So I translated the include file to English and removed a lot of routines that I think would not be too useful for the others. The file is below. Some of the routines are obtained from Euforum, but sorry I didn't keep the original author names. A lot of routines are still missing. I think these routines need to be included in the standard library project: - copy/rename/move/delete/rmdir functions, USING WIN32 API and LINUX SYSTEM CALLS instead of system("del " & filename,0) which I hate very much (personally) since it's not reliable - *simple* hash map/set, like hash_set(key, value), hash_get(key, default_value), hash_find(key), etc - date/time library, like datetime.e by CyrekSoft If you think that my file below is suitable for inclusion, please include it in the Std Library project, but since there is some performance problems, please optimize it. Looking forward for your suggestions, etc! -- Standard Library ... by Aku 2000-2004 -- Renewed in 2005 to use English and for general public -- Removed a lot of unused routines include dll.e include get.e include wildcard.e include file.e --------------------------------------------------------------------- --------------------------------------------------------------------- object pppath if platform() = 3 then pppath = '/' else pppath = '\\' end if object xGetTickCount, xSleep if platform() = WIN32 then xGetTickCount = define_c_func(open_dll("kernel32"), "GetTickCount", {}, C_LONG) xSleep = define_c_proc(open_dll("kernel32"), "Sleep", {C_ULONG}) end if --------------------------------------------------------------------- --# String / Sequence --------------------------------------------------------------------- -- left(string st, int n) -- same as left() on VB, returns the first /n chars of st, if /n > length(/st) -- then /st is returned global function left(sequence st, atom n) if n >= length(st) then return st else return st[1..n] end if end function -- mid(string st, int start, int len) -- same as mid() on VB, returns the /len chars of /st starting from -- position /start. If /len = -1, /st[/start..length(/st)] is returned. global function mid(sequence st, atom start, atom len) if start > length(st) then return "" elsif len = 0 or len <= -2 then return "" elsif start+len-1 > length(st) then return st[start..length(st)] elsif len = -1 then return st[start..length(st)] elsif len+start-1 < 0 then return "" elsif start < 1 then return st[1..len+start-1] else return st[start..len+start-1] end if end function -- slice(string st, int start, int stop) -- returns /st[/start../stop] but takes care of invalid subscript global function slice(sequence st, atom start, atom stop) if stop = -1 then stop = length(st) end if if start < 1 then start = 1 end if if stop > length(st) then stop = length(st) end if if start > stop then return "" end if return st[start..stop] end function -- vslice(sequence s, int colno) -- vertical slicing -- for example, if /s = {{1,2}, {3,4}} and /colno = 2, -- then vslice(s, colno) = {2,4} global function vslice(sequence s, atom colno) sequence ret ret = {} for i = 1 to length(s) do ret = append(ret, s[i][colno]) end for return ret end function -- right(string st, int n) -- same as right() on VB, returns the last /n chars of st, if /n > length(/st) -- then /st is returned global function right(sequence st, atom n) if n >= length(st) then return st else return st[length(st)-n+1..length(st)] end if end function -- instr(int start, string st1, string st2) -- same as instr() in VB -- Basically it's match(st2, /st1[start..length(/st1)]), -- but if st2 = "", will return 1 global function instr(atom start, sequence st1, sequence st2) integer pos if start > length(st1) then return 0 elsif equal(st2, {}) then return 1 else pos = match(st2, st1[start..length(st1)]) if pos then return pos + start - 1 else return 0 end if end if end function -- instr_nc(int start, string st1, string st2) -- non case sensitive version of instr() global function instr_nc(atom start, sequence st1, sequence st2) return instr(start, lower(st1), lower(st2)) end function -- split(string st, string delim) -- splits /st to sequence of strings -- example: split("abacbabacaaba", "ba") = {"a", "c", "", "caa", ""} global function split(sequence st, sequence delim) sequence ret object pos ret={} while 1 do pos = match(delim, st) if pos then ret = append(ret, st[1..pos-1]) st = st[pos+length(delim)..length(st)] else exit end if end while ret = append(ret, st) return ret end function -- join(sequence s, string delim) -- joins /s to the original string -- example: join({"1", "23"}, "_") = "1_23" global function join(sequence s, object delim) object ret if not length(s) then return "" end if ret = "" for i=1 to length(s)-1 do ret &= s[i] & delim end for ret &= s[length(s)] return ret end function -- replace(string st, string sfind, string sreplace) -- replaces every occurence of /sfind in /st with /sreplace global function ganti(sequence st, sequence sfind, sequence sreplace) atom pos, a pos = 1 while 1 do a = instr(pos, st, sfind) if not a then exit end if st = st[1..a-1] & sreplace & st[length(sfind)+a..length(st)] pos = a+length(sreplace) end while return st end function -- part(sequence s, int pos) -- simply returns /s[/pos] with error handling -- useful for emulating: func(something)[pos] which is not a legal syntax in eu -- in that case, use: part(func(something), pos) global function part(object s, atom pos) if atom(s) then return s end if if length(s) = 0 then return 0 end if if pos > length(s) then return s[length(s)] end if if pos < 1 then return s[1] end if return s[pos] end function -- remove_dup(sequence s) -- remove duplicates in s global function remove_dup(sequence s) object mark, ret mark = repeat(1, length(s)) for i = 1 to length(s)-1 do for j = i+1 to length(s) do if equal(s[i], s[j]) then mark[j] = 0 end if end for end for ret = {} for i = 1 to length(mark) do if mark[i] then ret = append(ret, s[i]) end if end for return ret end function -- seq_insert(int at, sequence s, object new) -- inserts /new at position /at to /s global function seq_insert(integer at, sequence s, object new) s &= 0 s[at+1..length(s)] = s[at..length(s)-1] s[at] = new return s end function -- seq_remove(object at, sequence s) -- removes element(s) in position(s) /at from /s -- /at can be an int or an {int from, int to} global function seq_remove(object at, sequence s) if atom(at) then at = {at,at} end if s = s[1..at[1]-1] & s[at[2]+1..length(s)] return s end function -- shuffle(sequence s) -- changes the order of elements of /s randomly global function shuffle(sequence s) object temp integer j for i = length(s) to 2 by -1 do j = rand(i) temp = s[j] s[j] = s[i] s[i] = temp end for return s end function -- find_all(sequence s, object sfind) -- returns positions of matching elements -- example: find_all({1,9,3,9,9}, 9) = {2,4,5} global function find_all(sequence s, object ofind) object ret ret = {} for i=1 to length(s) do if equal(ofind, s[i]) then ret &= i end if end for return ret end function -- vfind(object ofind, sequence o, atom colno) -- vertical find. -- finds /sfind in column /colno of /o global function vfind(object ofind, sequence o, atom colno) for i=1 to length(o) do if equal(ofind, o[i][colno]) then return i end if end for return 0 end function -- trim(string st) -- removes \n, \r, \t, and spaces from beginning and end of /st global function trim(sequence st) object p p = 0 for i = 1 to length(st) do if find(st[i], "\n\r\t ") then p = i else exit end if end for st = st[p+1..length(st)] p = length(st)+1 for i = length(st) to 1 by -1 do if find(st[i], "\n\r\t ") then p = i else exit end if end for st = st[1..p-1] return st end function -- is_string(object o) -- determines whether /o is a sequence with atom (>=32 and <=255) -- or in "\n\r\t" as its elements global function is_string(object o) if sequence(o) then for i=1 to length(o) do if sequence(o[i]) then return 0 elsif not ((o[i] >= 32 and o[i] <= 255) or find(o[i], "\n\r\t")) then return 0 end if end for return 1 end if return 0 end function --------------------------------------------------------------------- --# Pretty Printing --------------------------------------------------------------------- object euob_tmp procedure euob_makeString(object o) sequence ret ret = "\"" for i = 1 to length(o) do if o[i] = '\t' then ret &= "\\t" elsif o[i] = '\n' then ret &= "\\n" elsif o[i] = '\r' then ret &= "\\r" elsif o[i] = '"' then ret &= "\\\"" elsif o[i] = '\'' then ret &= "\\'" elsif o[i] = '\\' then ret &= "\\\\" else ret &= o[i] end if end for ret &= "\"" euob_tmp &= ret end procedure procedure euob_do(object o) if atom(o) then euob_tmp &= sprintf("%.12g", o) elsif is_string(o) then euob_makeString(o) else euob_tmp &= "{" for i = 1 to length(o) do euob_do(o[i]) if i != length(o) then euob_tmp &= ", " end if end for euob_tmp &= "}" end if end procedure -- euob(object o) -- returns a string representation of an Eu object /o global function euob(object o) euob_tmp = "" euob_do(o) return euob_tmp end function --------------------------------------------------------------------- --# File and I/O --------------------------------------------------------------------- -- file_length(string filename) -- return length of file /filename. -- if not found, returns -1 global function file_length(sequence filename) object list list = dir(filename) if atom(list) or length(list) = 0 then return -1 end if return list[1][D_SIZE] end function -- file_path(string st) -- returns the 'directory' name of a file -- supports \ for win/dos and / for linux/http etc global function file_path(sequence st) object ppdi, ppdi2 st = reverse(st) ppdi = find('\\', st) ppdi2 = find('/', st) if length(find_all('\\', st)) = 1 and st[length(st)] = '\\' then return "\\" elsif length(find_all('/', st)) = 1 and st[length(st)] = '/' then return "/" end if if ppdi=0 and ppdi2=0 then return reverse(st) elsif ppdi=0 then return reverse(st[ppdi2+1..length(st)]) elsif ppdi2=0 then return reverse(st[ppdi+1..length(st)]) elsif ppdi < ppdi2 then return reverse(st[ppdi+1..length(st)]) elsif ppdi2 <= ppdi then return reverse(st[ppdi2+1..length(st)]) end if end function -- file_name(string st) -- returns the 'file' name of a file -- supports \ for win/dos and / for linux/http etc global function file_name(sequence st) object ppdi, ppdi2 st = reverse(st) ppdi = find('\\', st) ppdi2 = find('/', st) if ppdi=0 and ppdi2=0 then return reverse(st) elsif ppdi=0 then return reverse(st[1..ppdi2-1]) elsif ppdi2=0 then return reverse(st[1..ppdi-1]) elsif ppdi < ppdi2 then return reverse(st[1..ppdi-1]) elsif ppdi2 <= ppdi then return reverse(st[1..ppdi2-1]) end if end function -- read_file(object f) -- returns the contents of file /f -- /f can be a filename or a file number as returned by open() -- -1 is returned if failed global function read_file(object f) object fn, ret, kar, len if sequence(f) then len = file_length(f) if len = 0 then return "" elsif len < 0 then return -1 end if ret = repeat(0, len) fn = open(f, "rb") if fn < 0 then return -1 end if for i = 1 to len do ret[i] = getc(fn) end for close(fn) else ret = "" while 1 do kar = getc(f) if kar != -1 then ret &= kar else exit end if end while end if return ret end function -- read_lines(string f) -- get lines of file /f as sequence of strings -- /f can be filename or file number as returned from open() -- \r in end of lines are discarded -- blank lines are ignored -- -1 if failed global function read_lines(sequence f) object fn, ret, y ret = {} if sequence(f) then fn = open(f, "r") else fn = f end if if fn < 0 then return -1 end if while 1 do y = gets(fn) if atom(y) then exit end if if length(y) then if y[length(y)] = '\r' then y = y[1..length(y)-1] end if ret = append(ret, y) end if end while if sequence(f) then close(fn) end if return ret end function -- write_lines(object f, sequence s) -- write lines to file, opposite of read_lines global procedure write_lines(object f, sequence s) object fn if sequence(f) then fn = open(f, "w") else fn = f end if for i=1 to length(s) do puts(fn, s[i]) puts(fn, "\n") end for if sequence(f) then close(fn) end if end procedure -- write_file(object f, string s) -- write all contents to file, opposite of read_file global procedure write_file(object f, sequence s) object fn if sequence(f) then fn = open(f, "wb") else fn = f end if if fn = -1 then return end if puts(fn, s) if sequence(f) then close(fn) end if end procedure -- read_val(int fn) -- reads a Eu object from file number /fn -- equals value(get(/fn))[2] global function getval(atom fn) object temp temp = get(fn) return temp[2] end function -- merge_path(string path, string file) -- merges the /file to its /path. -- example: on win32, merge_path("c:\\abc", "def") = "c:\\abc\\def" -- takes care of excessive slashes global function merge_path(sequence path, sequence file) if length(path) = 0 then return file end if if path[length(path)] = pppath then path = path[1..length(path)-1] end if if length(file) = 0 then return path end if if file[1] = pppath then file = file[2..length(file)] end if return path & pppath & file end function -- file_type(string filename) -- returns 0 if /filename does not exist -- returns 1 if /filename is a file -- returns 2 if /filename is a directory global function file_type(sequence filename) object dirfil if find('*', filename) or find('*', filename) then return 0 end if if length(filename) = 2 and filename[2] = ':' then filename &= "\\" end if dirfil = dir(filename) if sequence(dirfil) then if find('d', dirfil[1][2]) or (length(filename)=3 and filename[2]=':') then return 2 else return 1 end if else return 0 end if end function --------------------------------------------------------------------- --# Sequence Math --------------------------------------------------------------------- -- abs(object o) -- returns absolute value of /o global function abs(object o) return ((o>0)*2-1) * o end function -- sum(object o) -- returns the sum of all atoms in /o and inside /o global function sum(object o) object hs if atom(o) then return o else hs = 0 for i = 1 to length(o) do hs += sum(o[i]) end for end if return hs end function -- max(sequence s) -- returns the index of the element having maximum value global function max(sequence s) object maxi, maxn maxi = 0 maxn = -9e999 for i = 1 to length(s) do if s[i] > maxn then maxn = s[i] maxi = i end if end for return maxi end function -- min(sequence s) -- returns the index of the element having minimum value global function min(sequence s) object mini, minn mini = 0 minn = 9e999 for i = 1 to length(s) do if s[i] < minn then minn = s[i] mini = i end if end for return mini end function -- range(object o, object min, object max) -- returns true if o is between min and max inclusive global function range(object o, object min, object max) return (o >= min) and (o <= max) end function --------------------------------------------------------------------- --# Timing --------------------------------------------------------------------- -- timer() -- functions same as time() but with 1/1000 resolution on Win32 global function timer() if platform() = 2 then return (c_func(xGetTickCount, {})/1000) else return time() end if end function -- stop(atom ms) -- stops execution of the program by /ms milliseconds global procedure stop(atom ms) atom start if ms < 0 then ms = 0 end if if platform() = WIN32 then c_proc(xSleep, {ms}) else start = timer() while 1 do if timer()-start >= (ms/1000) then exit end if end while end if end procedure --------------------------------------------------------------------- --# Misc --------------------------------------------------------------------- -- val(string o) -- returns value(/o)[2] global function val(sequence o) object tp tp = value(o) return tp[2] end function -- iif(atom v, object iftrue, object iffalse) -- Inline if. -- will return /iftrue if /v, or /iffalse if not /v. global function kalo(atom v, object iftrue, object iffalse) if v then return iftrue end if return iffalse end function