#define	    ident	"1B02"
#ifdef VAXC
#module	    MakePrint	ident
#endif
#ifdef __DECC
#pragma	    module	    MakePrint	ident
#endif
/*
** +--------------------------------------------------------------+
** |                  Paul Scherrer Institute                     |
** |                     Department ASQ				  |
** |                                                              |
** | This software may be used freely by non-profit organizations.|
** | It may be copied provided that the name of P.S.I. and of the |
** | author is included. Neither P.S.I. nor the author assume any |
** | responsibility for the use of this software outside of P.S.I.|
** +--------------------------------------------------------------+
**
** Module Name  . . . . . . . . : [...LIB.SINQ]MAKEPRINT.C
**
** Author   . . . . . . . . . . : D. Maden
** Date of creation . . . . . . : Nov 1995
**
**  To compile this module, use:

	$ import tasmad
	$ define/group sinq_c_tlb mad_lib:sinq_c.tlb
	$ cc /debug /noopt /obj=[]MakePrint -
			tasmad_disk:[mad.lib.sinq]MakePrint +
			sinq_c_tlb/lib

**  To include this module in SINQ.OLB, use:

  $ import tasmad
  $ define/group sinq_c_tlb mad_lib:sinq_c.tlb
  $
  $ define/group sinq_olb mad_lib:sinq_dbg.olb
  $ @tasmad_disk:[mad.lib.sinq]sinq_olb MakePrint debug
  $
  $ define/group sinq_olb mad_lib:sinq.olb
  $ @tasmad_disk:[mad.lib.sinq]sinq_olb MakePrint
**
** Updates:
**  1A01 30-Nov-1995 DM.	Initial version.
**  1B01 21-Mar-1996 DM.	Move from DELTAT.OLB to SINQ.OLB.
**============================================================================
** The entry points included in this module are described below. Prototypes
** can be defined via:
**
**    #include <sinq_prototypes.h>
**
**	MakeCharPrintable  - routine used by MakePrintable and MakeMemPrintable.
**	MakeMemPrintable   - version of MakePrintable which will handle
**				buffers containing a NUL character.
**	MakePrint	   - ensure all characters in a buffer are printable.
**	MakePrintable	   - extended version of MakePrint.
**---------------------------------------------------------------------
**  char  *MakePrint (*text)
**	   ---------
**  Input Args:
**	none
**  Output Args:
**	none
**  Modified Args:
**	char	*text
**  Return status:
**	A pointer to "text".
**  Routines called:
**	none
**  Description:
**	The routine ensures that all characters in "text" are 7-bit
**	and then replaces any non-printing character with a ".". A trailing
**	"\n" or "\r" is removed.
**---------------------------------------------------------------------------
**  int   *MakeCharPrintable (*out, out_size, in)
**	   -----------------
**  Input Args:
**	char	in	    -- the character to be converted.
**	int	out_size    -- the size of the out buffer.
**  Output Args:
**	char	*out	    -- buffer to hold the converted text.
**  Modified Args:
**	none
**  Return status:
**	The number of characters put into the output buffer.
**  Routines called:
**	none
**  Description:
**	The routine puts a printable version of the character "in" into the
**	"out" buffer. The printable version is generated as follows:
**
**	  a) If the parity bit of a char is set, a "^" is inserted into the
**	     output buffer, the parity bit of the char is cleared and processed
**	     further.
**	  b) If the char is "^", "\^" is inserted into the output buffer.
**	  c) If the char is "\", "\\" is inserted into the output buffer.
**	  d) If the char is a standard C-language control char, it gets replaced
**	     by a recognised backslash escape sequence. The following are
**	     recognised:
**			NUL 0x00 --> \0
**			BEL 0x07 --> \a
**			BS  0x08 --> \b
**			HT  0x09 --> \t
**			LF  0x0a --> \n
**			VT  0x0b --> \v
**			FF  0x0c --> \f
**			CR  0x0d --> \r
**	  e) If the character is printable (i.e. between " "/0x20 and "~"/0x7e
**	     inclusive), it is inserted into the output buffer as is.
**	  f) Anything else gets inserted as "\xxx", where xxx is the octal
**	     representation of the character.
**---------------------------------------------------------------------------
**  char  *MakePrintable (*out, out_size, *in)
**	   -------------
**  Input Args:
**	char	*in	    -- the text to be converted.
**	int	out_size    -- the size of the out buffer.
**  Output Args:
**	char	*out	    -- buffer to hold the converted text.
**  Modified Args:
**	none
**  Return status:
**	A pointer to "out".
**  Routines called:
**	none
**  Description:
**	The routine converts characters in the "in" string to a printable
**	representation using MakeCharPrintable and copies them to "out" until
**	a null is detected.
**---------------------------------------------------------------------------
**  char  *MakeMemPrintable (*out, out_size, *in, in_len)
**	   ----------------
**  Input Args:
**	int	out_size    -- the size of the out buffer.
**	char	*in	    -- the text to be converted.
**	int	in_len	    -- the number of characters to be converted.
**  Output Args:
**	char	*out	    -- buffer to hold the converted text.
**  Modified Args:
**	none
**  Return status:
**	A pointer to "out".
**  Routines called:
**	none
**  Description:
**	The routine is the same as MakePrintable, except that it converts
**	a given number of characters rather than a null terminated string.
**============================================================================*/
/*
**---------------------------------------------------------------------------
**					Global Definitions
*/
#include    <stdlib.h>
#include    <stdio.h>
#include    <string.h>
#ifdef FORTIFY
#include    <fortify.h>
#endif

#include    <sinq_prototypes.h>

#define	    NIL	    ('\0')
/*--------------------------------------------------------------------------
**					Global Variables
*/
/*
**--------------------------------------------------------------------------
**		MakeCharPrintable:  makes a single character printable.
*/
int MakeCharPrintable(char *out, int out_size, char in)
{
/*      =================
**
**		Return value is number of chars put into *out.
*/
  char buff[8], *pntr;

  pntr = buff;

  if ((in & 0x80) != 0) {       /* Parity bit set? */
    *pntr++ = '^';              /* Yes. Put a '^' in the buffer .. */
    in = in & 0x7f;             /* .. and remove the parity bit. */
  }

  switch (in) {
  case '^':
    *pntr++ = '\\';
    *pntr++ = '^';
    break;
  case '\\':
    *pntr++ = '\\';
    *pntr++ = '\\';
    break;
  case '\000':
    *pntr++ = '\\';
    *pntr++ = '0';
    break;
  case '\007':
    *pntr++ = '\\';
    *pntr++ = 'a';
    break;
  case '\010':
    *pntr++ = '\\';
    *pntr++ = 'b';
    break;
  case '\011':
    *pntr++ = '\\';
    *pntr++ = 't';
    break;
  case '\012':
    *pntr++ = '\\';
    *pntr++ = 'n';
    break;
  case '\013':
    *pntr++ = '\\';
    *pntr++ = 'v';
    break;
  case '\014':
    *pntr++ = '\\';
    *pntr++ = 'f';
    break;
  case '\015':
    *pntr++ = '\\';
    *pntr++ = 'r';
    break;
  default:
    if ((in < ' ') || (in > '~')) {
      pntr += sprintf(pntr, "\\%3.3o", in);
    } else {
      *pntr++ = in;
    }
  }
  out_size = (out_size > (pntr - buff)) ? (pntr - buff) : out_size;
  memcpy(out, buff, out_size);
  return out_size;
}

/*
**--------------------------------------------------------------------------
**		MakeMemPrintable:  alternative version of MakePrintable.
*/
char *MakeMemPrintable(
/*       ================
*/ char *out,
                        int out_size, char *in, int in_len)
{

  int i;
  char *pntr;

  if (out_size <= 0)
    return out;

  while ((out_size > 1) && (in_len > 0)) {
    i = MakeCharPrintable(out, (out_size - 1), *in);
    out += i;
    out_size -= i;
    in++;
    in_len--;
  }
  *out = NIL;
  return out;
}

/*
**--------------------------------------------------------------------------
**		MakePrint:  Make all characters in a buffer printable.
*/
char *MakePrint(char *chr)
{
/*       =========
*/
  int len, i;

  for (i = 0; chr[i] != NIL; i++)
    chr[i] &= 0x7F;

  len = strlen(chr);
  if (len <= 0)
    return chr;

  if (chr[len - 1] == '\r')
    chr[len - 1] = NIL;
  if (chr[len - 1] == '\n')
    chr[len - 1] = NIL;

  for (i = 0; chr[i] != NIL; i++) {
    if (chr[i] < ' ')
      chr[i] = '.';
    if (chr[i] == 0x7F)
      chr[i] = '.';
  }

  return chr;
}

/*
**--------------------------------------------------------------------------
**		MakePrintable:  improved version of MakePrint.
*/
char *MakePrintable(
/*       =============
*/ char *out,
                     int out_size, char *in)
{

  int i;
  char *pntr;

  if (out_size <= 0)
    return out;

  while ((out_size > 1) && (*in != NIL)) {
    i = MakeCharPrintable(out, (out_size - 1), *in);
    in++;
    out += i;
    out_size -= i;
  }
  *out = NIL;
  return out;
}

/*-------------------------------------------- End of MakePrint.C =======*/
