aboutsummaryrefslogtreecommitdiff
path: root/site/udo/string_tools.udo
diff options
context:
space:
mode:
authorRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
committerRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
commit9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 (patch)
tree291bd79ce340e67affa755a8a6b4f6a83cce93ea /site/udo/string_tools.udo
downloadapps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.gz
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.bz2
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.zip
initial
Diffstat (limited to 'site/udo/string_tools.udo')
-rwxr-xr-xsite/udo/string_tools.udo375
1 files changed, 375 insertions, 0 deletions
diff --git a/site/udo/string_tools.udo b/site/udo/string_tools.udo
new file mode 100755
index 0000000..c2c14c0
--- /dev/null
+++ b/site/udo/string_tools.udo
@@ -0,0 +1,375 @@
+#ifndef UDO_STRINGTOOLS
+#define UDO_STRINGTOOLS ##
+/*
+ String processing tools
+
+ This file is part of the SONICS UDO collection by Richard Knight 2021, 2022, 2023
+ License: GPL-2.0-or-later
+ http://1bpm.net
+
+*/
+
+#include "/host_platform.udo"
+
+/*
+ Replace character with another character or sequence of characters
+ Soutput str_replacechar Sinput, Sfrom, Sto
+
+ Soutput string with replacements
+ Sinput input string
+ Sfrom character to replace
+ Sto string or character to substitute
+*/
+opcode str_replacechar, S, SSS
+ Sinput, Sfrom, Sto xin
+ Soutput = ""
+ index = 0
+ while (index < strlen(Sinput)) do
+ Schar = strsub(Sinput, index, index + 1)
+ if (strcmp(Sfrom, Schar) == 0) then
+ Soutput = strcat(Soutput, Sto)
+ else
+ Soutput = strcat(Soutput, Schar)
+ endif
+ index += 1
+ od
+ xout Soutput
+endop
+
+
+/*
+ String alphabetical bubble sort
+ Sout[] srt_bubblestr Sin[]
+
+ Sout[] sorted array
+ Sin[] array to sort
+*/
+opcode srt_bubblestr, S[], S[]
+ Sin[] xin
+ Stemp = ""
+ ilen = lenarray(Sin)
+ index1 = 0
+ while (index1 < ilen-1) do
+ index2 = 0
+ while (index2 < ilen-1-index1) do
+ if (strcmp(Sin[index2], Sin[index2+1]) > 0) then
+ Stemp = Sin[index2]
+ Sin[index2] = Sin[index2+1]
+ Sin[index2+1] = Stemp
+ endif
+
+ index2 += 1
+ od
+ index1 += 1
+ od
+ xout Sin
+endop
+
+
+/*
+ Polynomial rolling hash
+ ihash str_hash Sstring
+
+ ihash the resulting hash value
+ Sstring string to be hashed
+*/
+opcode str_hash, i, S
+ Sin xin
+ ip = 31
+ im = 1e9+7 ; was 1e9+9, changed for 32bit
+ ipp = 1
+ ihash = 0
+ index = 0
+ while (index < strlen(Sin)) do
+ ihash = (ihash + ((strchar(strsub(Sin, index)) - 97) + 1) * ipp) ; changed from *ip to *ipp ??? due to collisions. not fully checked
+ ipp = (ipp * ip) % im
+ index += 1
+ od
+ xout ihash
+endop
+
+
+/*
+ Split separated string to array
+ Sitems[] str_split Sinput, Separator
+
+ Sitems[] the processed items
+ Sinput string to split
+ Separator separator to split on
+*/
+opcode str_split, S[], SS
+ Sin, Sep xin
+ Stemp = Sin
+ itemnum = 1
+ index = 1
+ while (index > 0) do
+ index strindex Stemp, Sep
+ if (index > 0) then
+ Stemp strsub Stemp, index+1
+ itemnum += 1
+ endif
+ od
+ Sout[] init itemnum
+
+ iwindex = 0
+ Stemp = Sin
+ index = 1
+ while (index > 0) do
+ index strindex Stemp, Sep
+ if (index > 0) then
+ Sout[iwindex] strsub Stemp, 0, index
+ Stemp strsub Stemp, index+1
+ else
+ Sout[iwindex] = Stemp
+ endif
+ iwindex += 1
+ od
+
+ xout Sout
+endop
+
+
+/*
+ Print ftable contents
+ printtable ifn
+
+ ifn ftable number to print
+*/
+opcode printtable, 0, i
+ ifn xin
+ index = 0
+ while (index < ftlen(ifn)) do
+ print table:i(index, ifn)
+ index += 1
+ od
+endop
+
+
+
+/*
+ Store string to an exising table as ascii characters
+ str2tab String, ifn
+
+ String string to store
+ ifn table to store to
+*/
+opcode str2tab, 0, Si
+ String, ifn xin
+ index = 0
+ while (index < strlen(String)) do
+ ival strchar String, index
+ tabw_i ival, index, ifn
+ index += 1
+ od
+ tabw_i -99, index, ifn
+endop
+
+
+/*
+ Create a table and store a string in it as ascii characters
+ ifn str2newtab String
+
+ ifn new table number
+ String string to store
+*/
+opcode str2newtab, i, S
+ String xin
+ ifn ftgen 0, 0, strlen(String)+1, 7, 0
+ str2tab String, ifn
+ xout ifn
+endop
+
+
+/*
+ Obtain a string from a table containing ascii characters
+ String tab2str ifn
+
+ String retrieved string
+ ifn table number
+*/
+opcode tab2str, S, i
+ ifn xin
+ index = 0
+ Sval = ""
+ ival = 0
+ while (ival != -99) do
+ ival tab_i index, ifn
+ if (ival == -99) igoto done
+ Sval strcat Sval, sprintf("%c", ival)
+ index += 1
+ od
+done:
+ xout Sval
+endop
+
+
+/*
+ Obtain file extension converted to lowercase (anything past the last dot)
+ Sextension fileextension Sfile
+
+ Sfile path or filename
+ Sextension the extension in lower case
+*/
+opcode fileextension, S, S
+ Sfile xin
+ ilastdot strrindex Sfile, "."
+ if (ilastdot == -1) then
+ Sextension = "none"
+ goto return
+ endif
+ ilen strlen Sfile
+ Sextension strsub Sfile, ilastdot + 1, ilen
+ Sextension strlower Sextension
+ goto return
+return:
+ xout Sextension
+endop
+
+
+/*
+ Print a string array with each value separated by a newline
+
+ str_printarray Sarray[]
+
+ Sarray[] the array to print
+*/
+opcode str_printarray, 0, S[]
+ Sarray[] xin
+ ilen = lenarray(Sarray)
+ index = 0
+ while (index < ilen) do
+ prints sprintf("%s\n", Sarray[index])
+ index += 1
+ od
+endop
+
+
+/*
+ Test if a string is numeric
+
+ isnumeric str_isnumeric Svalue
+
+ isnumeric 0 if not numeric, 1 if numeric
+ Svalue string to test
+*/
+opcode str_isnumeric, i, S
+ Svalue xin
+ isnumeric = 1
+ ihaspoint = 0
+ index = 0
+ while (index < strlen(Svalue)) do
+ ichar = strchar(Svalue, index)
+
+ ; allow only one decimal point
+ if (ichar == 46) then
+ if (ihaspoint == 1) then
+ isnumeric = 0
+ goto complete
+ else
+ ihaspoint = 1
+ endif
+
+ ; not a number or decimal place
+ elseif (!(ichar >= 48 && ichar <= 57)) then
+ isnumeric = 0
+ goto complete
+ endif
+ index += 1
+ od
+complete:
+ xout isnumeric
+endop
+
+
+
+/*
+ Convert a string to float if numeric
+
+ ivalid, ivalue try_strtod Svalue
+
+ ivalid 0 if the input is not numeric, 1 if conversion is successful
+ ivalue converted value, or -1 if the input is not numeric
+*/
+opcode try_strtod, ii, S
+ Svalue xin
+ if (str_isnumeric(Svalue) == 0) then
+ ivalid = 0
+ ivalue = -1
+ else
+ ivalid = 1
+ ivalue = strtod(Svalue)
+ endif
+ xout ivalid, ivalue
+endop
+
+
+/*
+ Get the basename from a file path separated by slashes
+
+ Sbasename str_basename Spath
+
+ Sbasename the filename
+ Spath the path
+*/
+opcode str_basename, S, S
+ Spath xin
+ Sbasename = strsub(Spath, strrindex(Spath, "/") + 1)
+ xout Sbasename
+endop
+
+
+/*
+ Get a random alphanumeric string
+
+ Sout str_random [ilen=10]
+
+ Sout the random string
+ ilen length of string
+*/
+opcode str_random, S, j
+ ilen xin
+ Sout = ""
+ ilen = (ilen == -1) ? 10 : ilen
+ index = 0
+ while (index < ilen) do
+ irange = round(random(0, 2))
+ if (irange == 0) then
+ ichar random 48, 57
+ elseif (irange == 1) then
+ ichar random 65, 90
+ elseif (irange == 2) then
+ ichar random 97, 122
+ endif
+ Sout = strcat(Sout, sprintf("%c", ichar))
+ index += 1
+ od
+ xout Sout
+endop
+
+/*
+ Get a random filename
+
+ Sout str_randomfilename Sext [,ilen=10]
+
+ Sout the random filename
+ Sext file extension
+ ilen length of string
+*/
+opcode str_randomfilename, S, Sj
+ Sext, ilen xin
+ Sfile str_random ilen
+ xout strcat(Sfile, sprintf(".%s", Sext))
+endop
+
+/*
+ Get a random filename in the host temporary directory
+
+ Sout str_randomtempfilename Sext [,ilen=10]
+*/
+opcode str_randomtempfilename, S, Sj
+ Sext, ilen xin
+ Sfile str_randomfilename Sext, ilen
+ xout sprintf("%s/%s", host_tempdir(), Sfile)
+endop
+
+#end