/* 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; }