/*static char *SCCSID = "@(#)cmsubstr.c	6.2 91/02/22";*/
/* static char *SCCSID = "@(#)cmsubstr.c	6.2 91/02/22"; */

/*********************************************************************/
/*	 IBM/Microsoft Confidential				     */
/*								     */
/*	 Copyright (c) IBM Corporation 1987, 1989		     */
/*	 Copyright (c) Microsoft Corporation 1987, 1989 	     */
/*								     */
/*	 All Rights Reserved					     */
/*********************************************************************/

/********** START OF SPECIFICATION ********* IBM CONFIDENTIAL ********/
/* SOURCE FILENAME:  CMSUBSTR.C 				     */
/*								     */
/* CONTENTS:	     COM_SUBSTR   COM_STRNCPY			     */
/*********************************************************************/

  #include "cmdbcs.h"                            /* dbcs externs */
  #include "comsub.h"                            /* dbcs externs */
  #include <string.h>				 /* C string support  */
  #include <stdio.h>

/********** START OF SPECIFICATION ********* IBM CONFIDENTIAL ********/
/*								     */
/* SUBROUTINE NAME:  COM_SUBSTR 				     */
/*								     */
/* DESCRIPTIVE NAME:  SEARCH FOR 1ST OCCURENCE OF SUBSTRING	     */
/*		      WITHIN A STRING (STRING VERSION OF STRSTR)     */
/*								     */
/* FUNCTION:							     */
/*								     */
/*								     */
/* NOTES:							     */
/*								     */
/*								     */
/* ENTRY POINT:  com_substr					     */
/*   LINKAGE  : 						     */
/*								     */
/* INPUT:    str1     --- source string pointer (unsigned char ptr)  */
/*	     str2     --- string to be located	(unsigned char ptr)  */
/*								     */
/* EXIT:   integer						     */
/*	 value	       meaning					     */
/*	 pointer       a pointer to the first occurence of string    */
/*	 NULL pointer  given string is not found		     */
/*								     */
/*								     */
/*								     */
/* EXIT-ERROR:							     */
/*	 none							     */
/*								     */
/*								     */
/*								     */
/* EFFECTS:							     */
/*								     */
/* INTERNAL REFERENCES: 					     */
/*   ROUTINES: com_chkdbcs,					     */
/*								     */
/* EXTERNAL REFERENCES: 					     */
/*   ROUTINES: com_settbl,strlen				     */
/*								     */
/* RELEASE:							     */
/*								     */
/*   VERSION	  DATE		 REASON 			     */
/*								     */
/*     1.00	06/13/1986     initial version			     */
/*     1.10	07/15/1987     - JMH - 1) changes from I2 review     */
/*				       2) code cleanup		     */
/*				       3) comment clean up	     */
/*     1.20	03/14/1988    Cora Yang 			     */
/*			     1. The trailing byte and Leading byte   */
/*				could be both in DBCS range.	     */
/*				see ptm 2126.			     */
/*			     2. The most frequently used variables   */
/*				are putting in REGISTERS now to      */
/*				improve the performance.	     */
/*			     3. Use "pointers" instead of "array"    */
/*				to improve the performance.	     */
/*			     4. The calculation which only need      */
/*				to be performed once, we bring it    */
/*				out of the loop to improve the	     */
/*				performance.			     */
/*								     */
/*     2.0    03/29/1988    Changed chk_dbcs to com_chkdbcs	     */
/*								     */
/* B001 02/20/91 fgw  B718926: warning messages for C6 compiles      */
/******************* END OF SPECIFICATIONS ***************************/

  unsigned char *com_substr(str1,str2)	   /*				    */
    unsigned char *str1;		   /* string to be searched	    */
    unsigned char *str2;		   /* search string		    */
    {					   /*				    */
	      int     str1_l, str2_l,len;
	      int     i;
	      int     temp_l;
     register int     temp_i, temp_j;	   /* @@			    */
      int   rc;
					   /*				    */
     com_settbl();			   /* initialize DBCS table	    */
					   /*				    */
     str1_l = strlen(str1);		   /* get string length of str to   */
					   /*  be searched		    */
     str2_l = strlen(str2);		   /* get string length of str to   */
					   /*  search with		    */
					   /*				    */
     if (str2_l > str1_l)		   /* if string to search with is   */
       { return(NULL); }		   /* bigger that string being	    */
					   /* searched then return NULL     */
					   /*				    */
/*************************************/
/*				     */
/* search for substring match	     */
/*  within string to be searched     */
/*				     */
/*************************************/

/* Algorithm:							       */
/*  search until the end of the  shorter string is reached.	       */
/*  if substring 1st char match 				       */
/*    then							       */
/*	  IF the PREVIOUS is not a DBCS Lead byte		       */
/*	      THEN   WE FOUND A METCH				       */
/*								       */
/*								       */
     len = str1_l-str2_l+1;					/* @@  */
     for (i=0; i < len; i++)	    {				/* @@  */
       if (*str2 == *(str1+i) )        {			/* @@  */
	  if ( (rc = com_chkdbcs(str1, i-1)) != DBCS )	   {
	     for (temp_i=i,temp_j=0,temp_l=str2_l;
		  (temp_l > 0) &&
		  (*(str2+temp_j) == *(str1+temp_i));		/* @@	*/
		  temp_l--,temp_i++,temp_j++);

	     if (temp_l == 0)
		 return(str1+i);				/* @@	*/
	  }
       }
     }

  return(NULL); 				 /* return NULL if no match	  */
						 /* on substring		  */
}						 /*				  */


/********** START OF SPECIFICATION ********* IBM CONFIDENTIAL ********/
/*								     */
/* SUBROUTINE NAME:  COM_STRNCPY				     */
/*								     */
/* DESCRIPTIVE NAME:  COPY N CHARACTERS TO A STRING		     */
/*								     */
/* FUNCTION:							     */
/*								     */
/* NOTES:							     */
/*								     */
/* ENTRY POINT:  com_strncpy					     */
/*   LINKAGE  : 						     */
/*								     */
/* INPUT:    trg      --- target string pointer (unsigned char ptr)  */
/*	     src      --- source string pointer (unsigned char ptr)  */
/*	     len      --- maximum length of the copy (unsigned int)  */
/*								     */
/* EXIT:   unsigned char ptr to target string			     */
/*								     */
/* EXIT-ERROR:							     */
/*	 none							     */
/*								     */
/* EFFECTS:							     */
/*								     */
/* INTERNAL REFERENCES: 					     */
/*   ROUTINES:							     */
/*								     */
/* EXTERNAL REFERENCES: 					     */
/*   ROUTINES: check_dbcs					     */
/*								     */
/* RELEASE:							     */
/*								     */
/*   VERSION	  DATE		 REASON 			     */
/*								     */
/*     1.00	11/13/1989     initial version			     */
/*								     */
/******************* END OF SPECIFICATIONS ***************************/

unsigned char *com_strncpy(trg, src, len)
  unsigned char *trg;			 /* ;BC001; target string	      */
  unsigned char *src;			 /* ;BC001; source string	      */
  unsigned int len;			 /* maximum length to copy	      */
{
   char *retptr;

   retptr = trg;			 /* init return ptr		      */

   while (len && *src) {		 /* while chars remain and not max len*/
      if ( check_dbcs(*src) == DBCS ) {  /*    if dbcs lead byte then...      */
	 if (len == 1) {		 /*	  if no room for trail byte...*/
	    break;			 /*	     then punt. 	      */
	 } else {			 /*	  else room for trail byte... */
	    *trg = *src;		 /*	     copy lead byte	      */
	    trg++;			 /*	     increment ptrs	      */
	    src++;			 /*				      */
	    len--;			 /*	     decrement length	      */
	 }
      }
      *trg = *src;			 /*    copy trail byte		      */
      trg++;				 /*    increment ptrs		      */
      src++;				 /*				      */
      len--;				 /*    decrement length 	      */
   }

   while (len) {			 /* while there is room left...       */
      *trg = '\0';                       /*    fill remaining bytes with 0    */
      trg++;				 /*    increment ptr		      */
      len--;				 /*    decrement length 	      */
   }

   return( retptr );			 /* return ptr to target	      */
}
