1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-25 12:55:50 +03:00
occt/src/ExpToCasExe/ExpToCasExe.cxx
dpasukhi c36205a05e 0033378: Configuration - Moving ExpToCas into separate module
Moved ExpToCasExe and its DLL to new module - DETools
Created new module - DETools to keep tools to DE
Changed definition of main of ExpToCasExe to not const parameter
FlexLexer.h moved to general location into TKernel
2023-05-18 22:48:02 +01:00

396 lines
13 KiB
C++

// Created: Mon Nov 1 12:50:27 1999
// Author: Andrey BETENEV
// Copyright (c) 1999-2020 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <cstring>
#include <Express_Item.hxx>
#include <Express_Schema.hxx>
#include <Message.hxx>
#include <OSD_File.hxx>
#include <OSD_FileSystem.hxx>
#include <OSD_OpenFile.hxx>
#include <TCollection_HAsciiString.hxx>
#include "exptocas.tab.hxx"
//=======================================================================
// function : GetSchema
// purpose : interface to parser
//=======================================================================
Handle(Express_Schema) GetSchema (const char* theFileName)
{
std::ifstream aFileStream;
OSD_OpenStream(aFileStream, theFileName, std::ios_base::in | std::ios_base::binary);
exptocas::scanner aScanner(&aFileStream);
aScanner.yyrestart(&aFileStream);
// uncomment next string for debug of parser
//aScanner.set_debug(1);
exptocas::parser aParser(&aScanner);
aParser.parse();
return Express::Schema();
}
//=======================================================================
// function : LoadList
// purpose : Load list of (class name, package name) from the file
// Package names and optional mark flag are set to items in the schema
//=======================================================================
static Standard_Boolean LoadList (const char *theFileName,
const Handle(Express_Schema)& theSchema,
const Standard_Boolean theMark)
{
const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
std::shared_ptr<std::istream> aStreamPtr = aFileSystem->OpenIStream (theFileName, std::ios::in);
Standard_IStream& anIS = *aStreamPtr;
if (aStreamPtr == nullptr)
{
Message::SendFail() << "Error: cannot open " << theFileName;
return Standard_False;
}
Message::SendInfo() << "Loading " << theFileName << "...";
char aBuf[512];
Standard_Integer aLineNum = 0;
// a line entry in file has the next format:
// item_name package_name [shortname [check_flag(0 or 1) [fillshared_flag(0 or 1) [category]]]]
while (anIS.getline (aBuf, 512))
{
char* aCurPos = aBuf;
char* anItemName;
char* aPackageName;
char* aShortName;
char* aCheckFlag;
char* aFillSharedFlag;
char* aCategoryName;
Standard_Size aSepIdx = 0;
aLineNum += 1;
// -------------------------------------------------------------
// first word is an item name
// -------------------------------------------------------------
// skip any whitespace character in the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if first word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the name of the item
anItemName = aCurPos;
// shift the position
if (aCurPos[aSepIdx] == '\0')
{
aCurPos += aSepIdx;
}
else
{
aCurPos[aSepIdx] = '\0';
aCurPos += aSepIdx + 1;
}
Handle(Express_Item) anItem = theSchema->Item (anItemName, Standard_True);
// skip any class name not in schema
if (anItem.IsNull())
{
continue;
}
// -------------------------------------------------------------
// second word is a package name
// -------------------------------------------------------------
// skip any whitespace character in the rest of the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if second word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the name of the package
aPackageName = aCurPos;
// shift the position
if (aCurPos[aSepIdx] == '\0')
{
aCurPos += aSepIdx;
}
else
{
aCurPos[aSepIdx] = '\0';
aCurPos += aSepIdx + 1;
}
// make warning if there is another package for the item
if (anItem->IsPackageNameSet() && anItem->GetPackageName().IsDifferent (aPackageName))
{
Message::SendWarning() << "Warning: Package is redefined for item " << anItemName;
}
anItem->SetPackageName (aPackageName);
anItem->SetGenMode (theMark ? Express_Item::GM_GenByUser : Express_Item::GM_NoGen);
// -------------------------------------------------------------
// third word is an item short name (optional)
// -------------------------------------------------------------
// skip any whitespace character in the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if third word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the short name
aShortName = aCurPos;
// shift the position
if (aCurPos[aSepIdx] == '\0')
{
aCurPos += aSepIdx;
}
else
{
aCurPos[aSepIdx] = '\0';
aCurPos += aSepIdx + 1;
}
if (!std::isalpha (*aShortName))
{
Message::SendWarning() << "Warning: Not recognized a shortname at the line " << aLineNum;
continue;
}
// if short name "-" then just do not set it
if (*aShortName != '-')
{
Handle(TCollection_HAsciiString) anItemShortName = new TCollection_HAsciiString(aShortName);
if (anItemShortName->Length() > 0)
{
anItem->SetShortName (anItemShortName);
}
}
// -------------------------------------------------------------
// fourth word is an item check flag (optional)
// -------------------------------------------------------------
// skip any whitespace character in the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if fourth word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the check flag
aCheckFlag = aCurPos;
// shift the position
if (aCurPos[aSepIdx] == '\0')
{
aCurPos += aSepIdx;
}
else
{
aCurPos[aSepIdx] = '\0';
aCurPos += aSepIdx + 1;
}
if (!(*aCheckFlag == '0' || *aCheckFlag == '1'))
{
Message::SendWarning() << "Warning: Not recognized a check flag at the line " << aLineNum;
continue;
}
Standard_Boolean hasCheck = (*aCheckFlag == '0' ? Standard_False : Standard_True);
anItem->SetCheckFlag (hasCheck);
// -------------------------------------------------------------
// fifth word is an item fill share flag (optional)
// -------------------------------------------------------------
// skip any whitespace character in the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if fifth word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the fill share flag
aFillSharedFlag = aCurPos;
// shift the position
if (aCurPos[aSepIdx] == '\0')
{
aCurPos += aSepIdx;
}
else
{
aCurPos[aSepIdx] = '\0';
aCurPos += aSepIdx + 1;
}
if (!(*aFillSharedFlag == '0' || *aFillSharedFlag == '1'))
{
Message::SendWarning() << "Warning: Not recognized a fill shared flag at the line " << aLineNum;
continue;
}
Standard_Boolean hasFillShared = (*aFillSharedFlag == '0' ? Standard_False : Standard_True);
anItem->SetFillSharedFlag (hasFillShared);
// -------------------------------------------------------------
// sixth word is an item category name (optional)
// -------------------------------------------------------------
// skip any whitespace character in the line
while (*aCurPos && (aSepIdx = strcspn (aCurPos, " \t\r\n")) == 0)
{
aCurPos++;
}
// to next line if sixth word isn't found or comment started
if (*aCurPos == '\0' || *aCurPos == '#')
{
continue;
}
// get the category name
aCategoryName = aCurPos;
aCurPos[aSepIdx] = '\0';
if (!std::isalpha (*aCategoryName))
{
Message::SendWarning() << "Warning: Not recognized a category name at the line " << aLineNum;
continue;
}
// if category name "-" then just do not set it
if (*aCategoryName != '-')
{
Handle(TCollection_HAsciiString) anItemCategoryName = new TCollection_HAsciiString(aCategoryName);
if (anItemCategoryName->Length() > 0)
{
anItem->SetShortName (anItemCategoryName);
}
}
}
Message::SendInfo() << " Done";
return Standard_True;
}
//=======================================================================
// function : main
// purpose :
//=======================================================================
int main (int argc, char* argv[])
{
if (argc < 2)
{
Message::SendInfo() << "EXPRESS -> CASCADE/XSTEP classes generator 3.0\n"
"Use: ExpToCas <schema.exp> [<create.lst> [<packaging.lst> [start_index]]]\n"
"Where: \n"
"- schema.exp is a file with EXPRESS schema \n"
"- create.lst is a file with list of types to generate (all if none)\n"
" (or \"-\" for creating all entities in the schema)\n"
"- packaging.lst is a file with classes distribution per package\n"
" in the form of the list (one item per line) \"<TypeName> <Package>\"\n"
" If package not defined for some type, \"StepStep\" assumed\n"
"- start_index - a first number for auxiliary generated files with data\n"
" to copy into StepAP214_Protocol.cxx, RWStepAP214_GeneralModule.cxx and\n"
" RWStepAP214_ReadWriteModule.cxx";
return 0;
}
//=================================
// Step 1: parsing EXPRESS file
// open schema file
OSD_Path aPath (argv[1]);
OSD_File aFile (aPath);
if (!aFile.IsReadable())
{
Message::SendFail() << "Error: Cannot open " << argv[1];
return -1;
}
// parse
Message::SendInfo() << "Starting parsing " << argv[1];
Handle(Express_Schema) aSchema = GetSchema (argv[1]);
if (aSchema.IsNull())
{
Message::SendFail() << "Error: Parsing finished with no result";
return -1;
}
else
{
Message::SendInfo() << "Schema " << aSchema->Name()->ToCString() << " successfully parsed";
}
Message::SendInfo() << "Total " << aSchema->NbItems() << " items";
//=================================
// Step 2: Prepare data for creating classes
// load packaging information
if (argc > 3)
{
if (!LoadList (argv[3], aSchema, Standard_False))
{
return -1;
}
}
// load list of classes to generate
if (argc > 2)
{
if (argv[2][0] == '-')
{
// set mark for all items
for (Standard_Integer num = 1; num <= aSchema->NbItems(); num++)
{
aSchema->Item (num)->SetGenMode (Express_Item::GM_GenByUser);
}
}
else if (!LoadList (argv[2], aSchema, Standard_True))
{
return -1;
}
}
// get starting index
Standard_Integer anIndex = -1;
if (argc > 4)
{
char* aStopSymbol;
anIndex = (Standard_Integer) strtol (argv[4], &aStopSymbol, 10);
if (*aStopSymbol != '\0')
{
Message::SendFail() << "Error: invalid starting index: " << argv[4];
return -1;
}
}
//=================================
// Step 3: Iterate over new items and set the package name if need
const TCollection_AsciiString aUserName("user");
for (Standard_Integer aNum = 1; aNum <= aSchema->NbItems(); aNum++)
{
if (aSchema->Item (aNum)->GetGenMode() == Express_Item::GM_GenByUser)
{
aSchema->Item (aNum)->Use2(aUserName, Express_Item::GetUnknownPackageName());
}
}
//=================================
// Step 4: Iterate by items and generate classes
Standard_Boolean isDone = Standard_False;
Express_Item::SetIndex (anIndex);
do
{
isDone = Standard_False;
for (Standard_Integer aNum = 1; aNum <= aSchema->NbItems(); aNum++)
{
isDone = isDone || aSchema->Item (aNum)->Generate();
}
} while (isDone);
return 0;
}