#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>
**
**	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.
**---------------------------------------------------------------------------
**  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 copies all the characters in "in" to "out", ensuring that
**	"out" only contains printable characters.
**	If the parity bit of a char is set, the char is prefixed with "^",
**	any "^" chars get replaced by "\^".
**	Then, if the result is non-printable, it is replaced by "\" and its
**	octal value. Standard C-language control chars get replaced with
**	the corresponding printable string, e.g. <LF> is "\n". Any "\" is
**	replaced by "\\".
**============================================================================*/
/*
**---------------------------------------------------------------------------
**					Global Definitions
*/
#include    <stdlib.h>
#include    <stdio.h>
#include    <string.h>

#include    <sinq_prototypes.h>

#define	    NIL	    ('\0')
/*--------------------------------------------------------------------------
**					Global Variables
*/
/*
**--------------------------------------------------------------------------
**		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		len, i, j;
    char	*my_tmp1, *my_tmp2;

    len = strlen (in);

    my_tmp1 = malloc (5 * len + 1);	/* Get plenty of working space */
    if (my_tmp1 == NULL) {
      out[0] = NIL; return out;
    }

    my_tmp2 = malloc (5 * len + 1);
    if (my_tmp2 == NULL) {
      free (my_tmp1); out[0] = NIL; return out;
    }
		    /*
		    ** Process the parity bits, "\" and "^" first.
		    */
    i = 0; j = 0;
    while (in[i] != NIL) {
      if ((in[i] & 0x80) != 0) {
        my_tmp1[j] = '^'; j++;
	my_tmp1[j] = in[i] & 0x7f;
      }else if (in[i] == '\\') {
	my_tmp1[j] = '\\'; j++;
	my_tmp1[j] = '\\';
      }else if (in[i] == '^') {
	my_tmp1[j] = '\\'; j++;
	my_tmp1[j] = '^';
      }else {
        my_tmp1[j] = in[i];
      }
      i++; j++;
    }
    my_tmp1[j] = NIL;
		    /*
		    ** Now do the non-printing stuff.
		    */
    i = 0; j = 0;
    while (my_tmp1[i] != NIL) {
      if ((my_tmp1[i] < ' ') || (my_tmp1[i] == 0x7f)) {
	my_tmp2[j] = '\\', j++;
        switch (my_tmp1[i]) {
	 case '\007': my_tmp2[j] = 'a'; break;
	 case '\010': my_tmp2[j] = 'b'; break;
	 case '\011': my_tmp2[j] = 't'; break;
	 case '\012': my_tmp2[j] = 'n'; break;
	 case '\013': my_tmp2[j] = 'v'; break;
	 case '\014': my_tmp2[j] = 'f'; break;
	 case '\015': my_tmp2[j] = 'r'; break;
	 default: sprintf (&my_tmp2[j], "%3o", my_tmp1[i]); j += 2; break;
	}
      }else {
        my_tmp2[j] = my_tmp1[i];
      }
      i++; j++;
    }
    my_tmp2[j] = NIL;

    StrJoin (out, out_size, my_tmp2, "");

    free (my_tmp1); free (my_tmp2);
    return out;
  }
/*-------------------------------------------- End of MakePrint.C =======*/
