I bet if you timed it the strchr() TRT in a loop is faster. 

On 25/02/2014, at 12:19 AM, John McKown <[email protected]> wrote:

> Again, my thanks to all for the help, which was my fault in not realizing
> that I had used the -o switch instead of the -O switch and so was not
> having my code optimized.
> 
> On the off chance that anybody was wondering why I was doing this, it was
> just a test to try to determine the "best" way to see if a C string ended
> with a \r, or carriage return. Why? Because sometimes people here goof up
> and ftp a Windows file to the mainframe, but do it from a UNIX server.
> Well, they don't, but we share an NAS box between Windows an Linux servers.
> So the file on the z sometimes has an extraneous \r at the very end of the
> line. One good thing this did for me was point out that I was really doing
> it wrong. I found the address of the end of the string using with the code
> "argv[i]+strlen(argv[i])". But the strlen() code generated actually found
> the end of the string using the SRST and then converted that to an integer
> (size_t), which I then converted right back to an address. So I searched
> and found the strchr() routine which can find the terminating null and
> returns its address. Using this function resulted in a TRT in a loop. Which
> I didn't much care for. So I looked at the memchr() function. But it
> requires a maximum length. Now, since I'm looking for a \0. And since a
> proper C string is \0 delimited, I _ASSuMEd_ that the string was properly
> delimited. This allowed me to use an arbitrary length for the memchr()
> call. So I used 0x7fffffff, or 2GiB. That seems more than large enough to
> me.
> 
> The code is now:
> 
> for(i=0; i<argc; i++) {
>     if ('\r'==*( (char *) memchr(argv[i],'\0',0x7fffffff)-1)
>          *( (char *) memchr(argv[i],'\0',0x7fffffff)-1) = '\0';
> }
> 
> Of course, this would really be done after the fgets() call. The code
> generated is lovely:
> 
> *         if ('\r' == *(findend-1))
>          L        r5,(*)uchar*(r2,r1,0)
>          LR       r6,r5
>          LA       r0,0
>          AL       r6,=F'2147483647'
>          SRST     r6,r5
>          JO       *-4
>          BL       @1L13
>          LA       r6,0
> @1L13    DS       0H
>          AHI      r6,H'-1'
>          CLI      (*)uchar(r6,0),13
>          BNE      @1L5
> *            *(findend-1)='\0';
>          MVI      (*)uchar(r6,0),0
> @1L5     DS       0H
> 
> where findend is:
> #define findend (char *)memchr(argv[i],'\0',0x7fffffff) // for ease to
> change method
> 
> I need to cast the (void *) from memchr() to a (char *) in order to
> subtract 1 from it. Of course, this can S0C4 if the string is not \0
> delimited. Or it could possibly corrupt a byte of innocent storage. But
> this should not happen in my planned use since fgets() should return a
> pointer to a \0 delimited string or NULL. And I _will_ check for NULL.
> 
> 
> 
> On Sat, Feb 22, 2014 at 11:16 PM, John McKown
> <[email protected]>wrote:
> 
>> Just for fun, I wrote a very small C program. I compiled it on Linux/Intel
>> using GCC 4.8.2. I then got it compiled on z/OS 1.13. The program is very
>> small:
>> 
>> #include <stdlib.h>
>> #include <stdio.h>
>> #include <string.h>
>> #undef strlen
>> int main (int argc, char *argv[]) {
>>    int i;
>>    for(i=0;i<argc;i++) {
>>       if ('\r' == *(argv[i]+strlen(argv[i])) )
>>          *(argv[i]+strlen(argv[i]))='\0';
>>    }
>>    return 0;
>> }
>> 
>> <snip/>
> 
> ----------------------------------------------------------------------
> For IBM-MAIN subscribe / signoff / archive access instructions,
> send email to [email protected] with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to