2010-08-25 21:42:57 +00:00
|
|
|
/*
|
|
|
|
* NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
|
|
|
|
*
|
|
|
|
* Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
|
|
|
|
*
|
|
|
|
* Tecplot hereby grants OpenCFD limited authority to distribute without
|
2013-07-18 01:02:34 +00:00
|
|
|
* alteration the source code to the Tecplot Input/Output library, known
|
|
|
|
* as TecIO, as part of its distribution of OpenFOAM and the
|
2010-08-25 21:42:57 +00:00
|
|
|
* OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
|
|
|
|
* granted access to the TecIO source code, and may redistribute it for the
|
|
|
|
* purpose of maintaining the converter. However, no authority is granted
|
|
|
|
* to alter the TecIO source code in any form or manner.
|
|
|
|
*
|
2013-07-18 01:02:34 +00:00
|
|
|
* This limited grant of distribution does not supersede Tecplot, Inc.'s
|
2010-08-25 21:42:57 +00:00
|
|
|
* copyright in TecIO. Contact Tecplot, Inc. for further information.
|
2013-07-18 01:02:34 +00:00
|
|
|
*
|
2010-08-25 21:42:57 +00:00
|
|
|
* Tecplot, Inc.
|
|
|
|
* 3535 Factoria Blvd, Ste. 550
|
|
|
|
* Bellevue, WA 98006, USA
|
|
|
|
* Phone: +1 425 653 1200
|
|
|
|
* http://www.tecplot.com/
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "MASTER.h"
|
|
|
|
#define TECPLOTENGINEMODULE
|
|
|
|
|
|
|
|
/*
|
|
|
|
******************************************************************
|
|
|
|
******************************************************************
|
|
|
|
******* ********
|
|
|
|
****** (C) 1988-2008 Tecplot, Inc. *******
|
|
|
|
******* ********
|
|
|
|
******************************************************************
|
|
|
|
******************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define STRUTILMODULE
|
|
|
|
#include "GLOBAL.h"
|
|
|
|
#include "TASSERT.h"
|
|
|
|
#include "Q_UNICODE.h"
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
#include "ARRLIST.h"
|
|
|
|
#include "STRLIST.h"
|
|
|
|
#include "STRUTIL.h"
|
|
|
|
#include "ALLOC.h"
|
|
|
|
|
|
|
|
#include "Q_MSG.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cctype> // ...needed to find std::tolower and std::toupper
|
|
|
|
#include <limits.h>
|
|
|
|
#include "TranslatedString.h"
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace tecplot::strutil;
|
|
|
|
|
|
|
|
#ifdef MSWIN
|
|
|
|
# pragma warning (disable : 4786) /* STL warning about trucated identifiers */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* END HEADER */
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
#define INITIAL_FORMAT_BUFFER_SIZE 16384*3
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
static char *FormatStringBuffer = NULL;
|
|
|
|
static int FormatStringBufferSize = INITIAL_FORMAT_BUFFER_SIZE;
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#if defined MSWIN
|
|
|
|
#else
|
|
|
|
#endif /* !MSWIN */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This should be one of the last functions called by Tecplot while mopping up.
|
|
|
|
*/
|
|
|
|
void FormatStringBufferCleanup(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* NOTE: We use free instead of FREE_ARRAY for the scratch buffer because in
|
|
|
|
* debug mode FREE_ARRAY uses ErrMsg which uses vFormatString causing
|
|
|
|
* infinite recursion.
|
|
|
|
*/
|
|
|
|
if (FormatStringBuffer != NULL)
|
|
|
|
free(FormatStringBuffer);
|
|
|
|
FormatStringBuffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
char *vFormatString(const char *Format,
|
|
|
|
va_list Arguments)
|
|
|
|
{
|
|
|
|
char *Result = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(Format));
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: We use malloc instead of ALLOC_ARRAY for the scratch buffer because
|
|
|
|
* in debug mode ALLOC_ARRAY uses ErrMsg which uses vFormatString
|
|
|
|
* causing infinite recursion.
|
|
|
|
*/
|
|
|
|
if (FormatStringBuffer == NULL)
|
|
|
|
FormatStringBuffer = (char *)malloc(FormatStringBufferSize);
|
|
|
|
|
|
|
|
if (FormatStringBuffer != NULL)
|
|
|
|
{
|
|
|
|
Boolean_t TryAgain = FALSE;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Assign a value other than '\0' to the end of the buffer so that we
|
|
|
|
* can determine if the buffer needs to be expanded. If after we call
|
|
|
|
* vsnprintf the end of the buffer has a '\0' we need to expand it.
|
|
|
|
*/
|
|
|
|
FormatStringBuffer[FormatStringBufferSize - 1] = (char)!'\0';
|
|
|
|
|
|
|
|
# if defined MSWIN
|
|
|
|
memset(FormatStringBuffer, 0, FormatStringBufferSize - 1);
|
|
|
|
|
|
|
|
TryAgain =
|
|
|
|
_vsnprintf(FormatStringBuffer,
|
|
|
|
FormatStringBufferSize,
|
|
|
|
Format,
|
|
|
|
Arguments) == -1;
|
|
|
|
# elif defined IRIX62
|
|
|
|
vsprintf(FormatStringBuffer,
|
|
|
|
Format,
|
|
|
|
Arguments);
|
|
|
|
CHECK(strlen(FormatStringBuffer) < FormatStringBufferSize);
|
|
|
|
# else
|
|
|
|
vsnprintf(FormatStringBuffer,
|
|
|
|
FormatStringBufferSize,
|
|
|
|
Format,
|
|
|
|
Arguments);
|
|
|
|
# endif
|
|
|
|
|
|
|
|
#ifndef MSWIN
|
|
|
|
TryAgain = (FormatStringBuffer[FormatStringBufferSize - 1] == '\0');
|
|
|
|
#endif
|
|
|
|
if (TryAgain)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Reallocate the buffer and try again.
|
|
|
|
*
|
|
|
|
* NOTE: We use malloc/free instead of ALLOC/FREE_ARRAY for the
|
|
|
|
* scratch buffer because in debug mode ALLOC/FREE_ARRAY
|
|
|
|
* uses ErrMsg which uses vFormatString causing infinite
|
|
|
|
* recursion.
|
|
|
|
*/
|
|
|
|
free(FormatStringBuffer);
|
|
|
|
FormatStringBufferSize += MAX(1, FormatStringBufferSize / 2);
|
|
|
|
FormatStringBuffer = (char *)malloc(FormatStringBufferSize);
|
|
|
|
TryAgain = (FormatStringBuffer != NULL);
|
|
|
|
if (!TryAgain)
|
|
|
|
FormatStringBufferSize = INITIAL_FORMAT_BUFFER_SIZE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (TryAgain);
|
|
|
|
|
|
|
|
if (FormatStringBuffer != NULL)
|
|
|
|
Result = DupString(dontTranslate(FormatStringBuffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(Result) || Result == NULL);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
char *FormatString(TranslatedString Format,
|
|
|
|
...) /* 0 or more variable arguments */
|
|
|
|
{
|
|
|
|
REQUIRE(!Format.isNull());
|
|
|
|
|
|
|
|
va_list Arguments;
|
|
|
|
va_start(Arguments, Format);
|
|
|
|
char *Result = vFormatString(Format.c_str(), Arguments);
|
|
|
|
va_end(Arguments);
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(Result) || Result == NULL);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
int FormatString(string& Buffer,
|
|
|
|
TranslatedString Format
|
|
|
|
...) /* 0 or more variable arguments */
|
|
|
|
{
|
|
|
|
REQUIRE(!Format.isNull());
|
|
|
|
|
|
|
|
va_list Arguments;
|
|
|
|
va_start(Arguments, Format);
|
|
|
|
char *FormattedString = vFormatString(Format.c_str(), Arguments);
|
|
|
|
va_end(Arguments);
|
|
|
|
|
|
|
|
int Result;
|
|
|
|
if (FormattedString != NULL)
|
|
|
|
{
|
|
|
|
Buffer.assign(FormattedString);
|
|
|
|
Result = (int)Buffer.size();
|
|
|
|
FREE_ARRAY(FormattedString, "FormattedString");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Result = -1;
|
|
|
|
|
|
|
|
|
|
|
|
ENSURE(Result == -1 || Result >= 0);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a duplicate of the string or NULL if sufficient memory is not
|
|
|
|
* available.
|
|
|
|
*
|
|
|
|
* NOTE: This function was created because ResetString(...) does not
|
|
|
|
* duplicate zero length strings but returns NULL instead.
|
|
|
|
*/
|
|
|
|
char *DupString(TranslatedString String)
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_TRANSLATED_STRING(String));
|
|
|
|
|
|
|
|
char *Result = ALLOC_ARRAY(strlen(String.c_str()) + 1, char, "duplicate string");
|
|
|
|
if (Result != NULL)
|
|
|
|
strcpy(Result, String.c_str());
|
|
|
|
|
|
|
|
ENSURE(Result == NULL || (VALID_REF(Result) && strcmp(Result, String.c_str()) == 0));
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy up to 'Count' characters from the 'Source' string beginning at
|
|
|
|
* position 'Index' to the 'Target' string. The actual number of characters
|
|
|
|
* copied may be less than 'Count' if a '\0' was encountered in the
|
|
|
|
* 'Source' string before 'Count' characters were copied.
|
|
|
|
*
|
|
|
|
* NOTE: The 'Target' and 'Source' strings may overlap.
|
|
|
|
*/
|
|
|
|
void CopySubString(char *Target,
|
|
|
|
const char *Source,
|
|
|
|
int Index,
|
|
|
|
int Count)
|
|
|
|
{
|
|
|
|
LgIndex_t Length = 0;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(Target));
|
|
|
|
REQUIRE("Target string is sized to accommodate a string who's length "
|
|
|
|
"is at least MIN(strlen(&Source[Index]), Count) characters.");
|
|
|
|
REQUIRE(VALID_REF(Source));
|
|
|
|
REQUIRE(0 <= Index && Index <= (LgIndex_t)strlen(Source));
|
|
|
|
REQUIRE(Count >= 0);
|
|
|
|
|
|
|
|
Length = MIN((LgIndex_t)strlen(&Source[Index]), Count);
|
|
|
|
memmove(Target, &Source[Index], Length);
|
|
|
|
Target[Length] = '\0';
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(Target) && (LgIndex_t)strlen(Target) == Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif /* TECPLOTKERNEL */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove any leading white space from the string and return
|
|
|
|
* a reference to it. NOTE: The input string is modified.
|
|
|
|
*/
|
|
|
|
char *StringFlushLeft(char *String)
|
|
|
|
{
|
|
|
|
char *Result = String;
|
|
|
|
char *Start = String;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
|
|
|
|
/* move the substring beginning at the first non-whitespace */
|
|
|
|
/* character to the head of the string */
|
|
|
|
while (isspace(*Start))
|
|
|
|
Start++;
|
|
|
|
if (Start != String)
|
|
|
|
memmove(String, Start, strlen(Start) + 1);
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(Result) && Result == String);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove any trailing white space from the string and return
|
|
|
|
* a reference to it. NOTE: The input string is modified.
|
|
|
|
*/
|
|
|
|
static char *StringFlushRight(char *String)
|
|
|
|
{
|
|
|
|
char *Result = String;
|
|
|
|
char *End = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
|
|
|
|
for (End = EndOfString(String); End != String && isspace(End[-1]); End--)
|
|
|
|
End[-1] = '\0';
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(Result) && Result == String);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove any leading and trailing white space from the string
|
|
|
|
* and return a reference to it. The return value is not
|
|
|
|
* absolutely necessary since the input string is modified
|
|
|
|
* but it is convenient sometimes.
|
|
|
|
* NOTE: The input string is modified but no memory is
|
|
|
|
* allocated nor deallocated.
|
|
|
|
*/
|
|
|
|
char *TrimLeadAndTrailSpaces(char *String)
|
|
|
|
{
|
|
|
|
REQUIRE((String == NULL) || VALID_REF(String));
|
|
|
|
if (String)
|
|
|
|
return (StringFlushLeft(StringFlushRight(String)));
|
|
|
|
else
|
|
|
|
return String;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the specified string is longer than the maximum specified length
|
|
|
|
* truncate it and return a reference to it.
|
|
|
|
*
|
|
|
|
* String
|
|
|
|
* String to truncate if necessary.
|
|
|
|
* MaxLength
|
|
|
|
* Length at which to truncate the specified string if exceeded.
|
|
|
|
*
|
|
|
|
* Return
|
|
|
|
* Reference to the input string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
char *StringTruncate(char *String,
|
|
|
|
LgIndex_t MaxLength)
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
REQUIRE(MaxLength >= 0);
|
|
|
|
|
|
|
|
if ((LgIndex_t)strlen(String) > MaxLength)
|
|
|
|
String[MaxLength] = '\0';/* UTF8_SetAt(String,'\0',MaxLength); */
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(String));
|
|
|
|
ENSURE((LgIndex_t)strlen(String) <= MaxLength);
|
|
|
|
return String;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Trim and truncate the specified string such that its trimmed length
|
|
|
|
* does not exceed the specified length and return a reference to it.
|
|
|
|
*
|
|
|
|
* String
|
|
|
|
* String to trim and truncate if necessary.
|
|
|
|
* MaxLength
|
|
|
|
* Length at which to truncate the trimmed string if exceeded.
|
|
|
|
*
|
|
|
|
* Return
|
|
|
|
* Reference to the input string.
|
|
|
|
*/
|
|
|
|
char *StringTrimAndTruncate(char *String,
|
|
|
|
LgIndex_t MaxLength)
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
REQUIRE(MaxLength >= 0);
|
|
|
|
|
|
|
|
TrimLeadAndTrailSpaces(String);
|
|
|
|
StringTruncate(String, MaxLength);
|
|
|
|
|
|
|
|
ENSURE(VALID_REF(String));
|
|
|
|
ENSURE((LgIndex_t)strlen(String) <= MaxLength);
|
|
|
|
return String;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef MSWIN
|
|
|
|
StringList_pa LineBreakString(const char *String,
|
|
|
|
UInt32_t WrapMargin)
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
|
|
|
|
StringList_pa Result = StringListAlloc();
|
|
|
|
if (Result != NULL)
|
|
|
|
{
|
|
|
|
Boolean_t IsOk = TRUE;
|
|
|
|
if (strlen(String) > WrapMargin)
|
|
|
|
{
|
|
|
|
char *StringCopy = DupString(dontTranslate(String));
|
|
|
|
IsOk = (StringCopy != NULL);
|
|
|
|
if (IsOk)
|
|
|
|
{
|
|
|
|
char *CPtr = StringCopy;
|
|
|
|
char *SubString = StringCopy;
|
|
|
|
UInt32_t SubStringLen = 0;
|
|
|
|
while (*CPtr != '\0' && IsOk)
|
|
|
|
{
|
|
|
|
while (*CPtr != '\0' && SubStringLen < WrapMargin)
|
|
|
|
{
|
|
|
|
/* look for a hard break */
|
|
|
|
if (*CPtr == '\n')
|
|
|
|
{
|
|
|
|
*CPtr = '\0'; /* replace the newline */
|
|
|
|
CPtr++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CPtr++;
|
|
|
|
SubStringLen++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we didn't find a hard break or the end of the string
|
|
|
|
* then we need to back up and find the closest space.
|
|
|
|
*/
|
|
|
|
if (*CPtr != '\0' && SubStringLen == WrapMargin)
|
|
|
|
{
|
|
|
|
/* find the closes space from the right */
|
|
|
|
if (*CPtr != ' ')
|
|
|
|
{
|
|
|
|
while (CPtr != SubString && *CPtr != ' ')
|
|
|
|
CPtr--;
|
|
|
|
if (*CPtr != ' ')
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Bummer, this line will exceed the wrap margin.
|
|
|
|
* Search forward for the next space or newline.
|
|
|
|
*/
|
|
|
|
while (*CPtr != '\0' && *CPtr != ' ' && *CPtr != '\n')
|
|
|
|
CPtr++;
|
|
|
|
while (*CPtr != '\0' && *CPtr == ' ')
|
|
|
|
CPtr++; /* skip over the white space */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*CPtr != '\0')
|
|
|
|
{
|
|
|
|
*CPtr = '\0';
|
|
|
|
CPtr++;
|
|
|
|
}
|
|
|
|
StringFlushRight(SubString);
|
|
|
|
}
|
|
|
|
|
|
|
|
IsOk = StringListAppendString(Result, SubString);
|
|
|
|
SubString = CPtr;
|
|
|
|
SubStringLen = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
FREE_ARRAY(StringCopy, "StringCopy");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
IsOk = StringListAppendString(Result, String);
|
|
|
|
|
|
|
|
if (!IsOk)
|
|
|
|
StringListDealloc(&Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
ENSURE(Result == NULL || VALID_REF(Result));
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif /* TECPLOTKERNEL */
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lexicographically compares, at most, the first 'Len' characters of
|
|
|
|
* s1 and s2.
|
|
|
|
*
|
|
|
|
* param s1
|
|
|
|
* First string or NULL.
|
|
|
|
* param s2
|
|
|
|
* Second string or NULL.
|
|
|
|
* param Len
|
|
|
|
* Maximum number of characters to compare.
|
|
|
|
* return
|
|
|
|
* Integer value greater than, equal to, or less than zero according
|
|
|
|
* to whether the first 'Len' characters of 's1' are greater than,
|
|
|
|
* equal to, or less than 's2'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
int ustrncmp(const char *s1,
|
|
|
|
const char *s2,
|
|
|
|
size_t Len)
|
|
|
|
{
|
|
|
|
REQUIRE((s1 == NULL) || VALID_REF(s1));
|
|
|
|
REQUIRE((s2 == NULL) || VALID_REF(s2));
|
|
|
|
REQUIRE(Len >= 0);
|
|
|
|
|
|
|
|
char *t1;
|
|
|
|
char *t2;
|
|
|
|
char ct1;
|
|
|
|
char ct2;
|
|
|
|
size_t I = 0;
|
|
|
|
if ((s1 == NULL) && (s2 == NULL))
|
|
|
|
return 0;
|
|
|
|
if (s1 == NULL)
|
|
|
|
return -1;
|
|
|
|
else if (s2 == NULL)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
t1 = (char*)s1;
|
|
|
|
t2 = (char*)s2;
|
|
|
|
|
|
|
|
while (*t1 && *t2 && (I < Len))
|
|
|
|
{
|
|
|
|
ct1 = CAPITAL(*t1);
|
|
|
|
ct2 = CAPITAL(*t2);
|
|
|
|
if (ct1 != ct2)
|
|
|
|
return (ct1 - ct2);
|
|
|
|
t1++;
|
|
|
|
t2++;
|
|
|
|
I++;
|
|
|
|
}
|
|
|
|
if ((I == Len) ||
|
|
|
|
((*t1 == '\0') && (*t2 == '\0')))
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return CAPITAL(*t1) - CAPITAL(*t2);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lexicographically compares the characters of s1 and s2.
|
|
|
|
*
|
|
|
|
* param s1
|
|
|
|
* First string or NULL.
|
|
|
|
* param s2
|
|
|
|
* Second string or NULL.
|
|
|
|
* return
|
|
|
|
* Integer value greater than, equal to, or less than zero according to
|
|
|
|
* whether the characters of 's1' are greater than, equal to, or less
|
|
|
|
* than 's2'.
|
|
|
|
*/
|
|
|
|
int ustrcmp(const char *s1,
|
|
|
|
const char *s2)
|
|
|
|
{
|
|
|
|
REQUIRE((s1 == NULL) || VALID_REF(s1));
|
|
|
|
REQUIRE((s2 == NULL) || VALID_REF(s2));
|
|
|
|
|
|
|
|
return (ustrncmp(s1, s2, INT_MAX));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#if !defined NO_ASSERTS && defined DEBUG_ALLOC
|
|
|
|
#endif
|
|
|
|
#endif /* TECPLOTKERNEL */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The problem with passing file names for release builds is that
|
|
|
|
* the full path name is used (i.e., c:\user\craig\v7.5\tecplot\alloc.c)
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
|
|
|
|
#if !defined NO_ASSERTS
|
|
|
|
Boolean_t InternalResetString(char **SBase,
|
|
|
|
const char *NewString,
|
|
|
|
Boolean_t IssueErrMsg,
|
|
|
|
const char *FileName,
|
|
|
|
int LineNumber)
|
|
|
|
#else
|
|
|
|
Boolean_t InternalResetString(char **SBase,
|
|
|
|
const char *NewString,
|
|
|
|
Boolean_t IssueErrMsg)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_REF(SBase));
|
|
|
|
REQUIRE(*SBase == NULL || VALID_REF(*SBase));
|
|
|
|
REQUIRE(NewString == NULL || VALID_REF(NewString));
|
|
|
|
REQUIRE(IMPLICATION(VALID_REF(*SBase), *SBase != NewString)); /* Prevent calling with same string. */
|
|
|
|
REQUIRE(VALID_BOOLEAN(IssueErrMsg));
|
|
|
|
REQUIRE(VALID_NON_ZERO_LEN_STR(FileName));
|
|
|
|
REQUIRE(LineNumber >= 1);
|
|
|
|
|
|
|
|
if (*SBase)
|
|
|
|
{
|
|
|
|
#if !defined NO_ASSERTS && defined DEBUG_ALLOC
|
|
|
|
char S[80+1];
|
|
|
|
MakeDebugRecord(FileName, LineNumber, "releasing", *SBase, S, 80);
|
|
|
|
FREE_ARRAY(*SBase, S);
|
|
|
|
#else
|
|
|
|
FREE_ARRAY(*SBase, "");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (NewString == NULL)
|
|
|
|
{
|
|
|
|
*SBase = NULL;
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if !defined NO_ASSERTS && defined DEBUG_ALLOC
|
|
|
|
char S[80+1];
|
|
|
|
MakeDebugRecord(FileName, LineNumber, "duplicating", NewString, S, 80);
|
|
|
|
*SBase = ALLOC_ARRAY(strlen(NewString) + 1, char, S);
|
|
|
|
#else
|
|
|
|
# if defined MSWIN && defined _DEBUG && !defined(MAKEARCHIVE) && !defined(NO_ASSERTS)
|
|
|
|
/* Allow the MFC memory leak detection to report the leak at the
|
|
|
|
* calling programs location, and not here (which is fairly useless).
|
|
|
|
* But first, we have to turn off the preprocessor definition of new
|
|
|
|
* and get to the original. */
|
|
|
|
# undef new
|
|
|
|
*SBase = new(FileName, LineNumber) char[strlen(NewString)+1];
|
|
|
|
# define new DEBUG_NEW
|
|
|
|
# else
|
|
|
|
*SBase = ALLOC_ARRAY(strlen(NewString) + 1, char, "");
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
if (*SBase)
|
|
|
|
{
|
|
|
|
strcpy(*SBase, NewString);
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (IssueErrMsg)
|
|
|
|
ErrMsg(translate("Out of memory"));
|
|
|
|
return (FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unfortunately, this routine uses the interface of DeleteStringToAdd
|
|
|
|
* forcing StringToAdd to be non-const. Another copy of this routine
|
|
|
|
* for const char *'s is below. Eventually we should get rid of
|
|
|
|
* the two routines and DeleteStringToAdd, always using the const version
|
|
|
|
* and deleting the string if necessary in the code that calls TackOnString.
|
|
|
|
*/
|
|
|
|
Boolean_t TackOnString(char **SBase,
|
|
|
|
const char *StringToAdd,
|
|
|
|
Boolean_t DeleteStringToAdd,
|
|
|
|
Boolean_t ConvertNewlinesToAscii)
|
|
|
|
{
|
|
|
|
size_t CurLen;
|
|
|
|
size_t NewLen;
|
|
|
|
int NumNewlines = 0;
|
|
|
|
char *NewString;
|
|
|
|
const char *CPtr = StringToAdd;
|
|
|
|
Boolean_t IsOk = TRUE;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(SBase));
|
|
|
|
REQUIRE((StringToAdd == NULL) || VALID_REF(StringToAdd));
|
|
|
|
REQUIRE(VALID_BOOLEAN(DeleteStringToAdd));
|
|
|
|
REQUIRE(VALID_BOOLEAN(ConvertNewlinesToAscii));
|
|
|
|
|
|
|
|
if ((StringToAdd == NULL) ||
|
|
|
|
(*StringToAdd == '\0'))
|
|
|
|
{
|
|
|
|
if (StringToAdd &&
|
|
|
|
(*StringToAdd == '\0') &&
|
|
|
|
DeleteStringToAdd)
|
|
|
|
{
|
|
|
|
char *TMP = (char *)StringToAdd;
|
|
|
|
FREE_ARRAY(TMP, "empty string to add");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
if (*SBase == NULL)
|
|
|
|
CurLen = 0;
|
|
|
|
else
|
|
|
|
CurLen = strlen(*SBase);
|
|
|
|
|
|
|
|
while (*CPtr)
|
|
|
|
if (*CPtr++ == '\n')
|
|
|
|
NumNewlines++;
|
|
|
|
|
|
|
|
NewLen = CurLen + strlen(StringToAdd) + 1 + NumNewlines;
|
|
|
|
|
|
|
|
NewString = ALLOC_ARRAY(NewLen, char, StringToAdd);
|
|
|
|
|
|
|
|
if (NewString == NULL)
|
|
|
|
{
|
|
|
|
if (DeleteStringToAdd)
|
|
|
|
{
|
|
|
|
char *TMP = (char *)StringToAdd;
|
|
|
|
FREE_ARRAY(TMP, StringToAdd);
|
|
|
|
}
|
|
|
|
IsOk = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*SBase)
|
|
|
|
{
|
|
|
|
strcpy(NewString, *SBase);
|
|
|
|
FREE_ARRAY(*SBase, (CurLen > 0 ? *SBase : "previous text"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*NewString = '\0';
|
|
|
|
|
|
|
|
{
|
|
|
|
char *NPtr = EndOfString(NewString);
|
|
|
|
const char *APtr = StringToAdd;
|
|
|
|
while (*APtr)
|
|
|
|
{
|
|
|
|
if ((*APtr == '\n') && ConvertNewlinesToAscii)
|
|
|
|
{
|
|
|
|
*NPtr++ = '\\';
|
|
|
|
*NPtr++ = 'n';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*NPtr++ = *APtr; //UTF8_AssignAndIncrement(&NPtr,(char**)&APtr,TRUE,FALSE); //*NPtr++ = *APtr;
|
|
|
|
APtr++;
|
|
|
|
}
|
|
|
|
*NPtr = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DeleteStringToAdd)
|
|
|
|
{
|
|
|
|
char *TMP = (char *)StringToAdd;
|
|
|
|
FREE_ARRAY(TMP, StringToAdd);
|
|
|
|
}
|
|
|
|
|
|
|
|
*SBase = NewString;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ENSURE(VALID_BOOLEAN(IsOk));
|
|
|
|
return (IsOk);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See TackOnString for discussion.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
Boolean_t TackOnConstString(char **SBase,
|
|
|
|
const char *StringToAdd,
|
|
|
|
Boolean_t ConvertNewlinesToAscii)
|
|
|
|
{
|
|
|
|
size_t CurLen;
|
|
|
|
size_t NewLen;
|
|
|
|
int NumNewlines = 0;
|
|
|
|
char *NewString;
|
|
|
|
const char *CPtr = StringToAdd;
|
|
|
|
Boolean_t IsOk = TRUE;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(SBase));
|
|
|
|
REQUIRE((StringToAdd == NULL) || VALID_REF(StringToAdd));
|
|
|
|
REQUIRE(VALID_BOOLEAN(ConvertNewlinesToAscii));
|
|
|
|
|
|
|
|
if ((StringToAdd != NULL) &&
|
|
|
|
(*StringToAdd != '\0'))
|
|
|
|
{
|
|
|
|
if (*SBase == NULL)
|
|
|
|
CurLen = 0;
|
|
|
|
else
|
|
|
|
CurLen = strlen(*SBase);
|
|
|
|
|
|
|
|
while (*CPtr)
|
|
|
|
if (*CPtr++ == '\n')
|
|
|
|
NumNewlines++;
|
|
|
|
|
|
|
|
NewLen = CurLen + strlen(StringToAdd) + 1 + NumNewlines;
|
|
|
|
|
|
|
|
NewString = ALLOC_ARRAY(NewLen, char, StringToAdd);
|
|
|
|
|
|
|
|
if (NewString == NULL)
|
|
|
|
{
|
|
|
|
IsOk = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*SBase)
|
|
|
|
{
|
|
|
|
strcpy(NewString, *SBase);
|
|
|
|
FREE_ARRAY(*SBase, (CurLen > 0 ? *SBase : "previous text"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*NewString = '\0';
|
|
|
|
|
|
|
|
{
|
|
|
|
char *NPtr = EndOfString(NewString);
|
|
|
|
const char *APtr = StringToAdd;
|
|
|
|
while (*APtr)
|
|
|
|
{
|
|
|
|
if ((*APtr == '\n') && ConvertNewlinesToAscii)
|
|
|
|
{
|
|
|
|
*NPtr++ = '\\';
|
|
|
|
*NPtr++ = 'n';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*NPtr++ = *APtr; // UTF8_AssignAndIncrement(&NPtr,(char**)&APtr,TRUE,FALSE);
|
|
|
|
APtr++;
|
|
|
|
}
|
|
|
|
*NPtr = '\0';
|
|
|
|
}
|
|
|
|
*SBase = NewString;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ENSURE(VALID_BOOLEAN(IsOk));
|
|
|
|
return (IsOk);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
Boolean_t TackOnChar(char **SBase,
|
|
|
|
char CharToAdd)
|
|
|
|
{
|
|
|
|
REQUIRE(VALID_REF(SBase));
|
|
|
|
|
|
|
|
char S[2];
|
|
|
|
S[0] = CharToAdd;
|
|
|
|
S[1] = '\0';
|
|
|
|
|
|
|
|
return (TackOnString(SBase, S, FALSE, FALSE));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts all one character new line characters in the allocated string
|
|
|
|
* to a two character "\n" sequence.
|
|
|
|
*
|
|
|
|
* param String
|
|
|
|
* String to scan and convert if necessary. Note that the string will
|
|
|
|
* be reallocated if any new line characters are discovered.
|
|
|
|
*
|
|
|
|
* return
|
|
|
|
* TRUE if the request was successfull, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Okay for UTF-8
|
|
|
|
Boolean_t ReplaceNewlineWithBackslashN(char **String)
|
|
|
|
{
|
|
|
|
size_t I;
|
|
|
|
LgIndex_t NewlineCount;
|
|
|
|
size_t Length;
|
|
|
|
char *Replacement;
|
|
|
|
|
|
|
|
REQUIRE(VALID_REF(String));
|
|
|
|
REQUIRE(VALID_REF(*String));
|
|
|
|
|
|
|
|
/* count how many new line character are present */
|
|
|
|
NewlineCount = 0;
|
|
|
|
Length = strlen(*String);
|
|
|
|
for (I = 0; I < Length; I++)
|
|
|
|
if ((*String)[I] == '\n')
|
|
|
|
NewlineCount++;
|
|
|
|
|
|
|
|
if (NewlineCount != 0)
|
|
|
|
{
|
|
|
|
/* allocate a new string and convert */
|
|
|
|
Replacement = ALLOC_ARRAY(Length + NewlineCount + 1, char,
|
|
|
|
"replacement string");
|
|
|
|
if (Replacement != NULL)
|
|
|
|
{
|
|
|
|
size_t J;
|
|
|
|
for (I = J = 0; I < Length + 1; I++, J++)
|
|
|
|
{
|
|
|
|
if ((*String)[I] == '\n')
|
|
|
|
{
|
|
|
|
Replacement[J] = '\\';
|
|
|
|
J++;
|
|
|
|
Replacement[J] = 'n';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Replacement[J] = (*String)[I];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sanity check */
|
|
|
|
CHECK(I == Length + 1);
|
|
|
|
CHECK(J == Length + NewlineCount + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* release the old string and record the new one */
|
|
|
|
FREE_ARRAY(*String, "original string");
|
|
|
|
*String = Replacement;
|
|
|
|
}
|
|
|
|
|
|
|
|
ENSURE(*String == NULL || VALID_REF(*String));
|
|
|
|
return (*String != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
/* CORE SOURCE CODE REMOVED */
|
|
|
|
#if defined TECPLOTKERNEL
|
|
|
|
#if !defined NO_ASSERTS
|
|
|
|
#endif /* !NO_ASSERTS */
|
|
|
|
#endif /*TECPLOTKERNEL*/
|
|
|
|
#endif
|