Page 1 of 1

Getting strlen from str[0]

PostPosted: Fri Sep 27, 2019 5:50 pm
by Joseph Baron
Hello,
I'm looking for a way to get the length of a string up to 255 chars into an integer.

strlen() only handles 80.

So I convert the str char using ord() to get the integer and I find that ord() too only handles up to 80.

I'm hoping someone has a simple answer...

Re: Getting strlen from str[0]

PostPosted: Fri Sep 27, 2019 7:40 pm
by dhs
Hi Joseph.
I couldn't remember any limitation on strlen, so wrote a quick test macro to refresh my memory as shown below.
Code: Select allPROGRAM Test;

VAR
   s : str255;
   i : integer;

BEGIN
   s := '12345678901234567890123456789012345678901234567890123456789012345678901234567890';
   i := strlen (s);
   getint (i);
   strcat (s, '1234567890');
   i := strlen (s);
   getint (i);
   strcat (s, '1234567890');
   i := ord(s[0]);
   getint (i);
END Test.


the getint(i) statement is showing the correct values (80, 90, then 100) each time so I'm not sure what is causing you to see a maximum value of 80.

DCAL has always only allowed you to hard code a string of up to 80 characters (so if you want to hard code a longer value you need to use strcat as I have done in this macro), but I don't think there is any restriction on strlen that prevents it reporting the correct length of longer strings.

Best Regards,
David H.

Re: Getting strlen from str[0]

PostPosted: Sat Sep 28, 2019 12:37 pm
by Joseph Baron
I stand corrected on strlen() and ord(), thanks David.

It took some digging and I found that getPath and setPath are the limiting functions, it is GETPATH that only allows 80 chars:

getPath (path, PathLyr);

I hope you can prove me wrong on this one as well :D

The users that I have seem to use longer and longer path names and a recent event has prompted me to plug a fix to prevent it from happening again.

It looks like the next step is to write my own getpath255() unless it already exists...

Re: Getting strlen from str[0]

PostPosted: Sun Sep 29, 2019 3:01 am
by dhs
Yes, getpath does seem to truncate long paths ... I will add a note about that to my version of the DCAL manual.

Provided that the main datacad path (where dcadwin.ini is located) is not more than 80 characters long you could use code along the following lines to read the layer path from the dcadwin.ini file:
Code: Select allROGRAM Test;
PROCEDURE readIniStr (IniFile, Section, Ident, Default : str255;ReturnStr : OUT str255); BUILTIN 625;
VAR
   s : str255;
BEGIN
   getpath(s, 22); ! pathINI has a value of 22 in D4D UConstants module - seems to give the required result
   strcat (s, 'dcadwin.ini');
   readIniStr (s, 'Paths', 'PATH_LAYER', 'path not read', s);
   getstr (s, 255); ! s should now have the layer path
END Test.

Be aware that the path read from dcadwin.ini may be a relative path. That may not be a problem, but if it is you will need to insert the main datacad path to the front of the string (I haven't given it a lot of thought, but maybe check if the 2nd character of the path is a colon to check if it is relative or not).

Re: Getting strlen from str[0]

PostPosted: Mon Sep 30, 2019 1:18 pm
by Joseph Baron
Thanks for your help David,

Your code is along the lines of how I was thinking.

I have notes from way back in 1995 that getstr() does not handle 255 chars. The most I could pack in the str today is 133 chars for some reason.

Re: Getting strlen from str[0]

PostPosted: Tue Oct 01, 2019 11:24 am
by Joseph Baron
David,

Would you happen to have any updated information on getflname()?

It seems I've run into another 80 char limit that will have to be resolved to allow 255 chars.

Re: Getting strlen from str[0]

PostPosted: Tue Oct 01, 2019 2:57 pm
by dhs
The most I could pack in the str today is 133 chars
Can't say I've ever noticed that previously, but I get the same result as you (133 chars).
Would you happen to have any updated information on getflname()?

I've never run into any limitation on getflname, but not sure if I've ever used it. I am surprised at the limitation, but can confirm that I get an error message if the file name is longer than 80.

Over the years I have got reasonably good at getting around the Classic DCAL limitations. My solution to this problem would be something along the following lines:
  • write a small Delphi program to get the file name and then write the name to a temp file
  • call that program from the macro using ExecAndWait
  • once ExecAndWait returns control to the macro read the file name from the temp file and then delete the temp file.
    (I'm not aware of any limitation (other than 255) on the max len that f_rdstr can read, but if there is your Delphi app could split the name over multiple lines and the macro could do multiple f_rdstr and then concat them together)
... not a particularly elegant solution, and means that you need to distribute an exe file together with your macro, but it gets the job done! ... the other option would be to rewrite the whole macro using D4D.