How to copy strings using bytemove (Spin,Flexprop) ?
pik33
Posts: 2,387
in Propeller 2
I wrote a method to copy one string into another (inserting a short string into a longer one, replacing the old content of the destination)
It works.
pub strcpy(sto,sfrom,ifrom,count) |i repeat i from 0 to count-1 byte[sto+ifrom+i]:=byte[sfrom+i]
I tried to use bytemove to achieve the same results, without success. (and with strange side effects instead)
Is it possible to replace the loop with bytemove? If yes, how?
Comments
I would try it like that:
Andy's example will work. I've not (yet) needed to instert a string, but I often replace one with another. I do it like this
The +1 ensures that the terminating 0 is also copied so we don't end up with fragments of the original string. Of course, p_dest must be the same length or larger than p_src.
If count is the length of the string AND the zero at the end, Ariba's code is all you need, otherwise you will need to take other steps to ensure the zero-termination.
I clear my entire destination buffer to zeros first, then copy the actual string. This ensures that I have the zero termination, and makes me think about whether I've done something stupid like copy a string that's longer than the buffer.
One of my big gotchas was copying a string that wasn't zero terminated, after setting count from strsize() and getting a length of who-knows-what!
This didn't work, inserting garbage into the string. It seems I have to try this in a clean environment, and, if it still fails, report a bug, else find a bug in my code.
Here is some code I use for handling strings on the P1. It should easily adapt to P2
`
pub NewString 'Clear the string buffer
pub AddString(str) |StrLen, BufCap
pub CopyString(str)
`
The arguments for your method aren't clear. I took ifrom to mean how far from the beginning of the source string to start the copy process. It works.
One potential source of 'garbage' is this:
I have a string in the array String[256]..
If I call AddString(String) I will get a whole lot of garbage from whatever the first 4 bytes of my string point to when interpreted as a LONG
If I call AddString(@String) I will properly pass the address of String, which will result in correct operation.
I looked up the C version of strcpy().
To duplicate that in Spin you would do this:
The +1 with strsize() ensures that the terminating 0 is copied as well. I suggest you simplify your version like this:
It's just a wrapper, but may make your code easier for others to understand.
Yes. When dealing with strings, you always have to deal with their addresses.
Winners don't do
strcpy
(unless they're really really sure).
C's
strncopy
isn't much better, either.A correct and safe string copy in Spin2 would be
or using bytemove
or "brr go fast" (untested)
All this talk about "strcpy" is kind of missing the point of the original post, I think -- the original code was not a string copy, but rather inserting some number of characters into the middle of a string. So probably the function would better have been named "strins", it's not the same as C "strcpy".
Here's a program to do that using bytemove:
Output is:
IMHO you need to move the original string from its' end+1 to its' new end+1 (which is the size of the inserted string past the current end) and step -1 back to the insertion point.
This allows for the problem of moving the original string with overlapping data.
well depends if it overlaps on the end or the beginning.
But if I remember correctly Spin 1 byte/word/longmove take that into account.
Mike