#define	    ident	"1B03"
#ifdef VAXC
#module	    StrJoin	ident
#endif
#ifdef __DECC
#pragma	    module	    StrJoin	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]STRJOIN.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=[]StrEdit -
			tasmad_disk:[mad.lib.sinq]StrEdit +
			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 StrEdit debug
  $
  $ define/group sinq_olb mad_lib:sinq.olb
  $ @tasmad_disk:[mad.lib.sinq]sinq_olb StrEdit
**
** Updates:
**  1A01  2-Nov-1995 DM.	Initial version.
**  1B01 21-Mar-1996 DM.	Move from DELTAT.OLB to SINQ.OLB.
**  1B03 28-May-1997 DM.	Allow result string to be either of source
**				 strings.
**============================================================================
** The following entry points are included in this module:
**
**-------------------------------------------------------------------------
**    #include <sinq_prototypes.h>
**
**    char *StrJoin (&result, result_size, &str_a, &str_b)
**	    -------
**  Input Args:
**	int   result_size   - max size of "result". The resultant string will
**				have a max length of (result_size - 1) to allow
**				for the zero terminator
**	char *str_a	    - Pointer to first  string to be joined.
**	char *str_b	    - Pointer to second string to be joined.
**  Output Args:
**	char *result	    - Pointer to resulting string.
**  Modified Args:
**	none
**  Return value:
**	Pointer to resulting string.
**  Global variables modified:
**	none
**  Routines called:
**	None
**  Description:
**	The routine joins 2 strings, checking for total string length and
**	ensuring the result will be zero terminated. The "result" arg may be
**	the same as "str_a" or "str_b".
**-------------------------------------------------------------------------
**			Global Definitions
*/
#include    <string.h>

#define	    NIL	    '\0'
/*
**====================================================================
*/
/*
**====================================================================
**		StrJoin	- join 2 strings.
**			    Note: strncat is used exclusively rather than
**				  strncpy to be sure result is always
**				  null terminated.
*/
char *StrJoin(
/*	 =======
*/ char *result,
               int result_size, char *str_a, char *str_b)
{

  int i, size, size_a, size_b;

  size = result_size - 1;

  if (size < 0)
    return result;

  if (result == str_a) {        /* Are the result and str_a the same? */
    size_a = strlen(str_a);     /* Yes */
    if (size_a > size) {        /* Check sizes anyway. */
      result[size] = NIL;       /* Truncate str_a. No room for str_b! */
    } else {
      size = size - strlen(result);     /* And append str_b */
      if (size > 0) {
        strncat(result, str_b, size);
      }
    }
  } else if (result == str_b) { /* Are the result and str_b the same? */
    size_a = strlen(str_a);     /* Yes, this is a bit complicated! */
    size_b = strlen(str_b);
    if (size_a >= size) {       /* If str_a completely fills result, .. */
      result[0] = NIL;          /* .. then just copy in str_a */
      strncat(result, str_a, size);
    } else {
      /*
       ** Otherwise, str_b must first be moved to
       ** make room for str_a and then str_a must
       ** be put at the front of the result.
       */
      if ((size_a + size_b) > size)
        size_b = size - size_a;
      result[size_a + size_b] = NIL;
      for (i = (size_b - 1); i >= 0; i--) {
        result[size_a + i] = str_b[i];
      }
      memcpy(result, str_a, size_a);
    }
  } else {                      /* Result is neither str_a nor str_b so .. */
    result[0] = NIL;            /* .. str_a needs to be copied */
    strncat(result, str_a, size);
    size = size - strlen(result);       /* And str_a appended */
    if (size > 0)
      strncat(result, str_b, size);
  }
  return result;
}

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