Preserving the new-line while reading variable length record



Help for C/C++ for MVS, OS/390 C/C++, z/OS C/C++ and C/C++ Productivity Tools for OS/390

Preserving the new-line while reading variable length record

Postby zatlas1 » Mon Jul 23, 2012 9:22 am

I've got a C program that does something like this and gets all records into a buffer:
extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
{
pcre_uint8 *here = start;

for (;;)
  {
  size_t rlen = (size_t)(buffer_size - (here - buffer));

  if (rlen > 1000)
    {
    int dlen;

    /* Read the next line by normal means, prompting if the file is stdin. */

      {
      if (f == stdin) printf("%s", prompt);
      if (fgets((char *)here, rlen,  f) == NULL)
        return (here == start)? NULL : start;
      }

    dlen = (int)strlen((char *)here);
    if (dlen > 0 && here[dlen - 1] == '\n') return start;
    here += dlen;
    }

  else
    {
    int new_buffer_size = 2*buffer_size;
    pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
    pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size);
    pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);

    if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
      {
      fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
      exit(1);
      }

    memcpy(new_buffer, buffer, buffer_size);
    memcpy(new_pbuffer, pbuffer, buffer_size);

    buffer_size = new_buffer_size;

    start = new_buffer + (start - buffer);
    here = new_buffer + (here - buffer);

    free(buffer);
    free(dbuffer);
    free(pbuffer);

    buffer = new_buffer;
    dbuffer = new_dbuffer;
    pbuffer = new_pbuffer;
    }
  }

return NULL;  /* Control never gets here */
}

The result in buffer, clearly does not contain the new-line, but I need to preserve the new-line. How could I do that?
zatlas1
 
Posts: 61
Joined: Mon Mar 15, 2010 9:19 am
Has thanked: 0 time
Been thanked: 0 time

Re: Preserving the new-line while reading variable length re

Postby steve-myers » Mon Jul 23, 2012 9:36 am

From the fgets chapter in z/OS V1R13.0 XL C/C++ Run-Time Library Reference
Reads bytes from a stream pointed to by stream into an array pointed to by string, starting at the position indicated by the file position indicator. Reading continues until the number of characters read is equal to n-1, or until a newline character (\n), or until the end of the stream, whichever comes first. The fgets() function stores the result in string and adds a NULL character (\0) to the end of the string. The string includes the newline character, if read.

Note the last sentence.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: Preserving the new-line while reading variable length re

Postby zatlas1 » Mon Jul 23, 2012 4:42 pm

Thank you
I know that it should, but when I print the whole buffer with fprinf or printf, the thing prints as one long line wrapped around and I do not see anything that could be described as a new-line character. Same fprintf on Windows, yields separate lines. So i guess I should question the output side: How could I make the new-line characters in the buffer affect the output to yield a NEW LINE?
Is there a way to print a memory dump of a character string in C so I could prove either way?
What exactly is the new-line character in z/OS/EBCDIC?
ZA
zatlas1
 
Posts: 61
Joined: Mon Mar 15, 2010 9:19 am
Has thanked: 0 time
Been thanked: 0 time

Re: Preserving the new-line while reading variable length re

Postby dick scherrer » Mon Jul 23, 2012 7:01 pm

Hello,

I may misunderstand this, but mainframe (z/OS) files do not have some character(s) (i.e. CR LF NEWLINE) for a new line. The data is stored in fixed length records which by definition have the same length or variable records that the system prefixes the data with the record length.

If you are sending data to a z/OS system, you should not try to process the control characters from the "ascii" file(s). In the cases where an ftp (or other xmission) "sent" these, we ignore them in the mainframe process.

If i misunderstand, please clarify.
Hope this helps,
d.sch.
User avatar
dick scherrer
Global moderator
 
Posts: 6268
Joined: Sat Jun 09, 2007 8:58 am
Has thanked: 3 times
Been thanked: 93 times

Re: Preserving the new-line while reading variable length re

Postby steve-myers » Mon Jul 23, 2012 7:56 pm

Mr. Scherrer is 100% correct. Regular MVS datasets do not use control characters like the Unix new line character. IBM made the mistake of imbedded control character data with the IBM 14xx series, and swore off it when they designed System/360. The possible exception exception is carriage control data in printed output, but the CPU does not regard this as control data.

Unix System Services (or whatever IBM calls it this week) files use control characters like new line, and the ''\0' character terminates C style strings.

In my opinion, zatlas probably has a legitimate issue here. The printf and fputs type functions should be looking for '\n' characters when writing to regular datasets and start a new record at that point. Similarly, it should do the same thing when the output file is a 3270 type terminal.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: Preserving the new-line while reading variable length re

Postby zatlas1 » Mon Jul 23, 2012 8:32 pm

Oh
I agree with both of you. I will try to share the whole picture and may get the best advice that way. I am porting an open source package (runs fine on Unix, Linux and Windows) back to z/OS. The package is doing Perl Compatible Regular Expressions using C and thus enables regular expressions, Perl Style, in languages that do not have them. When I finish, I will publish it, the same as the original, as an open source, hopefully with appropriate API for COBOL and maybe PL/I and Rexx.
The mechanic part of the port - changing routine names to 8 characters, resolving some character mapping and intermodule dependencies was done utilizing some automation scripts and is done. The whole thing (the needed parts) compile and link without any additional issue.
Now I am in the testing phase. I may tell you that, learning from initial runs, I know that some parts do not work correctly, but that was expected and I intend to labor on it and resolve all issues, except of unsolvable (which I will try to document)
My issue is the test driver. The package comes with a C program that drives tests and goes through a whole suite of test data with supplied 'correct' results. My initial response was to try to use this same test driver in z/OS, but this one gives me some troubles (such as the one documented in this thread). I am weighing the option of abandoning that test driver altogether and rewrite it in COBOL, but this one is also not an easy task. I am trying to think which route will take away the least amount of scarce resources. Note that I have lmited access to mainframe (about three hours, at night, after workday)
Thanks
ZA
zatlas1
 
Posts: 61
Joined: Mon Mar 15, 2010 9:19 am
Has thanked: 0 time
Been thanked: 0 time

Re: Preserving the new-line while reading variable length re

Postby dick scherrer » Mon Jul 23, 2012 8:43 pm

Hello,

Thanks for the clarification :)

Personally, i'd suggest creating the COBOL code as it will most likely be easier maintained by you & others in your organization. You would have complete control and not need to be concerned with getting the provided driver code working in the z/OS environment.

If you get stuck implementing the COBOL replacement, we should be able to help.

Good luck!

d
User avatar
dick scherrer
Global moderator
 
Posts: 6268
Joined: Sat Jun 09, 2007 8:58 am
Has thanked: 3 times
Been thanked: 93 times

Re: Preserving the new-line while reading variable length re

Postby zatlas1 » Mon Jul 23, 2012 9:03 pm

The other benefit is that the API will be developed as a by-product...
I will try to make the decision tonight.

BTW, there is no organization, I do it on my own, on my won private time.

ZA
zatlas1
 
Posts: 61
Joined: Mon Mar 15, 2010 9:19 am
Has thanked: 0 time
Been thanked: 0 time

Re: Preserving the new-line while reading variable length re

Postby steve-myers » Tue Jul 24, 2012 12:47 am

I ran this program on the "mainframe" -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argn, char *dataset??(??) )
 {
  FILE *f;
  size_t maxrec = 256;
  char inputbuf??( 256 ??);
  int rnum = 0;
  if ( argn < 2 )
   printf( "readvb file\n" );
  else
   if ( ( f = fopen( dataset??(1??), "r" ) ) == NULL )
    printf( "I can not open %s\n", dataset );
   else
    {
     while( fgets( inputbuf, sizeof( inputbuf ), f ) != NULL )
      {
       rnum++;
       if ( strchr( inputbuf, '\n' ) == NULL )
        printf( "Record %d does not have a newline character\n", rnum );
       else
        printf( "Record %d has a newline character\n", rnum );
      }
     fclose( f);
    }
  return 0;
 }
I specified as input a dataset containing z/OS variable length records. The output produced the "Record nnn has a newline character" message for every record in the input. While reviewing the post I noticed the printf( "I can not open %s\n", dataset ); statement is wrong, but I'll leave it alone.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: Preserving the new-line while reading variable length re

Postby zatlas1 » Tue Jul 24, 2012 1:29 am

Thank You
1. I know that theoretically it should work, but this is not the issue; what would happen if you collect all the input lines in a huge buffer and then print all of them at once, how could you then control that it would print correctly (i.e. multiple lines) on z/OS? ...
2. However, even that is not the real issue. The existing test program that was written by the guy who'd created the package, was converted, compiled and linked in z/OS without any problem. Once I try to run it I get strange results. For example, when I let it read from stdin (SYSIN) and write to stdout (SYSPRINT) I get the results only (correct or incorrect), most of them are in new lines as they should, but the image of the input is not printed. When I read an actual file and output to an actual file, the image of the input is printed as a one long line (wrapped around) but no result is printed.
3. Thus, I have the practical issue: Should I invest my time in adjusting the existing test program (a side issue) to z/OS to the detriment of testing the core logic of the regular expressions, or should I abandon that test program and invest my limited time and energy resources in testing the core logic. There are advantages and disadvantages for both posibilities which I would weigh. If I decide to rewrite the test program in COBOL, I would add it to the published package.

Now, I have a new (quasi tongue-in-cheeck) challenge, is there a way to (partially) automate C to COBOL conversion :)
ZA
zatlas1
 
Posts: 61
Joined: Mon Mar 15, 2010 9:19 am
Has thanked: 0 time
Been thanked: 0 time

Next

Return to C, C++

 


  • Related topics
    Replies
    Views
    Last post