/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*--------------------------------------------------------------------*\
Pro/TOOKIT includes
\*--------------------------------------------------------------------*/
#include "ProToolkit.h"
#include "ProUtil.h"
/*--------------------------------------------------------------------*\
C System includes
\*--------------------------------------------------------------------*/
#include <ctype.h>
#include <stdlib.h>
/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "UtilString.h"
#include "TestError.h"
#include "PTApplsUnicodeUtils.h"
/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*\
Application data types
\*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
/*====================================================================*\
FUNCTION : ProUtilStrcmp()
PURPOSE : Like strcmp but case-independent
\*====================================================================*/
int ProUtilStrcmp(
char *s,
char *t)
{
int i = 0;
while( toupper(s[i]) == toupper(t[i]))
{
if( s[i++] == '\0' )
return(0);
}
return(s[i] - t[i]);
}
/*====================================================================*\
FUNCTION : ProUtilStrncmp()
PURPOSE : Like strncmp but case-independent
\*====================================================================*/
int ProUtilStrncmp(
char *s,
char *t,
int n)
{
int i = 0;
int counter = 0;
while( toupper(s[i]) == toupper(t[i]))
{
if(( s[i++] == '\0') || (counter++ >= n) )
return(0);
}
return(s[i] - t[i]);
}
/*====================================================================*\
FUNCTION : ProUtilStringUpper()
PURPOSE : Convert a string to upper case
\*====================================================================*/
void ProUtilStringUpper(
char *input_string,
char *output_string)
{
int i = 0;
while ( input_string[i] != '\0')
{
output_string[i] = (char)toupper(input_string[i]);
i++;
}
output_string[i] = '\0';
}
/*====================================================================*\
FUNCTION : ProUtilStringLower()
PURPOSE : Convert a string to lower case
\*====================================================================*/
void ProUtilStringLower(
char *input_string,
char *output_string)
{
int i = 0;
while ( input_string[i] != '\0')
{
output_string[i] = (char)tolower(input_string[i]);
i++;
}
output_string[i] = '\0';
}
/*====================================================================*\
FUNCTION : ProUtilWstrcmp()
PURPOSE : strcmp() but for wide strings, and case-sensitive.
\*====================================================================*/
int ProUtilWstrcmp(
wchar_t *ws1,
wchar_t *ws2)
{
int result, status;
status = ProWstringCompare (ws1, ws2, PRO_VALUE_UNUSED, &result);
return (result);
}
/*====================================================================*\
FUNCTION : ProUtilWstrCmp()
PURPOSE : strcmp() but for wide strings, and case-insensitive.
\*====================================================================*/
int ProUtilWstrCmp(
wchar_t *ws1,
wchar_t *ws2)
{
int len1, len2;
char* us1;
char* us2;
int result;
ProWstringLengthGet (ws1, &len1);
ProWstringLengthGet (ws2, &len2);
/* Allow extra length for wchar_t -> char conversion */
us1 = (char*) calloc ((4*len1+1), sizeof (char));
us2 = (char*) calloc ((4*len2+1), sizeof (char));
ProWstringToString (us1, ws1);
ProWstringToString (us2, ws2);
result = ProUtilStrcmp (us1, us2);
free (us1);
free (us2);
return (result);
}
/*====================================================================*\
FUNCTION : ProUtilWstrncmp()
PURPOSE : strncmp() but for wide strings, and case-insensitive.
\*====================================================================*/
int ProUtilWstrncmp(
wchar_t *ws1,
wchar_t *ws2,
int n)
{
int len1, len2;
char* us1;
char* us2;
int result;
ProWstringLengthGet (ws1, &len1);
ProWstringLengthGet (ws2, &len2);
/* Allow extra length for wchar_t -> char conversion */
us1 = (char*) calloc ((4*len1+1), sizeof (char));
us2 = (char*) calloc ((4*len2+1), sizeof (char));
ProWstringToString (us1, ws1);
ProWstringToString (us2, ws2);
result = ProUtilStrncmp (us1, us2, n);
free (us1);
free (us2);
return (result);
}
/*====================================================================*\
FUNCTION : ProUtilWstrcpy()
PURPOSE : strcpy() but for wide strings
\*====================================================================*/
wchar_t *ProUtilWstrcpy(
wchar_t *ws1,
wchar_t *ws2)
{
ProWstringCopy (ws2, ws1, PRO_VALUE_UNUSED);
return (ws2);
}
/*====================================================================*\
FUNCTION : ProUtilStrwscmp()
PURPOSE : Compare a string to a wide string
\*====================================================================*/
int ProUtilStrwscmp(
char *s1,
wchar_t *ws2)
{
wchar_t* ws1;
int result;
int len = strlen (s1);
ws1 = (wchar_t*) calloc (len + 1, sizeof (wchar_t));
ProStringToWstring (ws1, s1);
result = ProUtilWstrcmp(ws1, ws2);
free (ws1);
return (result);
}
/*====================================================================*\
FUNCTION : ProUtilStrnwscmp()
PURPOSE : strncmp() for a string and a wide string
\*====================================================================*/
int ProUtilStrnwscmp(
char *s1,
wchar_t *ws2,
int n)
{
wchar_t* ws1;
int result;
ws1 = (wchar_t*) calloc (n+1, sizeof (wchar_t));
ProStringToWstring (ws1, s1);
result = ProUtilWstrncmp(ws1, ws2, n);
free (ws1);
return (result);
}
/*====================================================================*\
FUNCTION : ProUtilWstrPrint()
PURPOSE : printf a wide string - for diagnostics
\*====================================================================*/
int ProUtilWstrPrint(
wchar_t *ws1,
int width)
{
char s1[PRO_PATH_SIZE], format[10];
ProTKSprintf(format,"%%-%ds", width);
ProWstringToString(s1, ws1);
ProTKPrintf(format, s1);
return (0);
}
/*=====================================================================*\
Function: ProUtilWstrLen()
Purpose: Get the length of a wide string
\*=====================================================================*/
int ProUtilWstrLen(
wchar_t *wstr)
{
int n;
ProWstringLengthGet (wstr, &n);
return(n);
}
/*=====================================================================*\
Function: ProUtilWstrcat()
Purpose: Concatenates two wide strings
\*=====================================================================*/
wchar_t *ProUtilWstrcat(
wchar_t *ws1,
wchar_t *ws2)
{
ProWstringConcatenate (ws2, ws1, PRO_VALUE_UNUSED);
return (ws1);
}
/*=====================================================================*\
Function: ProUtilWstrStrcatToWstr()
Purpose: Concatenates a wstring and a string and returns a wstring
\*=====================================================================*/
wchar_t *ProUtilWstrStrcatToWstr(
wchar_t *ws1,
char *s2)
{
wchar_t* ws2;
int len = strlen (s2);
ws2 = (wchar_t*) calloc (len + 1, sizeof (wchar_t));
ProStringToWstring (ws2, s2);
ProWstringConcatenate (ws2, ws1, PRO_VALUE_UNUSED);
free (ws2);
return(ws1);
}
/*=====================================================================*\
Function: ProUtilStrWstrcatToStr
Purpose: Concatenates a string and a wstring and returns a string
\*=====================================================================*/
char *ProUtilStrWstrcatToStr(char *s1, wchar_t *ws2)
{
char s2[PRO_PATH_SIZE];
ProError status;
ProWstringToString(s2,ws2);
status = ProUtilstrcat(s1, s2);
return(s1);
}
/*=====================================================================*\
Function: ProUtilWstringArrayToFile
Purpose: prints an array of Wstrings into a file
\*=====================================================================*/
ProError ProUtilWstringArrayToFile (ProWstring* str_xar, ProPath wpath)
{
ProError status;
int str_num, str_count;
ProCharLine path;
FILE * fp;
ProCharLine a_string;
ProWstringToString (path, wpath);
fp = PTApplsUnicodeFopen(path, "w");
status = ProArraySizeGet(str_xar, &str_num);
TEST_CALL_REPORT("ProArraySizeGet", "ProUtilWstringArrayToFile",
status, (status != PRO_TK_NO_ERROR));
if (status != PRO_TK_NO_ERROR) return (status);
for (str_count = 0 ; str_count < str_num; str_count++)
{
ProWstringToString(a_string, (str_xar)[str_count]);
ProTKFprintf(fp, "%s\n",a_string);
}
fclose(fp);
return(PRO_TK_NO_ERROR);
}
/*=====================================================================*\
Function: ProUtilFileToWstringArray
Purpose: parses the lines of a file into a wide string array
\*=====================================================================*/
ProError ProUtilFileToWstringArray (ProPath wpath, ProWstring** str_xar)
{
ProError status;
FILE * fp;
ProCharLine a_line;
ProLine a_wline;
ProWstring a_wstring;
ProCharLine path;
/*------------------------------------------------------------------*\
Get the file pointer
\*------------------------------------------------------------------*/
ProWstringToString (path, wpath);
fp = PTApplsUnicodeFopen(path, "r");
/*------------------------------------------------------------------*\
Add each line of the file into a location of the array
\*------------------------------------------------------------------*/
while(!feof(fp))
{
if (fgets (a_line, PRO_LINE_SIZE, fp) == NULL)
return (PRO_TK_NO_ERROR);
ProStringToWstring(a_wline, a_line);
a_wstring = a_wline;
status = ProWstringArrayObjectAdd(str_xar, PRO_VALUE_UNUSED, 1, &a_wstring);
TEST_CALL_REPORT("ProWstringArrayObjectAdd", "ProUtilFileToWstringArray",
status, (status != PRO_TK_NO_ERROR));
if (status != PRO_TK_NO_ERROR) return (status);
}
fclose(fp);
return (PRO_TK_NO_ERROR);
}
/*=====================================================================*\
Function: ProUtilstrcpy
Purpose: Copy source_string into dest_string
\*=====================================================================*/
ProError ProUtilstrcpy(
char *dest_string,
const char *source_string )
{
if (dest_string == NULL)
return PRO_TK_BAD_INPUTS;
while ( (*dest_string++ = *source_string++) != '\0') ;
return PRO_TK_NO_ERROR;;
}
/*=====================================================================*\
Function: ProUtilstrcat
Purpose: Concatnet source_string to dest_string
\*=====================================================================*/
ProError ProUtilstrcat(char * dest_string, const char * source_string)
{
char * cp = dest_string;
ProError status;
if (dest_string == NULL)
return PRO_TK_BAD_INPUTS;
while( *cp )
++cp;
status = ProUtilstrcpy(cp,source_string);
return PRO_TK_NO_ERROR;;
}
/*=====================================================================*\
Function: ProUtilstrncpy
Purpose: Copies copy_length char's of source_string into dest_string
\*=====================================================================*/
ProError ProUtilstrncpy (char *dest_string, const char *source_string,
int copy_length )
{
int i;
if (dest_string == NULL || source_string == NULL)
return PRO_TK_BAD_INPUTS;
if (copy_length < 0)
return PRO_TK_BAD_INPUTS;
if (copy_length == 0)
return PRO_TK_BAD_INPUTS;
for (i = 1 ;
((*dest_string++ = *source_string++) != '\0') && (i < copy_length) ; i++ );
for ( ; i < copy_length; i++ )
*dest_string++ = '\0';
return PRO_TK_NO_ERROR;
}