Important update:
- DataTree->GetStr return Member->Value or NULL if not found - Rename DeviceCore EDataType to EMBDataType, avoid conflict with JSONpaser - Add DataTree to FunctionCore with LoadConfig() method - Change ProcessName to char * (from char[]) - JSONparse: - Rename RootPath to BasePath on all methods to reduce confusion - Allow FilePath to be NULL, add '/' if not present - Fixed Parsing sequence in ParseObject & ParseArray
This commit is contained in:
@@ -534,10 +534,10 @@ const char * CDataTree::GetStr( TDataMember * BaseMember, const char * Path, con
|
|||||||
}
|
}
|
||||||
else if (Member && Create && (Member->Type == jtNull)) {
|
else if (Member && Create && (Member->Type == jtNull)) {
|
||||||
SetValue( Member, jtString, Default );
|
SetValue( Member, jtString, Default );
|
||||||
return Default;
|
return Member->Value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Default;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -554,11 +554,11 @@ const char * CDataTree::GetStr( TDataMember * BaseMember, const char * Path, int
|
|||||||
else if (Member && Create && (Member->Type == jtNull)) {
|
else if (Member && Create && (Member->Type == jtNull)) {
|
||||||
SetValue( Member, jtString, Default );
|
SetValue( Member, jtString, Default );
|
||||||
Len = Member->Len;
|
Len = Member->Len;
|
||||||
return Default;
|
return Member->Value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Len = strlen( Default );
|
Len = 0;
|
||||||
return Default;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * ParamName, EDataType DataType, int ParamLen )
|
TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * ParamName, EMBDataType DataType, int ParamLen )
|
||||||
{
|
{
|
||||||
// Get register or end of list
|
// Get register or end of list
|
||||||
TDeviceParam ** Param = &Device->FirstParam;
|
TDeviceParam ** Param = &Device->FirstParam;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Enumerated types
|
// Enumerated types
|
||||||
typedef enum { dtUnsigned16 = 0, dtSigned16 = 1, dtUnsigned32 = 2, dtSigned32 = 3, dtFloat32 = 4, dtString = 5 } EDataType;
|
typedef enum { dtUnsigned16 = 0, dtSigned16 = 1, dtUnsigned32 = 2, dtSigned32 = 3, dtFloat32 = 4, dtString = 5 } EMBDataType;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const char DataTypeName[][20] = { "Unsigned16", "Signed16", "Unsigned32", "Signed32", "Float32", "String" };
|
const char DataTypeName[][20] = { "Unsigned16", "Signed16", "Unsigned32", "Signed32", "Float32", "String" };
|
||||||
@@ -41,7 +41,7 @@ struct SDevice {
|
|||||||
// Data parameters of devices
|
// Data parameters of devices
|
||||||
struct SDeviceParam {
|
struct SDeviceParam {
|
||||||
char * Name;
|
char * Name;
|
||||||
EDataType DataType;
|
EMBDataType DataType;
|
||||||
|
|
||||||
bool Scan;
|
bool Scan;
|
||||||
TChannel * EventChannel;
|
TChannel * EventChannel;
|
||||||
@@ -182,7 +182,7 @@ public:
|
|||||||
bool DestroyDevice( const char * DeviceName );
|
bool DestroyDevice( const char * DeviceName );
|
||||||
|
|
||||||
// Manage Params
|
// Manage Params
|
||||||
TDeviceParam * AddDeviceParam( TDevice * Device, const char * ParamName, EDataType DataType, int ParamLen = 1 );
|
TDeviceParam * AddDeviceParam( TDevice * Device, const char * ParamName, EMBDataType DataType, int ParamLen = 1 );
|
||||||
bool DestroyDeviceParam( TDevice * Device, const char * ParamName );
|
bool DestroyDeviceParam( TDevice * Device, const char * ParamName );
|
||||||
|
|
||||||
// Update/Init Param values
|
// Update/Init Param values
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
extern char ProcessName[];
|
extern char * ProcessName;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -33,8 +33,12 @@ CFunctionCore::CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebug
|
|||||||
Name = NULL;
|
Name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data Tree
|
||||||
|
DataTree = NULL;
|
||||||
|
BaseMember = NULL;
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
FirstChannel = NULL;
|
FirstChannel = NULL;
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
Log = pLog;
|
Log = pLog;
|
||||||
@@ -92,7 +96,17 @@ CFunctionCore::~CFunctionCore()
|
|||||||
if (Name) {
|
if (Name) {
|
||||||
free( Name );
|
free( Name );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CFunctionCore::LoadConfig( CDataTree * pDataTree, const char * pBasePath )
|
||||||
|
{
|
||||||
|
if (!(DataTree = pDataTree))
|
||||||
|
return false;
|
||||||
|
if (!(BaseMember = DataTree->GetMember( NULL, pBasePath, true )))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
// redA Libraries
|
// redA Libraries
|
||||||
#include "LogCore.h"
|
#include "LogCore.h"
|
||||||
#include "BufferCore.h"
|
#include "BufferCore.h"
|
||||||
|
#include "DataTreeCore.h"
|
||||||
|
|
||||||
// Standard C/C++ Libraries
|
// Standard C/C++ Libraries
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -52,6 +53,10 @@ protected:
|
|||||||
// Function Definition
|
// Function Definition
|
||||||
char * Name;
|
char * Name;
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
CDataTree * DataTree;
|
||||||
|
TDataMember * BaseMember;
|
||||||
|
|
||||||
// Channels
|
// Channels
|
||||||
TChannel * FirstChannel;
|
TChannel * FirstChannel;
|
||||||
|
|
||||||
@@ -77,6 +82,8 @@ public:
|
|||||||
CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
|
CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||||
virtual ~CFunctionCore();
|
virtual ~CFunctionCore();
|
||||||
|
|
||||||
|
virtual bool LoadConfig( CDataTree * DataTree, const char * BasePath );
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
inline const char * GetName() { return Name; };
|
inline const char * GetName() { return Name; };
|
||||||
|
|
||||||
|
|||||||
@@ -54,16 +54,16 @@ CJSONparse::~CJSONparse()
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::WriteToScreen( const char * RootPath, const int Indent )
|
bool CJSONparse::WriteToScreen( const char * BasePath, const int Indent )
|
||||||
{
|
{
|
||||||
// Print to screen
|
// Print to screen
|
||||||
WriteToHandle( RootPath, 1, Indent );
|
WriteToHandle( BasePath, 1, Indent );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::WriteToFile( const char * RootPath, const char * Path, const char * FileName, const int Indent )
|
bool CJSONparse::WriteToFile( const char * BasePath, const char * Path, const char * FileName, const int Indent )
|
||||||
{
|
{
|
||||||
char FilePath[250] = "";
|
char FilePath[250] = "";
|
||||||
|
|
||||||
@@ -72,11 +72,11 @@ bool CJSONparse::WriteToFile( const char * RootPath, const char * Path, const ch
|
|||||||
strcat( FilePath, FileName );
|
strcat( FilePath, FileName );
|
||||||
|
|
||||||
// Read file
|
// Read file
|
||||||
return WriteToFile( RootPath, FilePath, Indent );
|
return WriteToFile( BasePath, FilePath, Indent );
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::WriteToFile( const char * RootPath, const char * FilePath, const int Indent )
|
bool CJSONparse::WriteToFile( const char * BasePath, const char * FilePath, const int Indent )
|
||||||
{
|
{
|
||||||
int Handle = -1;
|
int Handle = -1;
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ bool CJSONparse::WriteToFile( const char * RootPath, const char * FilePath, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save to file
|
// Save to file
|
||||||
WriteToHandle( RootPath, Handle, Indent );
|
WriteToHandle( BasePath, Handle, Indent );
|
||||||
|
|
||||||
// Close file
|
// Close file
|
||||||
close( Handle );
|
close( Handle );
|
||||||
@@ -106,9 +106,9 @@ bool CJSONparse::WriteToFile( const char * RootPath, const char * FilePath, cons
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::WriteToHandle( const char * RootPath, const int Handle, const int Indent )
|
bool CJSONparse::WriteToHandle( const char * BasePath, const int Handle, const int Indent )
|
||||||
{
|
{
|
||||||
TDataMember * RootObject;
|
TDataMember * BaseMember;
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
if (!DataTree) {
|
if (!DataTree) {
|
||||||
@@ -124,17 +124,17 @@ bool CJSONparse::WriteToHandle( const char * RootPath, const int Handle, const i
|
|||||||
OutputHandle = Handle;
|
OutputHandle = Handle;
|
||||||
|
|
||||||
// Get Root object
|
// Get Root object
|
||||||
if (!RootPath || !*RootPath) {
|
if (!BasePath || !*BasePath) {
|
||||||
RootObject = DataTree->GetRootMember();
|
BaseMember = DataTree->GetRootMember();
|
||||||
}
|
}
|
||||||
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
|
else if (!(BaseMember = DataTree->GetMember( NULL, BasePath ))) {
|
||||||
Error = true;
|
Error = true;
|
||||||
sprintf( ErrorText, "Invalid root object path" );
|
sprintf( ErrorText, "Invalid root object path" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print to file
|
// Print to file
|
||||||
PrintObject( RootObject, Indent );
|
PrintObject( BaseMember, Indent );
|
||||||
write( OutputHandle, "\n", 1 );
|
write( OutputHandle, "\n", 1 );
|
||||||
|
|
||||||
OutputHandle = -1;
|
OutputHandle = -1;
|
||||||
@@ -142,20 +142,34 @@ bool CJSONparse::WriteToHandle( const char * RootPath, const int Handle, const i
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::ReadFromFile( const char * RootPath, const char * Path, const char * FileName )
|
bool CJSONparse::ReadFromFile( const char * BasePath, const char * Path, const char * FileName )
|
||||||
{
|
{
|
||||||
char FilePath[250] = "";
|
char FilePath[250] = "";
|
||||||
|
int PathLen = 0;
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
if (!FileName) {
|
||||||
|
Error = true;
|
||||||
|
sprintf( ErrorText, "No File name specified" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Build file name
|
// Build file name
|
||||||
strcpy( FilePath, Path );
|
if (Path && *Path) {
|
||||||
strcat( FilePath, FileName );
|
strcpy( FilePath, Path );
|
||||||
|
PathLen = strlen( FilePath );
|
||||||
|
if (FilePath[PathLen] != '/') {
|
||||||
|
FilePath[PathLen++] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy( &FilePath[PathLen], FileName );
|
||||||
|
|
||||||
// Read file
|
// Read file
|
||||||
return ReadFromFile( RootPath, FilePath );
|
return ReadFromFile( BasePath, FilePath );
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::ReadFromFile( const char * RootPath, const char * FilePath )
|
bool CJSONparse::ReadFromFile( const char * BasePath, const char * FilePath )
|
||||||
{
|
{
|
||||||
int Handle = -1;
|
int Handle = -1;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -183,7 +197,7 @@ bool CJSONparse::ReadFromFile( const char * RootPath, const char * FilePath )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Continuously refill buffer while loading
|
// Continuously refill buffer while loading
|
||||||
result = ReadFromHandle( RootPath, Handle, true );
|
result = ReadFromHandle( BasePath, Handle, true );
|
||||||
|
|
||||||
// Close File
|
// Close File
|
||||||
close( Handle );
|
close( Handle );
|
||||||
@@ -191,7 +205,7 @@ bool CJSONparse::ReadFromFile( const char * RootPath, const char * FilePath )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::ReadFromHandle( const char * RootPath, int Handle, bool pRefillBuffer )
|
bool CJSONparse::ReadFromHandle( const char * BasePath, int Handle, bool pRefillBuffer )
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
@@ -217,7 +231,7 @@ bool CJSONparse::ReadFromHandle( const char * RootPath, int Handle, bool pRefill
|
|||||||
|
|
||||||
// Continuously refill buffer while loading
|
// Continuously refill buffer while loading
|
||||||
RefillBuffer = pRefillBuffer;
|
RefillBuffer = pRefillBuffer;
|
||||||
result = ReadFromBuffer( RootPath );
|
result = ReadFromBuffer( BasePath );
|
||||||
RefillBuffer = false;
|
RefillBuffer = false;
|
||||||
|
|
||||||
// Destroy buffer
|
// Destroy buffer
|
||||||
@@ -228,9 +242,9 @@ bool CJSONparse::ReadFromHandle( const char * RootPath, int Handle, bool pRefill
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::ReadFromBuffer( const char * RootPath )
|
bool CJSONparse::ReadFromBuffer( const char * BasePath )
|
||||||
{
|
{
|
||||||
TDataMember * RootObject = NULL;
|
TDataMember * BaseMember = NULL;
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
if (!DataTree || !Buffer) {
|
if (!DataTree || !Buffer) {
|
||||||
@@ -241,17 +255,17 @@ bool CJSONparse::ReadFromBuffer( const char * RootPath )
|
|||||||
Error = false;
|
Error = false;
|
||||||
|
|
||||||
// Get/Create Root object
|
// Get/Create Root object
|
||||||
if (!RootPath || !*RootPath) {
|
if (!BasePath || !*BasePath) {
|
||||||
RootObject = DataTree->GetRootMember();
|
BaseMember = DataTree->GetRootMember();
|
||||||
}
|
}
|
||||||
else if (!(RootObject = DataTree->GetMember( NULL, RootPath, true ))) {
|
else if (!(BaseMember = DataTree->GetMember( NULL, BasePath, true ))) {
|
||||||
Error = true;
|
Error = true;
|
||||||
sprintf( ErrorText, "Invalid root object path" );
|
sprintf( ErrorText, "Invalid root object path" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete existing object contents
|
// Delete existing object contents
|
||||||
DataTree->Delete( RootObject, NULL );
|
DataTree->Delete( BaseMember, NULL );
|
||||||
|
|
||||||
// Position Counters
|
// Position Counters
|
||||||
LineNo = 1;
|
LineNo = 1;
|
||||||
@@ -259,7 +273,7 @@ bool CJSONparse::ReadFromBuffer( const char * RootPath )
|
|||||||
|
|
||||||
// Parse Root Object
|
// Parse Root Object
|
||||||
SkipWhiteSpace();
|
SkipWhiteSpace();
|
||||||
if (!ParseObject( RootObject )) {
|
if (!ParseObject( BaseMember )) {
|
||||||
if (!Error) {
|
if (!Error) {
|
||||||
Error = true;
|
Error = true;
|
||||||
CharNo += BufPos-Mark;
|
CharNo += BufPos-Mark;
|
||||||
@@ -427,14 +441,14 @@ bool CJSONparse::ParseString( char ** Value, int &Len )
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Error = true;
|
Error = true;
|
||||||
CharNo += BufPos-Mark+1;
|
CharNo += BufPos-Mark;
|
||||||
sprintf( ErrorText, "Invalid escape sequence on line %d:%d", LineNo, CharNo );
|
sprintf( ErrorText, "Invalid escape sequence on line %d:%d", LineNo, CharNo );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Error = true;
|
Error = true;
|
||||||
CharNo += BufPos-Mark+1;
|
CharNo += BufPos-Mark;
|
||||||
sprintf( ErrorText, "Un-escaped special character in string on line %d:%d", LineNo, CharNo );
|
sprintf( ErrorText, "Un-escaped special character in string on line %d:%d", LineNo, CharNo );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -538,14 +552,8 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
|||||||
|
|
||||||
// Get Value
|
// Get Value
|
||||||
SkipWhiteSpace();
|
SkipWhiteSpace();
|
||||||
if (!ParseObject( Member ) &&
|
if (!ParseObject( Member ) && !Error && !ParseArray( Member ) && !Error && !ParseString( Member ) && !Error && !ParsePrimitive( Member ) ) {}
|
||||||
!Error &&
|
if (Error) {
|
||||||
!ParseArray( Member ) &&
|
|
||||||
!Error &&
|
|
||||||
!ParseString( Member ) &&
|
|
||||||
!Error &&
|
|
||||||
!ParsePrimitive( Member ))
|
|
||||||
{
|
|
||||||
// Destroy member
|
// Destroy member
|
||||||
DataTree->Delete( Object, MemberName );
|
DataTree->Delete( Object, MemberName );
|
||||||
return false;
|
return false;
|
||||||
@@ -602,14 +610,8 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
|||||||
|
|
||||||
// Get Value
|
// Get Value
|
||||||
SkipWhiteSpace();
|
SkipWhiteSpace();
|
||||||
if (!ParseObject( Member ) &&
|
if (!ParseObject( Member ) && !Error && !ParseArray( Member ) && !Error && !ParseString( Member ) && !Error && !ParsePrimitive( Member ) ) {}
|
||||||
!Error &&
|
if (Error) {
|
||||||
!ParseArray( Member ) &&
|
|
||||||
!Error &&
|
|
||||||
!ParseString( Member ) &&
|
|
||||||
!Error &&
|
|
||||||
!ParsePrimitive( Member ))
|
|
||||||
{
|
|
||||||
DataTree->DestroyMember( &Member );
|
DataTree->DestroyMember( &Member );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,18 +66,18 @@ public:
|
|||||||
bool CreateBuffer( int pBufLen );
|
bool CreateBuffer( int pBufLen );
|
||||||
bool FillBuffer();
|
bool FillBuffer();
|
||||||
void FreeBuffer();
|
void FreeBuffer();
|
||||||
bool ReadFromBuffer( const char * RootPath );
|
bool ReadFromBuffer( const char * BasePath );
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
bool ReadFromHandle( const char * RootPath, const int Handle, bool pRefillBuffer );
|
bool ReadFromHandle( const char * BasePath, const int Handle, bool pRefillBuffer );
|
||||||
bool ReadFromFile( const char * RootPath, const char * Path, const char * FileName );
|
bool ReadFromFile( const char * BasePath, const char * Path, const char * FileName );
|
||||||
bool ReadFromFile( const char * RootPath, const char * FilePath );
|
bool ReadFromFile( const char * BasePath, const char * FilePath );
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
bool WriteToHandle( const char * RootPath, const int Handle, const int Indent = 2 );
|
bool WriteToHandle( const char * BasePath, const int Handle, const int Indent = 2 );
|
||||||
bool WriteToScreen( const char * RootPath, const int Indent = 2 );
|
bool WriteToScreen( const char * BasePath, const int Indent = 2 );
|
||||||
bool WriteToFile( const char * RootPath, const char * Path, const char * FileName, const int Indent = 2 );
|
bool WriteToFile( const char * BasePath, const char * Path, const char * FileName, const int Indent = 2 );
|
||||||
bool WriteToFile( const char * RootPath, const char * FilePath, const int Indent = 2 );
|
bool WriteToFile( const char * BasePath, const char * FilePath, const int Indent = 2 );
|
||||||
|
|
||||||
const char * GetError() { return ((Error)? ErrorText : "Success"); };
|
const char * GetError() { return ((Error)? ErrorText : "Success"); };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
extern char ProcessName[];
|
extern char * ProcessName;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user