|
Post by barryk on Feb 18, 2018 1:26:51 GMT 1
This code used to work, a long long time ago:
DECLARE arr1 TYPE char*
sendstr$="timeout60:myapp"
arr1=sendstr$ off1=INSTR(arr1,":") IF off1=0 THEN END arr1[off1-1]=0 field1$=arr1 off2=INSTR(arr1+off1,":") arr1[off1+off2-1]=0 field2$=arr1+off1
I don't recall the last version of BaCon when this worked. 2.0.3 definitely.
It is the last line that segfaults, with BaCon 3.7.1.
The code is simple. It assigns "timeout60" to field1$, and "myapp" to field2$.
The line 'arr1[off1-1]=0' replaces the ":" with a numeric zero. As there is no second ":", off2=0, so 'arr1[off1+off2-1]=0' writes 0 in same place as before.
So, arr1+off1 will point to the start of "myapp".
...except that it segfaults.
|
|
|
Post by Pjot on Feb 18, 2018 8:51:42 GMT 1
Hi barry, The reason that your code now fails has to do with the String Optimization engine implemented in BaCon. To summarize, for performance reasons, all regular strings should be pointed to by an odd address, so BaCon can identify string- and buffer length. The last line of your code assigns a pointer address back to a string, and BaCon now takes the bytes just before that position as parameters for these lengths. This causes an undefined large range to handle. As a quick woraround, you can change the last line of your code as follows: field2$=strdup(arr1+off1)
However, note that BaCon now has a very strong delimited string engine of which the API was proposed by forum member vovchik. To achieve your results, the following code will do the same: sendstr$ = "timeout60:myapp" IF NOT(TALLY(sendstr$, ":")) THEN END field1$ = TOKEN$(sendstr$, 1, ":") field2$ = TOKEN$(sendstr$, 2, ":")
HTH Peter
|
|
|
Post by barryk on Feb 18, 2018 10:00:51 GMT 1
Thanks very much, TALLY and TOKEN look great!
EDIT: Ah, no, have just realised that TOKEN will not do it for me.
Looking at that code in the program that it came from, there is also field3$, which is the third field.
But, that third field is allowed to have ":" chars in it.
so, sendstr$="timeout60:myapp:this is: third field: colons allowed"
The code is supposed to extract field3$="this is: third field: colons allowed"
So, I have done it this way:
DECLARE arr1 TYPE char*
sendstr$="timeout60:myapp:message allowed : in it"
arr1=sendstr$ off1=INSTR(arr1,":") IF off1=0 THEN END arr1[off1-1]=0 field1$=arr1 off2=INSTR(arr1+off1,":") arr1[off1+off2-1]=0
'field2$=arr1+off1 field2$=strdup(arr1+off1)
IF off2>0 THEN 'the message-part can have ":" chars in it... 'message$=arr1+off1+off2 message$=strdup(arr1+off1+off2) ENDIF
Thanks for the info!
But, if the second field of TOKEN can take a range, like the 'cut' utility (cut -f 3- -d ':')...
|
|
|
Post by Pjot on Feb 18, 2018 16:04:46 GMT 1
Hi barry, Well, also that situation can be easily solved with delimited string functions. Please take a look at the LAST$ function. Best regards Peter sendstr$ = "timeout60:myapp:this is: third field: colons allowed"
IF NOT(TALLY(sendstr$, ":")) THEN END
field1$ = TOKEN$(sendstr$, 1, ":")
field2$ = TOKEN$(sendstr$, 2, ":")
IF AMOUNT(sendstr$) > 2 THEN field3$ = LAST$(sendstr$, 2, ":")
|
|