Article 152113 of comp.os.vms:
hello again,

Eventually I have managed to post an AST in a C++ program thanks to Tony 
Cox and Nick de Smith both of whom gave me very valid suggestions.

However to do this I had to put a static global function which acts as 
the real AST and then this function calls the member function which 
belongs to the class.  Even the buffers and descriptors had to be 
declared global.By using this approch I cannot instatiate more than one 
instance of the class.
  
My idea is to be able to write a class (portReader) which would be 
initialized as portReader("TXA0:");  This class would be able to read 
data received on the corresponding TTY port.  I also want to instansiate 
more than one instance of this class; one for each port.

Are there any suggestions on how can I keep Object Oriented on the VMS 
when it comes to AST's.

Here is the idea for the class.  The follwing program does compile but 
the fails at runtime.

Thanks very much for your time.

-----------------------------------------------------------------------
//PORTREADER.CPP

#include <stdlib.h>
#include <stdio.h>
#include <descrip.h>
#include <iodef.h>
#include <ssdef.h>
#include <ttdef.h>
#include <tt2def.h>
#include <starlet.h>
#include <lib$routines.h>
#include <string.h>
#include <signal.h>

#define TTY_MAXBUF      1024
#define STRNG_MAXBUF    100
#define CONNECTION_TERMINATOR   0x1c

static int go_out;

class portReader
{
public:
  portReader (char *portName);
  ~portReader ();
  void portReaderAST (void);
private:
  void TTYhangupHandler (void);
  void portReaderASTstarter (void);
  void EndSession (void);
  void ExitHandler (void);
  void stringHandler (void);

  struct dsc$descriptor TTYportNameDSC;
  char    *TTYbuffer,*lineStr;
  int lineStrPointer;
  unsigned short  TTYchannel,TTY_QIOiosb[4];
  long unsigned   ReadTerminatorMask[2],ExitConditionValue;
  struct {
        unsigned long   flink;
        void            (portReader::*exit_handler)();
        unsigned long   arg_count;
        unsigned long   *exit_status;
  } ExitHandlerBlock;

  struct io_status_block {   /*   I/O status block */
         short int condition;
         short int count;
         int dev;
         } iosb;
};

portReader::portReader (char *portName)
{
  unsigned long status;

  $DESCRIPTOR (TTYportNameDSC, portName);

  ReadTerminatorMask[0] = 0;
  ReadTerminatorMask[1] = 0;

  ExitHandlerBlock.flink = 0;
  ExitHandlerBlock.exit_handler = &portReader::ExitHandler;
  ExitHandlerBlock.arg_count = 1;
  ExitHandlerBlock.exit_status = &ExitConditionValue;

  if (!((status = sys$assign (&TTYportNameDSC, &TTYchannel, 0, 0)) & 1))
    lib$signal (status);

  TTYbuffer = (char *)malloc (TTY_MAXBUF);
  lineStr = (char *)malloc (STRNG_MAXBUF);
  lineStrPointer = 0;

  if (!((status = sys$qiow (
      0,
      TTYchannel,
      IO$_SETMODE | IO$M_CTRLYAST,
      &TTY_QIOiosb, 0, 0,
      &portReader::TTYhangupHandler,
      0, 0, 0, 0, 0)) & 1))
    lib$signal (status);

  portReaderASTstarter ();
}

portReader::~portReader ()
{
  EndSession();
}

void
portReader::portReaderASTstarter (void)
{
  unsigned long status;

  if (!((status = sys$qio (
      0,
      TTYchannel,
      IO$_READVBLK | IO$M_NOECHO,
      &TTY_QIOiosb,
      &portReader::portReaderAST, 0,
      TTYbuffer,
      1, 0, &ReadTerminatorMask, 0, 0)) & 1))
    lib$signal (status);

  status = sys$alloc (&TTYportNameDSC, 0, 0, 0, 0);
}

void    portReader::portReaderAST (void)
{
  unsigned long status;
  int i;

  if (TTY_QIOiosb[0] == SS$_HANGUP)
    EndSession ();

  if (!(TTY_QIOiosb[0] & 1 ))
    sys$exit (TTY_QIOiosb[0]);

  if (!((status = sys$qiow (
      0,
      TTYchannel,
      IO$_READVBLK | IO$M_TIMED | IO$M_NOECHO,
      &TTY_QIOiosb, 0, 0,
      TTYbuffer + 1,
      TTY_MAXBUF, 0,
      &ReadTerminatorMask, 0, 0)) & 1))
    lib$signal (status);

  if (!(TTY_QIOiosb[0] & 1) && (TTY_QIOiosb[0] != SS$_TIMEOUT))
    lib$signal (TTY_QIOiosb[0]);

  for (i = 0;i <= TTY_QIOiosb[1];i++)
  {
    lineStr[lineStrPointer++] = TTYbuffer[i];
    if (TTYbuffer[i] == '\n' || TTYbuffer[i] == '\r' || TTYbuffer[i] == 
'\0')
    {
      lineStr[lineStrPointer] = '\0';
      stringHandler ();
      lineStrPointer = 0;
    }
  }
  if(!go_out)
    if (!((status = sys$qio (
        0,
        TTYchannel,
        IO$_READVBLK | IO$M_NOECHO,
        &TTY_QIOiosb,
        &portReader::portReaderAST, 0,
        TTYbuffer,
        1, 0, &ReadTerminatorMask, 0, 0)) & 1))
      lib$signal (status);
  return;
}

void portReader::TTYhangupHandler (void)
{
  EndSession();
  return;
}

void portReader::EndSession (void)
{ 
  unsigned long status;
  sys$dalloc (&TTYportNameDSC, 0);
  if (!((status = sys$cancel (TTYchannel)) & 1))
    lib$signal (status);
  printf ("Process terminated\n");
  sys$exit (1);
}

void portReader::ExitHandler (void)
{
  EndSession();
  return;
}


void portReader::stringHandler (void)
{
  // this routine will handle all the processing we need to do on the 
string.
  // for now we just print it on screen

  printf ("%s", lineStr);
}


main ()
{
  go_out = 0;
  portReader portTXA0("TXA0:");
  sys$hiber ();
  go_out = 1;
}




