mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
Fix first subset of warnings (about 100) - while(1) and similar constructs replaced by for(;;) - some uninitialized variables corrected Got rid of Warning C4189: local variable is initialised but not referenced Corrected mistakes after getting rid of C4189 compiler warning Corrected some mistakes that led to compiling errors Fixed test case because of improvement message - removed unnecessary TODO. Small fix: tabs have been replaced with whitespaces. Added TODO for Windows platform removed last TODO Corrected mistakes, returned some #ifdef DEB code, fixed test case . Restoring a few places which have been modified too much Small grammar fix Deleted unnecessary puts in bugs/end
368 lines
12 KiB
C++
Executable File
368 lines
12 KiB
C++
Executable File
// Created on: 2001-04-26
|
|
// Created by: OCC Team
|
|
// Copyright (c) 2001-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
|
|
#include <Message_MsgFile.hxx>
|
|
|
|
#include <TCollection_AsciiString.hxx>
|
|
#include <TCollection_ExtendedString.hxx>
|
|
#include <NCollection_DefineBaseCollection.hxx>
|
|
#include <NCollection_DefineDataMap.hxx>
|
|
#include <OSD_Environment.hxx>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
DEFINE_BASECOLLECTION(Message_CollectionOfExtendedString, TCollection_ExtendedString)
|
|
DEFINE_DATAMAP(Message_DataMapOfExtendedString,
|
|
Message_CollectionOfExtendedString,
|
|
TCollection_AsciiString,
|
|
TCollection_ExtendedString)
|
|
|
|
static Message_DataMapOfExtendedString& msgsDataMap ()
|
|
{
|
|
static Message_DataMapOfExtendedString aDataMap;
|
|
return aDataMap;
|
|
}
|
|
|
|
typedef enum
|
|
{
|
|
MsgFile_WaitingKeyword,
|
|
MsgFile_WaitingMessage,
|
|
MsgFile_WaitingMoreMessage,
|
|
MsgFile_Indefinite
|
|
} LoadingState;
|
|
|
|
//=======================================================================
|
|
//function : Message_MsgFile
|
|
//purpose : Load file from given directories
|
|
// theDirName may be represented as list: "/dirA/dirB /dirA/dirC"
|
|
//=======================================================================
|
|
|
|
Standard_Boolean Message_MsgFile::Load (const Standard_CString theDirName,
|
|
const Standard_CString theFileName)
|
|
{
|
|
if ( ! theDirName || ! theFileName ) return Standard_False;
|
|
|
|
Standard_Boolean ret = Standard_True;
|
|
TCollection_AsciiString aDirList (theDirName);
|
|
// Try to load from all consecutive directories in list
|
|
for (int i = 1;; i++)
|
|
{
|
|
TCollection_AsciiString aFileName = aDirList.Token (" \t\n", i);
|
|
if (aFileName.IsEmpty()) break;
|
|
#ifdef WNT
|
|
aFileName += '\\';
|
|
#else
|
|
aFileName += '/';
|
|
#endif
|
|
aFileName += theFileName;
|
|
if ( ! LoadFile (aFileName.ToCString()) )
|
|
ret = Standard_False;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : getString
|
|
//purpose : Takes a TCollection_ExtendedString from Ascii or Unicode
|
|
// Strings are left-trimmed; those beginning with '!' are omitted
|
|
//Called : from loadFile()
|
|
//=======================================================================
|
|
|
|
template <class _Char> static inline Standard_Boolean
|
|
getString (_Char *& thePtr,
|
|
TCollection_ExtendedString& theString,
|
|
Standard_Integer& theLeftSpaces)
|
|
{
|
|
_Char * anEndPtr = thePtr;
|
|
_Char * aPtr;
|
|
Standard_Integer aLeftSpaces;
|
|
|
|
do
|
|
{
|
|
// Skip whitespaces in the beginning of the string
|
|
aPtr = anEndPtr;
|
|
aLeftSpaces = 0;
|
|
for (;;)
|
|
{
|
|
_Char aChar = * aPtr;
|
|
if (aChar == ' ') aLeftSpaces++;
|
|
else if (aChar == '\t') aLeftSpaces += 8;
|
|
else if (aChar == '\r' || * aPtr == '\n') aLeftSpaces = 0;
|
|
else break;
|
|
aPtr++;
|
|
}
|
|
|
|
// Find the end of the string
|
|
for (anEndPtr = aPtr; * anEndPtr; anEndPtr++)
|
|
if (anEndPtr[0] == '\n')
|
|
{
|
|
if (anEndPtr[-1] == '\r') anEndPtr--;
|
|
break;
|
|
}
|
|
|
|
} while (aPtr[0] == '!');
|
|
|
|
// form the result
|
|
if (aPtr == anEndPtr) return Standard_False;
|
|
thePtr = anEndPtr;
|
|
if (*thePtr)
|
|
*thePtr++ = '\0';
|
|
theString = TCollection_ExtendedString (aPtr);
|
|
theLeftSpaces = aLeftSpaces;
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : loadFile
|
|
//purpose : Static function, fills the DataMap of Messages from Ascii or Unicode
|
|
//Called : from LoadFile()
|
|
//=======================================================================
|
|
|
|
template <class _Char> static inline Standard_Boolean loadFile (_Char * theBuffer)
|
|
{
|
|
TCollection_AsciiString aKeyword;
|
|
TCollection_ExtendedString aMessage, aString;
|
|
LoadingState aState = MsgFile_WaitingKeyword;
|
|
_Char * sCurrentString = theBuffer;
|
|
Standard_Integer aLeftSpaces=0, aFirstLeftSpaces = 0;
|
|
|
|
// Take strings one-by-one; comments already screened
|
|
while (::getString (sCurrentString, aString, aLeftSpaces))
|
|
{
|
|
Standard_Boolean isKeyword = (aString.Value(1) == '.');
|
|
switch (aState)
|
|
{
|
|
case MsgFile_WaitingMoreMessage:
|
|
if (isKeyword)
|
|
Message_MsgFile::AddMsg (aKeyword, aMessage); // terminate the previous one
|
|
// Pass from here to 'case MsgFile_WaitingKeyword'
|
|
else
|
|
{
|
|
// Add another line to the message already in the buffer 'aMessage'
|
|
aMessage += '\n';
|
|
aLeftSpaces -= aFirstLeftSpaces;
|
|
if (aLeftSpaces > 0) aMessage += TCollection_ExtendedString (aLeftSpaces, ' ');
|
|
aMessage += aString;
|
|
break;
|
|
}
|
|
case MsgFile_WaitingMessage:
|
|
if (isKeyword == Standard_False)
|
|
{
|
|
aMessage = aString;
|
|
aFirstLeftSpaces = aLeftSpaces; // remember the starting position
|
|
aState = MsgFile_WaitingMoreMessage;
|
|
break;
|
|
}
|
|
// Pass from here to 'case MsgFile_WaitingKeyword'
|
|
case MsgFile_WaitingKeyword:
|
|
if (isKeyword)
|
|
{
|
|
// remove the first dot character and all subsequent spaces + right-trim
|
|
aKeyword = TCollection_AsciiString (aString.Split(1));
|
|
aKeyword.LeftAdjust();
|
|
aKeyword.RightAdjust();
|
|
aState = MsgFile_WaitingMessage;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
// Process the last string still remaining in the buffer
|
|
if (aState == MsgFile_WaitingMoreMessage)
|
|
Message_MsgFile::AddMsg (aKeyword, aMessage);
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetFileSize
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Integer GetFileSize (FILE *theFile)
|
|
{
|
|
if ( !theFile ) return -1;
|
|
|
|
// get real file size
|
|
long nRealFileSize = 0;
|
|
if ( fseek(theFile, 0, SEEK_END) != 0 ) return -1;
|
|
nRealFileSize = ftell(theFile);
|
|
if ( fseek(theFile, 0, SEEK_SET) != 0 ) return -1;
|
|
|
|
return (Standard_Integer) nRealFileSize;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : LoadFile
|
|
//purpose : Load the list of messages from a file
|
|
//=======================================================================
|
|
|
|
Standard_Boolean Message_MsgFile::LoadFile (const Standard_CString theFileName)
|
|
{
|
|
if (theFileName == NULL || * theFileName == '\0') return Standard_False;
|
|
|
|
// Open the file
|
|
FILE *anMsgFile = fopen (theFileName, "rb");
|
|
if (!anMsgFile) return Standard_False;
|
|
|
|
// Read the file into memory
|
|
class Buffer
|
|
{
|
|
// self-destructing buffer
|
|
char *myBuf;
|
|
public:
|
|
Buffer (Standard_Integer theSize) : myBuf(new char [theSize]) {}
|
|
~Buffer () { delete [] myBuf; }
|
|
operator char* () const { return myBuf; }
|
|
char& operator [] (Standard_Integer theInd) { return myBuf[theInd]; }
|
|
};
|
|
Standard_Integer aFileSize = GetFileSize (anMsgFile);
|
|
if (aFileSize <= 0)
|
|
{
|
|
fclose (anMsgFile);
|
|
return Standard_False;
|
|
}
|
|
Buffer anMsgBuffer (aFileSize + 2);
|
|
Standard_Integer nbRead =
|
|
(Standard_Integer) fread (anMsgBuffer, 1, aFileSize, anMsgFile);
|
|
fclose (anMsgFile);
|
|
if (nbRead != aFileSize)
|
|
return Standard_False;
|
|
anMsgBuffer[aFileSize] = 0;
|
|
anMsgBuffer[aFileSize+1] = 0;
|
|
|
|
// Read the messages in the file and append them to the global DataMap
|
|
Standard_Boolean isLittleEndian = (anMsgBuffer[0] == '\xff' && anMsgBuffer[1] == '\xfe');
|
|
Standard_Boolean isBigEndian = (anMsgBuffer[0] == '\xfe' && anMsgBuffer[1] == '\xff');
|
|
if ( isLittleEndian || isBigEndian )
|
|
{
|
|
Standard_ExtCharacter * aUnicodeBuffer =
|
|
(Standard_ExtCharacter *) &anMsgBuffer[2];
|
|
// Convert Unicode representation to order adopted on current platform
|
|
#if defined(__sparc) && defined(__sun)
|
|
if ( isLittleEndian )
|
|
#else
|
|
if ( isBigEndian )
|
|
#endif
|
|
{
|
|
// Reverse the bytes throughout the buffer
|
|
for (Standard_ExtCharacter * aPtr = aUnicodeBuffer;
|
|
aPtr < (Standard_ExtCharacter *) &anMsgBuffer[aFileSize]; aPtr++)
|
|
{
|
|
unsigned short aWord = *aPtr;
|
|
*aPtr = (aWord & 0x00ff) << 8 | (aWord & 0xff00) >> 8;
|
|
}
|
|
}
|
|
return ::loadFile (aUnicodeBuffer);
|
|
}
|
|
else
|
|
return ::loadFile ((char*) anMsgBuffer);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : LoadFromEnv
|
|
//purpose :
|
|
//=======================================================================
|
|
void Message_MsgFile::LoadFromEnv
|
|
(const Standard_CString envname,
|
|
const Standard_CString filename,
|
|
const Standard_CString ext)
|
|
{
|
|
Standard_CString extname = ext;
|
|
TCollection_AsciiString extstr;
|
|
if (!extname || extname[0] == '\0') {
|
|
OSD_Environment extenv("CSF_LANGUAGE");
|
|
extstr = extenv.Value();
|
|
extname = extstr.ToCString();
|
|
}
|
|
if (!extname || extname[0] == '\0') extname = "us";
|
|
|
|
TCollection_AsciiString filestr(filename);
|
|
if (envname && envname[0] != '\0') {
|
|
OSD_Environment envenv(envname);
|
|
TCollection_AsciiString envstr = envenv.Value();
|
|
if (envstr.Length() > 0) {
|
|
if (envstr.Value(envstr.Length()) != '/') filestr.Insert (1,'/');
|
|
filestr.Insert (1,envstr.ToCString());
|
|
}
|
|
}
|
|
if (extname[0] != '.') filestr.AssignCat ('.');
|
|
filestr.AssignCat (extname);
|
|
|
|
Message_MsgFile::LoadFile (filestr.ToCString());
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AddMsg
|
|
//purpose : Add one message to the global table. Fails if the same keyword
|
|
// already exists in the table
|
|
//=======================================================================
|
|
|
|
Standard_Boolean Message_MsgFile::AddMsg (const TCollection_AsciiString& theKeyword,
|
|
const TCollection_ExtendedString& theMessage)
|
|
{
|
|
Message_DataMapOfExtendedString& aDataMap = ::msgsDataMap();
|
|
// if (aDataMap.IsBound (theKeyword))
|
|
// return Standard_False;
|
|
aDataMap.Bind (theKeyword, theMessage);
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : getMsg
|
|
//purpose : retrieve the message previously defined for the given keyword
|
|
//=======================================================================
|
|
|
|
const TCollection_ExtendedString &Message_MsgFile::Msg (const Standard_CString theKeyword)
|
|
{
|
|
TCollection_AsciiString aKey((char*)theKeyword);
|
|
return Msg (aKey);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : getMsg
|
|
//purpose : retrieve the message previously defined for the given keyword
|
|
//=======================================================================
|
|
|
|
const TCollection_ExtendedString &Message_MsgFile::Msg (const TCollection_AsciiString& theKeyword)
|
|
{
|
|
// find message in the map
|
|
Message_DataMapOfExtendedString& aDataMap = ::msgsDataMap();
|
|
if (aDataMap.IsBound (theKeyword))
|
|
return aDataMap.Find (theKeyword);
|
|
|
|
// if not found, generate error message
|
|
// to minimize risk of data races when running concurrently, set the static variables
|
|
// only if they are empty; this gives a possibility to enforce calling this method
|
|
// upfront to initialize these variables and only read access them afterwards. However
|
|
// theKeyword is no longer appended. aDefPrefix remained unchanged to not break some
|
|
// logs which might expect the previous value
|
|
static const TCollection_ExtendedString aDefPrefix ("Unknown message invoked with the keyword");
|
|
static const TCollection_AsciiString aPrefixCode ("Message_Msg_BadKeyword");
|
|
static TCollection_ExtendedString aFailureMessage;
|
|
if (aFailureMessage.Length() == 0) {
|
|
if (aDataMap.IsBound (aPrefixCode))
|
|
aFailureMessage = aDataMap.Find (aPrefixCode);
|
|
else
|
|
aFailureMessage = aDefPrefix;
|
|
}
|
|
return aFailureMessage;
|
|
}
|