Hi @MarkGoldberg, I’ve also thought that it could lead to problems but the variable was there to store the path which acctually never exceed the length of 200. But good point using the MaxFilePath. Afterall it was the code that was making the problem. After @Mark_Sarson made the changes then it worked fine.
Hi @vitesse unfortunately I don’t use StringTheory, but a good point altough.
what?!
seriously though, IMNSHO it could turn out to be the best money you ever spend on a third party product.
it is funny how we are all different. Years ago there was a thread on one of the newsgroups along the lines of “Which third party templates/products are indispensable?”
nearly everyone had a different opinion.
and of course it almost goes without saying that everyone thought that their opinion was the “correct” one.
this was back last century before ST was around but these days ST would get my vote.
We need to st.getValue() 3 times which is much worse
Since SYS is a Path it could contain spaces so you want “Quotes” around the 3 parts or the RUN will not work.
Using ST seems excessive to just append a backslash when simple Clarion code will do. Using a CString can save on the CLIP() in concatenation … but you MUST be sure to Clip on Assignment
cSYSbs CSTRING(257) !Path max 255 + 1 for trailing \ + 1 CHR(0)
CODE
cSYSbs=CLIP(SYS) !Assign CString=String MUST CLIP(String) or risk trailing spaces
IF RIGHT(cSYSbs,1)<>'\' THEN cSYSbs=cSYSbs & '\'.
RUN('"' & cSYSbs & 'BARKOD.EXE"' & |
' "' & cSYSbs & 'BARKOD.TXT"' & |
' "' & cSYSbs & 'BARKOD.BMP"',1)
FILE:MaxFilePath = 260
This is how I do those:
cSYSbs CSTRING(File:MaxFilePath+1)
Hi Mike - I hope things are OK for you and family at this time.
You have a fair point regarding the overhead of a function call but I have always thought of clip() as something to be avoided whereever possible.
Of course you could always avoid the multiple function calls by replacing
st.setValue(st.getValue() & ‘BARKOD.EXE ’ & st.getValue() & ‘BARKOD.TXT ‘ & st.getValue() & ‘BARKOD’&I&’.BMP’)
with something like
s &string
...
s &= st.setValuePtr()
st.setValue(s & ‘BARKOD.EXE ’ & s & ‘BARKOD.TXT ‘ & s & ‘BARKOD’&I&’.BMP’)
this is also less typing
and of couse you could probably do much the same to avoid the original clips, replacing
mypath=CLIP(SYS)&‘BARKOD.EXE ’&CLIP(SYS)&‘BARKOD.TXT&CLIP(SYS)&‘BARKOD’&I&’.BMP’
with something like
s &string
...
if SYS
s &= SYS[1 : len(clip(SYS))]
else
s &= null
end
mypath=s & ‘BARKOD.EXE ’ & s & ‘BARKOD.TXT ‘ & s & ‘BARKOD’&I&’.BMP’
to achieve the same outcome although with more typing and more chance of error.
perhaps true in this case Carl but generally ST will allow you to work at a higher level of abstraction without ever having to worry about the lower level details. So you do things more quickly with less chance of errors.
unfortunately not all Clarion programmers are anywhere near as good as you Carl and often I see code with “off by one” on subscripts whereas using ST avoids this whole class of error - so you end up with simpler code that is more easy to understand and maintain and less likely to have bugs.
My string class actually has a method called SlashPath. It appends a ‘\’ to the string if it doesn’t end with a ‘\’. That’s abstracted all the way.
aka the “One True String Class”
that was one of the most influential Clarion Mag articles ever!
A StringClass For Clarion
by Rick Martin
Published 2007-11-16
attached here with thanks to Dave Harms.
cmag-2007-11.pdf (2.0 MB)
Funny, isn’t it.
What seemed like a simple thing ended up spawning an essential piece of Clarion development. IMO.
Why? I really don’t understand. Well, CLIP is unconvinient enough when used in string concatenations multiple times. But it is not a reason to instantiate complex objects, assign values to get clipped values back, but without an explicit CLIP.
Someone was talking to me just last week about the idea of having “static” string theory methods that did not require the initial .SetValue(value) They would instead take a string value, and return the answer.
About the original question… which was specifically about C6.
Back in those good old days there was an excellent template called Power Run that did all that the original poster asked.
Was Power Run commercial?
Does anyone have a copy of it?
It was a product from Greg Burthume. He quit the Clarion game a long time ago, IIRC.
I do have an installer for PowerRun ver 5.0, which targeted C55. I don’t recall if I ever used it.
Since I still have a c55 installation, I have it.
Is it something we can share without issue?
(Don’t want to step on anyone’s toes.)
Perhaps I was mistaken about it being in C6.
yes clipping strings makes them as bad as using Cstrings. People argue about which is better/worse but it depends how “full” they are with data.
for example take a 10k string. If it is 90% full then doing a clip on a string has to scan backwards for 1000 chars from the end to find the first non-blank (ie space) character whereas in a cstring it would have to scan forwards 9000 chars from the start in search of the null character at position 9001. So in this case clip(string) is much better.
but suppose the 10k string was only 10% full - then the results are reversed and the string has to scan backwards 9000 chars to find a non-space whereas the cstring only has to scan forward a thousand (+1) chars to find the null.
so when appending, both these methods requires “scanning” to find the end of the contents of the string - and this is inefficient and time consuming.
so that is why I try to avoid cstrings and doing clip(someString).
sure you can manually keep track yourself of how long the contents currently are, but in an ideal world we could have a string that kept track of its current length without the user (programmer) needing to worry about the details. Ideally it would silently expand its memory buffer if and when required. So you could append or cat without any of the “scanning” mentioned above. Even more ideal, it could have a bunch of handy methods included - again shielding the user (programmer) the low level details. And be debugged and optimized so that it not only works, but works fast. Hey in theory it could even have a clever name .
Someone was talking to me just last week about the idea of having “static” string theory methods that did not require the initial .SetValue(value) They would instead take a string value, and return the answer.
I am not sure that “static” is the best word here Mark as it has other meanings which had me confused at first. For example sometimes I will declare
st StringTheory,static,thread
but here I think you mean ST methods that operate on supplied strings without reference to the normal ST value buffer.
There are several ST methods with this option, for example:
st.trace('hello world')
as opposed to
st.trace()
(The second version without a supplied string sends the current value to ODS).
Other methods that come to mind with this option are saveFile, Base64 encode/decode, some of the UTF and hex conversion methods, containsA, containsChar, isAll, findChar and findChars, cleanFileName and probably various others.
I’m not sure if you are saying these are a good thing or an abomination?
A theory is a good thing, of course. And here is the practice.
1st example, total CLIPs: 1.
lastname string(20)
firstname string(20)
fullname string(32)
lastname = cus:LastName
firstname = cus:FirstName
fullname = clip(lastname) &' '& firstname
2nd example, total CLIPs: 3
lastname StringTheory
firstname StringTheory
fullname StringTheory
lastname = lastname.SetValue(cus:LastName, st:clip)
firstname = firstname.SetValue(cus:FirstName, st:clip)
fullname.SetValue(lastname.GetValue() &' '& firstname.GetValue(), st:clip)
I don’t discuss about StringTheory itself, it is definitely good class. But I can live without it.