mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
Don't use svn command line tool to get revision number
XML code stolen from the xmlbuildsystem branch, we need to merge this when merging the xmlbuildsystem back into trunk svn path=/trunk/; revision=13656
This commit is contained in:
parent
915fb7c58c
commit
5de6577d1f
10 changed files with 3222 additions and 38 deletions
|
@ -5,7 +5,6 @@ include $(PATH_TO_TOP)/rules.mak
|
|||
CFLAGS += -Wall -Werror
|
||||
|
||||
TOOLS = \
|
||||
buildno$(EXE_POSTFIX) \
|
||||
regtests$(EXE_POSTFIX) \
|
||||
rcopy$(EXE_POSTFIX) \
|
||||
rdel$(EXE_POSTFIX) \
|
||||
|
@ -20,11 +19,7 @@ TOOLS = \
|
|||
CLEAN_FILES = $(TOOLS)
|
||||
|
||||
all: $(TOOLS) zlib_target wmc_target cabman_target cdmake_target mkhive_target rgenstat_target \
|
||||
wine2ros_target pipetools_target winebuild_target bin2res_target wrc_target
|
||||
|
||||
buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h
|
||||
@$(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c
|
||||
@$(EXE_PREFIX)buildno$(EXE_POSTFIX)
|
||||
wine2ros_target pipetools_target winebuild_target bin2res_target wrc_target buildno_target
|
||||
|
||||
regtests$(EXE_POSTFIX): regtests.c
|
||||
@$(HOST_CC) $(CFLAGS) -o regtests$(EXE_POSTFIX) regtests.c
|
||||
|
@ -133,11 +128,15 @@ bin2res_target:
|
|||
wrc_target:
|
||||
$(MAKE) --silent -C wrc wrc$(EXE_POSTFIX)
|
||||
|
||||
.PHONY: wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target
|
||||
buildno_target:
|
||||
$(MAKE) --silent -C buildno buildno$(EXE_POSTFIX)
|
||||
|
||||
.PHONY: wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target buildno_target
|
||||
|
||||
|
||||
ifeq ($(HOST),mingw32-linux)
|
||||
clean:
|
||||
$(MAKE) --silent -C buildno clean
|
||||
$(MAKE) --silent -C wrc clean
|
||||
$(MAKE) --silent -C cabman clean
|
||||
$(MAKE) --silent -C cdmake clean
|
||||
|
@ -148,12 +147,12 @@ clean:
|
|||
$(MAKE) --silent -C winebuild clean
|
||||
$(MAKE) --silent -C bin2res clean
|
||||
$(MAKE) --silent -C ../lib/zlib -f Makefile.host clean
|
||||
@rm ../include/reactos/buildno.h
|
||||
@rm mkconfig
|
||||
@rm $(TOOLS)
|
||||
endif
|
||||
ifeq ($(HOST),mingw32-windows)
|
||||
clean:
|
||||
$(MAKE) --silent -C buildno clean
|
||||
$(MAKE) --silent -C wrc clean
|
||||
$(MAKE) --silent -C cabman clean
|
||||
$(MAKE) --silent -C cdmake clean
|
||||
|
@ -165,7 +164,6 @@ clean:
|
|||
$(MAKE) --silent -C winebuild clean
|
||||
$(MAKE) --silent -C bin2res clean
|
||||
$(MAKE) --silent -C ../lib/zlib -f Makefile.host clean
|
||||
-@del ..\include\reactos\buildno.h
|
||||
-@del *$(EXE_POSTFIX)
|
||||
endif
|
||||
|
||||
|
|
42
reactos/tools/buildno/Makefile
Normal file
42
reactos/tools/buildno/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
|||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET = buildno$(EXE_POSTFIX)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
OBJECTS = buildno.o XML.o exception.o ssprintf.o
|
||||
|
||||
CLEAN_FILES = *.o buildno$(EXE_POSTFIX)
|
||||
|
||||
HOST_CXXFLAGS = -I$(PATH_TO_TOP)/include/reactos -g -Wall -Werror
|
||||
|
||||
buildno.o: buildno.cpp $(PATH_TO_TOP)/include/reactos/version.h
|
||||
$(HOST_CXX) $(HOST_CXXFLAGS) -o buildno.o -c buildno.cpp
|
||||
|
||||
XML.o: XML.cpp
|
||||
$(HOST_CXX) $(HOST_CXXFLAGS) -o XML.o -c XML.cpp
|
||||
|
||||
exception.o: exception.cpp
|
||||
$(HOST_CXX) $(HOST_CXXFLAGS) -o exception.o -c exception.cpp
|
||||
|
||||
ssprintf.o: ssprintf.cpp
|
||||
$(HOST_CXX) $(HOST_CXXFLAGS) -o ssprintf.o -c ssprintf.cpp
|
||||
|
||||
buildno$(EXE_POSTFIX): $(OBJECTS)
|
||||
$(HOST_CXX) -g $(OBJECTS) -o $(TARGET)
|
||||
@$(EXE_PREFIX)buildno$(EXE_POSTFIX)
|
||||
|
||||
ifeq ($(HOST),mingw32-linux)
|
||||
clean:
|
||||
-rm -f *.o $(TARGET)
|
||||
-rm $(PATH_TO_TOP)/include/reactos/buildno.h
|
||||
endif
|
||||
ifneq ($(HOST),mingw32-linux)
|
||||
clean:
|
||||
-del *.o $(TARGET)
|
||||
-del ..\..\include\reactos\buildno.h
|
||||
endif
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
727
reactos/tools/buildno/XML.cpp
Normal file
727
reactos/tools/buildno/XML.cpp
Normal file
|
@ -0,0 +1,727 @@
|
|||
// XML.cpp
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAX_PATH _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# define MAX_PATH PATH_MAX
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#include "XML.h"
|
||||
#include "exception.h"
|
||||
#include "ssprintf.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
#ifdef WIN32
|
||||
#define getcwd _getcwd
|
||||
#endif//WIN32
|
||||
|
||||
static const char* WS = " \t\r\n";
|
||||
static const char* WSEQ = " =\t\r\n";
|
||||
|
||||
string working_directory;
|
||||
|
||||
class XMLInclude
|
||||
{
|
||||
public:
|
||||
XMLElement *e;
|
||||
Path path;
|
||||
|
||||
XMLInclude ( XMLElement* e_, const Path& path_ )
|
||||
: e(e_), path(path_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class XMLIncludes : public vector<XMLInclude*>
|
||||
{
|
||||
public:
|
||||
~XMLIncludes()
|
||||
{
|
||||
for ( size_t i = 0; i < this->size(); i++ )
|
||||
delete (*this)[i];
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
InitWorkingDirectory()
|
||||
{
|
||||
// store the current directory for path calculations
|
||||
working_directory.resize ( _MAX_PATH );
|
||||
working_directory[0] = 0;
|
||||
getcwd ( &working_directory[0], working_directory.size() );
|
||||
working_directory.resize ( strlen ( working_directory.c_str() ) );
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
unsigned __int64
|
||||
#else
|
||||
unsigned long long
|
||||
#endif
|
||||
filelen ( FILE* f )
|
||||
{
|
||||
#ifdef WIN32
|
||||
return _filelengthi64 ( _fileno(f) );
|
||||
#else
|
||||
struct stat64 file_stat;
|
||||
if ( fstat64(fileno(f), &file_stat) != 0 )
|
||||
return 0;
|
||||
return file_stat.st_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
Path::Path()
|
||||
{
|
||||
if ( !working_directory.size() )
|
||||
InitWorkingDirectory();
|
||||
string s ( working_directory );
|
||||
const char* p = strtok ( &s[0], "/\\" );
|
||||
while ( p )
|
||||
{
|
||||
if ( *p )
|
||||
path.push_back ( p );
|
||||
p = strtok ( NULL, "/\\" );
|
||||
}
|
||||
}
|
||||
|
||||
Path::Path ( const Path& cwd, const string& file )
|
||||
{
|
||||
string s ( cwd.Fixup ( file, false ) );
|
||||
const char* p = strtok ( &s[0], "/\\" );
|
||||
while ( p )
|
||||
{
|
||||
if ( *p )
|
||||
path.push_back ( p );
|
||||
p = strtok ( NULL, "/\\" );
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
Path::Fixup ( const string& file, bool include_filename ) const
|
||||
{
|
||||
if ( strchr ( "/\\", file[0] )
|
||||
#ifdef WIN32
|
||||
// this squirreliness is b/c win32 has drive letters and *nix doesn't...
|
||||
|| file[1] == ':'
|
||||
#endif//WIN32
|
||||
)
|
||||
{
|
||||
return file;
|
||||
}
|
||||
vector<string> pathtmp ( path );
|
||||
string tmp ( file );
|
||||
const char* prev = strtok ( &tmp[0], "/\\" );
|
||||
const char* p = strtok ( NULL, "/\\" );
|
||||
while ( p )
|
||||
{
|
||||
if ( !strcmp ( prev, "." ) )
|
||||
; // do nothing
|
||||
else if ( !strcmp ( prev, ".." ) )
|
||||
{
|
||||
// this squirreliness is b/c win32 has drive letters and *nix doesn't...
|
||||
#ifdef WIN32
|
||||
if ( pathtmp.size() > 1 )
|
||||
#else
|
||||
if ( pathtmp.size() )
|
||||
#endif
|
||||
pathtmp.resize ( pathtmp.size() - 1 );
|
||||
}
|
||||
else
|
||||
pathtmp.push_back ( prev );
|
||||
prev = p;
|
||||
p = strtok ( NULL, "/\\" );
|
||||
}
|
||||
if ( include_filename )
|
||||
pathtmp.push_back ( prev );
|
||||
|
||||
// reuse tmp variable to return recombined path
|
||||
tmp.resize(0);
|
||||
for ( size_t i = 0; i < pathtmp.size(); i++ )
|
||||
{
|
||||
// this squirreliness is b/c win32 has drive letters and *nix doesn't...
|
||||
#ifdef WIN32
|
||||
if ( i ) tmp += "/";
|
||||
#else
|
||||
tmp += "/";
|
||||
#endif
|
||||
tmp += pathtmp[i];
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*static*/ string
|
||||
Path::RelativeFromWorkingDirectory ( const string& path )
|
||||
{
|
||||
vector<string> vwork, vpath, vout;
|
||||
Path::Split ( vwork, working_directory, true );
|
||||
Path::Split ( vpath, path, true );
|
||||
#ifdef WIN32
|
||||
// this squirreliness is b/c win32 has drive letters and *nix doesn't...
|
||||
// not possible to do relative across different drive letters
|
||||
if ( vwork[0] != vpath[0] )
|
||||
return path;
|
||||
#endif
|
||||
size_t i = 0;
|
||||
while ( i < vwork.size() && i < vpath.size() && vwork[i] == vpath[i] )
|
||||
++i;
|
||||
if ( i < vwork.size() )
|
||||
{
|
||||
// path goes above our working directory, we will need some ..'s
|
||||
for ( size_t j = 0; j < i; j++ )
|
||||
vout.push_back ( ".." );
|
||||
}
|
||||
while ( i < vpath.size() )
|
||||
vout.push_back ( vpath[i++] );
|
||||
|
||||
// now merge vout into a string again
|
||||
string out = ".";
|
||||
for ( i = 0; i < vout.size(); i++ )
|
||||
{
|
||||
out += "/" + vout[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
Path::Split ( vector<string>& out,
|
||||
const string& path,
|
||||
bool include_last )
|
||||
{
|
||||
string s ( path );
|
||||
const char* prev = strtok ( &s[0], "/\\" );
|
||||
const char* p = strtok ( NULL, "/\\" );
|
||||
out.resize ( 0 );
|
||||
while ( p )
|
||||
{
|
||||
out.push_back ( prev );
|
||||
prev = p;
|
||||
p = strtok ( NULL, "/\\" );
|
||||
}
|
||||
if ( include_last )
|
||||
out.push_back ( prev );
|
||||
}
|
||||
|
||||
XMLFile::XMLFile()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
XMLFile::close()
|
||||
{
|
||||
_buf.resize(0);
|
||||
_p = _end = NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
XMLFile::open(const string& filename_)
|
||||
{
|
||||
close();
|
||||
FILE* f = fopen ( filename_.c_str(), "rb" );
|
||||
if ( !f )
|
||||
return false;
|
||||
unsigned long len = (unsigned long)filelen(f);
|
||||
_buf.resize ( len );
|
||||
fread ( &_buf[0], 1, len, f );
|
||||
fclose ( f );
|
||||
_p = _buf.c_str();
|
||||
_end = _p + len;
|
||||
_filename = filename_;
|
||||
next_token();
|
||||
return true;
|
||||
}
|
||||
|
||||
// next_token() moves the pointer to next token, which may be
|
||||
// an xml element or a text element, basically it's a glorified
|
||||
// skipspace, normally the user of this class won't need to call
|
||||
// this function
|
||||
void
|
||||
XMLFile::next_token()
|
||||
{
|
||||
_p += strspn ( _p, WS );
|
||||
}
|
||||
|
||||
bool
|
||||
XMLFile::next_is_text()
|
||||
{
|
||||
return *_p != '<';
|
||||
}
|
||||
|
||||
bool
|
||||
XMLFile::more_tokens()
|
||||
{
|
||||
return _p != _end;
|
||||
}
|
||||
|
||||
// get_token() is used to return a token, and move the pointer
|
||||
// past the token
|
||||
bool
|
||||
XMLFile::get_token(string& token)
|
||||
{
|
||||
const char* tokend;
|
||||
if ( !strncmp ( _p, "<!--", 4 ) )
|
||||
{
|
||||
tokend = strstr ( _p, "-->" );
|
||||
if ( !tokend )
|
||||
tokend = _end;
|
||||
else
|
||||
tokend += 3;
|
||||
}
|
||||
else if ( !strncmp ( _p, "<?", 2 ) )
|
||||
{
|
||||
tokend = strstr ( _p, "?>" );
|
||||
if ( !tokend )
|
||||
tokend = _end;
|
||||
else
|
||||
tokend += 2;
|
||||
}
|
||||
else if ( *_p == '<' )
|
||||
{
|
||||
tokend = strchr ( _p, '>' );
|
||||
if ( !tokend )
|
||||
tokend = _end;
|
||||
else
|
||||
++tokend;
|
||||
}
|
||||
else
|
||||
{
|
||||
tokend = strchr ( _p, '<' );
|
||||
if ( !tokend )
|
||||
tokend = _end;
|
||||
while ( tokend > _p && isspace(tokend[-1]) )
|
||||
--tokend;
|
||||
}
|
||||
if ( tokend == _p )
|
||||
return false;
|
||||
token = string ( _p, tokend-_p );
|
||||
_p = tokend;
|
||||
next_token();
|
||||
return true;
|
||||
}
|
||||
|
||||
string
|
||||
XMLFile::Location() const
|
||||
{
|
||||
int line = 1;
|
||||
const char* p = strchr ( _buf.c_str(), '\n' );
|
||||
while ( p && p < _p )
|
||||
{
|
||||
++line;
|
||||
p = strchr ( p+1, '\n' );
|
||||
}
|
||||
return ssprintf ( "%s(%i)",_filename.c_str(), line );
|
||||
}
|
||||
|
||||
XMLAttribute::XMLAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
XMLAttribute::XMLAttribute(const string& name_,
|
||||
const string& value_)
|
||||
: name(name_), value(value_)
|
||||
{
|
||||
}
|
||||
|
||||
XMLAttribute::XMLAttribute ( const XMLAttribute& src )
|
||||
: name(src.name), value(src.value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XMLAttribute& XMLAttribute::operator = ( const XMLAttribute& src )
|
||||
{
|
||||
name = src.name;
|
||||
value = src.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
XMLElement::XMLElement ( const string& location_ )
|
||||
: location(location_),
|
||||
parentElement(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
XMLElement::~XMLElement()
|
||||
{
|
||||
size_t i;
|
||||
for ( i = 0; i < attributes.size(); i++ )
|
||||
delete attributes[i];
|
||||
for ( i = 0; i < subElements.size(); i++ )
|
||||
delete subElements[i];
|
||||
}
|
||||
|
||||
void
|
||||
XMLElement::AddSubElement ( XMLElement* e )
|
||||
{
|
||||
subElements.push_back ( e );
|
||||
e->parentElement = this;
|
||||
}
|
||||
|
||||
// Parse()
|
||||
// This function takes a single xml tag ( i.e. beginning with '<' and
|
||||
// ending with '>', and parses out it's tag name and constituent
|
||||
// attributes.
|
||||
// Return Value: returns true if you need to look for a </tag> for
|
||||
// the one it just parsed...
|
||||
bool
|
||||
XMLElement::Parse(const string& token,
|
||||
bool& end_tag)
|
||||
{
|
||||
const char* p = token.c_str();
|
||||
assert ( *p == '<' );
|
||||
++p;
|
||||
p += strspn ( p, WS );
|
||||
|
||||
// check if this is a comment
|
||||
if ( !strncmp ( p, "!--", 3 ) )
|
||||
{
|
||||
name = "!--";
|
||||
end_tag = false;
|
||||
return false; // never look for end tag to a comment
|
||||
}
|
||||
|
||||
end_tag = ( *p == '/' );
|
||||
if ( end_tag )
|
||||
{
|
||||
++p;
|
||||
p += strspn ( p, WS );
|
||||
}
|
||||
const char* end = strpbrk ( p, WS );
|
||||
if ( !end )
|
||||
{
|
||||
end = strpbrk ( p, "/>" );
|
||||
assert ( end );
|
||||
}
|
||||
name = string ( p, end-p );
|
||||
p = end;
|
||||
p += strspn ( p, WS );
|
||||
while ( *p != '>' && *p != '/' )
|
||||
{
|
||||
end = strpbrk ( p, WSEQ );
|
||||
if ( !end )
|
||||
{
|
||||
end = strpbrk ( p, "/>" );
|
||||
assert ( end );
|
||||
}
|
||||
string attribute ( p, end-p ), value;
|
||||
p = end;
|
||||
p += strspn ( p, WS );
|
||||
if ( *p == '=' )
|
||||
{
|
||||
++p;
|
||||
p += strspn ( p, WS );
|
||||
char quote = 0;
|
||||
if ( strchr ( "\"'", *p ) )
|
||||
{
|
||||
quote = *p++;
|
||||
end = strchr ( p, quote );
|
||||
}
|
||||
else
|
||||
{
|
||||
end = strpbrk ( p, WS );
|
||||
}
|
||||
if ( !end )
|
||||
{
|
||||
end = strchr ( p, '>' );
|
||||
assert(end);
|
||||
if ( end[-1] == '/' )
|
||||
end--;
|
||||
}
|
||||
value = string ( p, end-p );
|
||||
p = end;
|
||||
if ( quote && *p == quote )
|
||||
p++;
|
||||
p += strspn ( p, WS );
|
||||
}
|
||||
else if ( name[0] != '!' )
|
||||
{
|
||||
throw XMLSyntaxErrorException ( location,
|
||||
"attributes must have values" );
|
||||
}
|
||||
attributes.push_back ( new XMLAttribute ( attribute, value ) );
|
||||
}
|
||||
return !( *p == '/' ) && !end_tag;
|
||||
}
|
||||
|
||||
XMLAttribute*
|
||||
XMLElement::GetAttribute ( const string& attribute,
|
||||
bool required )
|
||||
{
|
||||
// this would be faster with a tree-based container, but our attribute
|
||||
// lists are likely to stay so short as to not be an issue.
|
||||
for ( size_t i = 0; i < attributes.size(); i++ )
|
||||
{
|
||||
if ( attribute == attributes[i]->name )
|
||||
return attributes[i];
|
||||
}
|
||||
if ( required )
|
||||
{
|
||||
throw RequiredAttributeNotFoundException ( location,
|
||||
attribute,
|
||||
name );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const XMLAttribute*
|
||||
XMLElement::GetAttribute ( const string& attribute,
|
||||
bool required ) const
|
||||
{
|
||||
// this would be faster with a tree-based container, but our attribute
|
||||
// lists are likely to stay so short as to not be an issue.
|
||||
for ( size_t i = 0; i < attributes.size(); i++ )
|
||||
{
|
||||
if ( attribute == attributes[i]->name )
|
||||
return attributes[i];
|
||||
}
|
||||
if ( required )
|
||||
{
|
||||
throw RequiredAttributeNotFoundException ( location,
|
||||
attribute,
|
||||
name );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// XMLParse()
|
||||
// This function reads a "token" from the file loaded in XMLFile
|
||||
// if it finds a tag that is non-singular, it parses sub-elements and/or
|
||||
// inner text into the XMLElement that it is building to return.
|
||||
// Return Value: an XMLElement allocated via the new operator that contains
|
||||
// it's parsed data. Keep calling this function until it returns NULL
|
||||
// (no more data)
|
||||
XMLElement*
|
||||
XMLParse(XMLFile& f,
|
||||
XMLIncludes* includes,
|
||||
const Path& path,
|
||||
bool* pend_tag = NULL )
|
||||
{
|
||||
string token;
|
||||
if ( !f.get_token(token) )
|
||||
return NULL;
|
||||
bool end_tag, is_include = false;
|
||||
|
||||
while ( token[0] != '<'
|
||||
|| !strncmp ( token.c_str(), "<!--", 4 )
|
||||
|| !strncmp ( token.c_str(), "<?", 2 ) )
|
||||
{
|
||||
if ( token[0] != '<' )
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"expecting xml tag, not '%s'",
|
||||
token.c_str() );
|
||||
if ( !f.get_token(token) )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMLElement* e = new XMLElement ( f.Location() );
|
||||
bool bNeedEnd = e->Parse ( token, end_tag );
|
||||
|
||||
if ( e->name == "xi:include" && includes )
|
||||
{
|
||||
includes->push_back ( new XMLInclude ( e, path ) );
|
||||
is_include = true;
|
||||
}
|
||||
|
||||
if ( !bNeedEnd )
|
||||
{
|
||||
if ( pend_tag )
|
||||
*pend_tag = end_tag;
|
||||
else if ( end_tag )
|
||||
{
|
||||
delete e;
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"end tag '%s' not expected",
|
||||
token.c_str() );
|
||||
return NULL;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
bool bThisMixingErrorReported = false;
|
||||
while ( f.more_tokens() )
|
||||
{
|
||||
if ( f.next_is_text() )
|
||||
{
|
||||
if ( !f.get_token ( token ) || !token.size() )
|
||||
{
|
||||
throw InvalidBuildFileException (
|
||||
f.Location(),
|
||||
"internal tool error - get_token() failed when more_tokens() returned true" );
|
||||
break;
|
||||
}
|
||||
if ( e->subElements.size() && !bThisMixingErrorReported )
|
||||
{
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"mixing of inner text with sub elements" );
|
||||
bThisMixingErrorReported = true;
|
||||
}
|
||||
if ( strchr ( token.c_str(), '>' ) )
|
||||
{
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"invalid symbol '>'" );
|
||||
}
|
||||
if ( e->value.size() )
|
||||
{
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"multiple instances of inner text" );
|
||||
e->value += " " + token;
|
||||
}
|
||||
else
|
||||
e->value = token;
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLElement* e2 = XMLParse ( f, is_include ? NULL : includes, path, &end_tag );
|
||||
if ( !e2 )
|
||||
{
|
||||
throw InvalidBuildFileException (
|
||||
e->location,
|
||||
"end of file found looking for end tag" );
|
||||
break;
|
||||
}
|
||||
if ( end_tag )
|
||||
{
|
||||
if ( e->name != e2->name )
|
||||
{
|
||||
delete e2;
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"end tag name mismatch" );
|
||||
break;
|
||||
}
|
||||
delete e2;
|
||||
break;
|
||||
}
|
||||
if ( e->value.size() && !bThisMixingErrorReported )
|
||||
{
|
||||
throw XMLSyntaxErrorException ( f.Location(),
|
||||
"mixing of inner text with sub elements" );
|
||||
bThisMixingErrorReported = true;
|
||||
}
|
||||
e->AddSubElement ( e2 );
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
XMLReadFile ( XMLFile& f, XMLElement& head, XMLIncludes& includes, const Path& path )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
XMLElement* e = XMLParse ( f, &includes, path );
|
||||
if ( !e )
|
||||
return;
|
||||
head.AddSubElement ( e );
|
||||
}
|
||||
}
|
||||
|
||||
XMLElement*
|
||||
XMLLoadInclude ( XMLElement* e, const Path& path, XMLIncludes& includes )
|
||||
{
|
||||
XMLAttribute* att;
|
||||
att = e->GetAttribute("href",true);
|
||||
assert(att);
|
||||
|
||||
string file ( path.Fixup(att->value,true) );
|
||||
string top_file ( Path::RelativeFromWorkingDirectory ( file ) );
|
||||
e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) );
|
||||
XMLFile fInc;
|
||||
if ( !fInc.open ( file ) )
|
||||
{
|
||||
// look for xi:fallback element
|
||||
for ( size_t i = 0; i < e->subElements.size(); i++ )
|
||||
{
|
||||
XMLElement* e2 = e->subElements[i];
|
||||
if ( e2->name == "xi:fallback" )
|
||||
{
|
||||
// now look for xi:include below...
|
||||
for ( i = 0; i < e2->subElements.size(); i++ )
|
||||
{
|
||||
XMLElement* e3 = e2->subElements[i];
|
||||
if ( e3->name == "xi:include" )
|
||||
{
|
||||
return XMLLoadInclude ( e3, path, includes );
|
||||
}
|
||||
}
|
||||
throw InvalidBuildFileException (
|
||||
e2->location,
|
||||
"<xi:fallback> must have a <xi:include> sub-element" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLElement* new_e = new XMLElement ( e->location );
|
||||
new_e->name = "xi:included";
|
||||
Path path2 ( path, att->value );
|
||||
XMLReadFile ( fInc, *new_e, includes, path2 );
|
||||
return new_e;
|
||||
}
|
||||
}
|
||||
|
||||
XMLElement*
|
||||
XMLLoadFile ( const string& filename, const Path& path )
|
||||
{
|
||||
XMLIncludes includes;
|
||||
XMLFile f;
|
||||
|
||||
if ( !f.open ( filename ) )
|
||||
throw FileNotFoundException ( filename );
|
||||
|
||||
XMLElement* head = new XMLElement("(virtual)");
|
||||
|
||||
XMLReadFile ( f, *head, includes, path );
|
||||
|
||||
for ( size_t i = 0; i < includes.size(); i++ )
|
||||
{
|
||||
XMLElement* e = includes[i]->e;
|
||||
XMLElement* e2 = XMLLoadInclude ( includes[i]->e, includes[i]->path, includes );
|
||||
if ( !e2 )
|
||||
{
|
||||
throw FileNotFoundException (
|
||||
ssprintf("%s (referenced from %s)",
|
||||
e->GetAttribute("top_href",true)->value.c_str(),
|
||||
f.Location().c_str() ) );
|
||||
}
|
||||
XMLElement* parent = e->parentElement;
|
||||
XMLElement** parent_container = NULL;
|
||||
if ( !parent )
|
||||
{
|
||||
delete e;
|
||||
throw Exception ( "internal tool error: xi:include doesn't have a parent" );
|
||||
return NULL;
|
||||
}
|
||||
for ( size_t j = 0; j < parent->subElements.size(); j++ )
|
||||
{
|
||||
if ( parent->subElements[j] == e )
|
||||
{
|
||||
parent_container = &parent->subElements[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !parent_container )
|
||||
{
|
||||
delete e;
|
||||
throw Exception ( "internal tool error: couldn't find xi:include in parent's sub-elements" );
|
||||
return NULL;
|
||||
}
|
||||
// replace inclusion tree with the imported tree
|
||||
e2->parentElement = e->parentElement;
|
||||
e2->name = e->name;
|
||||
e2->attributes = e->attributes;
|
||||
*parent_container = e2;
|
||||
e->attributes.resize(0);
|
||||
delete e;
|
||||
}
|
||||
return head;
|
||||
}
|
96
reactos/tools/buildno/XML.h
Normal file
96
reactos/tools/buildno/XML.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
// XML.h
|
||||
|
||||
#ifndef XML_H
|
||||
#define XML_H
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
void
|
||||
InitWorkingDirectory();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
unsigned __int64
|
||||
#else
|
||||
unsigned long long
|
||||
#endif
|
||||
filelen ( FILE* f );
|
||||
|
||||
class Path
|
||||
{
|
||||
std::vector<std::string> path;
|
||||
public:
|
||||
Path(); // initializes path to getcwd();
|
||||
Path ( const Path& cwd, const std::string& filename );
|
||||
std::string Fixup ( const std::string& filename, bool include_filename ) const;
|
||||
|
||||
static std::string RelativeFromWorkingDirectory ( const std::string& path );
|
||||
|
||||
static void Split ( std::vector<std::string>& out,
|
||||
const std::string& path,
|
||||
bool include_last );
|
||||
};
|
||||
|
||||
class XMLFile
|
||||
{
|
||||
friend class XMLElement;
|
||||
public:
|
||||
XMLFile();
|
||||
void close();
|
||||
bool open(const std::string& filename);
|
||||
void next_token();
|
||||
bool next_is_text();
|
||||
bool more_tokens();
|
||||
bool get_token(std::string& token);
|
||||
const std::string& filename() { return _filename; }
|
||||
std::string Location() const;
|
||||
|
||||
private:
|
||||
std::string _buf, _filename;
|
||||
|
||||
const char *_p, *_end;
|
||||
};
|
||||
|
||||
|
||||
class XMLAttribute
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
XMLAttribute();
|
||||
XMLAttribute ( const std::string& name_, const std::string& value_ );
|
||||
XMLAttribute ( const XMLAttribute& );
|
||||
XMLAttribute& operator = ( const XMLAttribute& );
|
||||
};
|
||||
|
||||
|
||||
class XMLElement
|
||||
{
|
||||
public:
|
||||
std::string location;
|
||||
std::string name;
|
||||
std::vector<XMLAttribute*> attributes;
|
||||
XMLElement* parentElement;
|
||||
std::vector<XMLElement*> subElements;
|
||||
std::string value;
|
||||
|
||||
XMLElement ( const std::string& location_ );
|
||||
~XMLElement();
|
||||
bool Parse(const std::string& token,
|
||||
bool& end_tag);
|
||||
void AddSubElement ( XMLElement* e );
|
||||
XMLAttribute* GetAttribute ( const std::string& attribute,
|
||||
bool required);
|
||||
const XMLAttribute* GetAttribute ( const std::string& attribute,
|
||||
bool required) const;
|
||||
};
|
||||
|
||||
XMLElement*
|
||||
XMLLoadFile ( const std::string& filename, const Path& path );
|
||||
|
||||
/*XMLElement*
|
||||
XMLParse(XMLFile& f,
|
||||
const Path& path,
|
||||
bool* pend_tag = NULL);*/
|
||||
|
||||
#endif//XML_H
|
|
@ -27,13 +27,15 @@
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "../include/reactos/version.h"
|
||||
#include "version.h"
|
||||
#include "XML.h"
|
||||
#include "exception.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* File to (over)write */
|
||||
#define BUILDNO_INCLUDE_FILE "../include/reactos/buildno.h"
|
||||
#define BUILDNO_INCLUDE_FILE "../../include/reactos/buildno.h"
|
||||
|
||||
static char * argv0 = "";
|
||||
|
||||
|
@ -59,10 +61,10 @@ write_h (int build, char *buildstr)
|
|||
FILE *h = NULL;
|
||||
char* s;
|
||||
char* s1;
|
||||
int length;
|
||||
unsigned length;
|
||||
int dllversion = KERNEL_VERSION_MAJOR + 42;
|
||||
|
||||
s1 = s = malloc(256 * 1024);
|
||||
s1 = s = (char *) malloc(256 * 1024);
|
||||
|
||||
s = s + sprintf (s, "/* Do not edit - Machine generated */\n");
|
||||
|
||||
|
@ -146,7 +148,7 @@ write_h (int build, char *buildstr)
|
|||
{
|
||||
char* orig;
|
||||
|
||||
orig = malloc(length);
|
||||
orig = (char *) malloc(length);
|
||||
fseek(h, 0, SEEK_SET);
|
||||
fread(orig, 1, length, h);
|
||||
if (memcmp(s1, orig, length) == 0)
|
||||
|
@ -175,39 +177,68 @@ char *
|
|||
GetRev(void)
|
||||
{
|
||||
static char Unknown[] = "UNKNOWN";
|
||||
static char Rev[10]; /* 999999999 revisions should be enough for everyone... */
|
||||
FILE *SvnCmd;
|
||||
char Line[256];
|
||||
char *p;
|
||||
static char Revision[10]; /* 999999999 revisions should be enough for everyone... */
|
||||
|
||||
SvnCmd = popen("svn info", "r");
|
||||
if (NULL == SvnCmd)
|
||||
try
|
||||
{
|
||||
fprintf(stderr, "Failed to run \"svn info\" command\n");
|
||||
return Unknown;
|
||||
}
|
||||
while (! feof(SvnCmd) && ! ferror(SvnCmd))
|
||||
{
|
||||
if (NULL == fgets(Line, sizeof(Line), SvnCmd))
|
||||
Path path;
|
||||
XMLElement *head;
|
||||
|
||||
try
|
||||
{
|
||||
break;
|
||||
head = XMLLoadFile(".svn/entries", path);
|
||||
}
|
||||
if (0 == strncmp(Line, "Revision: ", 10))
|
||||
catch(FileNotFoundException)
|
||||
{
|
||||
pclose(SvnCmd);
|
||||
p = Line + 10;
|
||||
if (sizeof(Rev) < strlen(p))
|
||||
head = XMLLoadFile("_svn/entries", path);
|
||||
}
|
||||
XMLElement *entries = head->subElements[0];
|
||||
for (size_t i = 0; i < entries->subElements.size(); i++)
|
||||
{
|
||||
XMLElement *entry = entries->subElements[i];
|
||||
if ("entry" == entry->name)
|
||||
{
|
||||
fprintf(stderr, "Weird SVN revision number %s", p);
|
||||
return Unknown;
|
||||
bool GotName = false;
|
||||
bool GotKind = false;
|
||||
bool GotRevision = false;
|
||||
for (size_t j = 0; j < entry->attributes.size(); j++)
|
||||
{
|
||||
XMLAttribute *Attribute = entry->attributes[j];
|
||||
if ("name" == Attribute->name && "" == Attribute->value)
|
||||
{
|
||||
GotName = true;
|
||||
}
|
||||
if ("kind" == Attribute->name && "dir" == Attribute->value)
|
||||
{
|
||||
GotKind = true;
|
||||
}
|
||||
if ("revision" == Attribute->name)
|
||||
{
|
||||
if (sizeof(Revision) <= Attribute->value.length() + 1)
|
||||
{
|
||||
strcpy(Revision, "revtoobig");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(Revision, Attribute->value.c_str());
|
||||
}
|
||||
GotRevision = true;
|
||||
}
|
||||
if (GotName && GotKind && GotRevision)
|
||||
{
|
||||
delete head;
|
||||
return Revision;
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(Rev, p, strlen(p) - 1);
|
||||
Rev[strlen(p) - 1] = '\0';
|
||||
return Rev;
|
||||
}
|
||||
}
|
||||
|
||||
pclose(SvnCmd);
|
||||
delete head;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
return Unknown;
|
||||
}
|
178
reactos/tools/buildno/exception.cpp
Normal file
178
reactos/tools/buildno/exception.cpp
Normal file
|
@ -0,0 +1,178 @@
|
|||
#include "pch.h"
|
||||
|
||||
#ifdef RBUILD
|
||||
#include "rbuild.h"
|
||||
#else
|
||||
#include "exception.h"
|
||||
#include "ssprintf.h"
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
|
||||
Exception::Exception ()
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception ( const string& message )
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
Exception::Exception ( const char* format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start ( args,
|
||||
format);
|
||||
Message = ssvprintf ( format,
|
||||
args);
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
void Exception::SetMessage ( const char* message,
|
||||
va_list args)
|
||||
{
|
||||
Message = ssvprintf ( message,
|
||||
args);
|
||||
}
|
||||
|
||||
|
||||
OutOfMemoryException::OutOfMemoryException ()
|
||||
: Exception ( "Out of memory" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InvalidOperationException::InvalidOperationException ( const char* filename,
|
||||
const int linenumber )
|
||||
{
|
||||
Message = ssprintf ( "%s:%d",
|
||||
filename,
|
||||
linenumber );
|
||||
}
|
||||
|
||||
InvalidOperationException::InvalidOperationException ( const char* filename,
|
||||
const int linenumber,
|
||||
const char* message,
|
||||
... )
|
||||
{
|
||||
string errorMessage;
|
||||
va_list args;
|
||||
va_start ( args,
|
||||
message );
|
||||
errorMessage = ssvprintf ( message,
|
||||
args );
|
||||
va_end ( args );
|
||||
Message = ssprintf ( "%s:%d %s",
|
||||
filename,
|
||||
linenumber,
|
||||
errorMessage.c_str () );
|
||||
}
|
||||
|
||||
|
||||
FileNotFoundException::FileNotFoundException ( const string& filename )
|
||||
: Exception ( "File '%s' not found.",
|
||||
filename.c_str() )
|
||||
{
|
||||
Filename = filename;
|
||||
}
|
||||
|
||||
|
||||
AccessDeniedException::AccessDeniedException ( const string& filename)
|
||||
: Exception ( "Access denied to file '%s'.",
|
||||
filename.c_str() )
|
||||
{
|
||||
Filename = filename;
|
||||
}
|
||||
|
||||
|
||||
InvalidBuildFileException::InvalidBuildFileException ( const string& location,
|
||||
const char* message,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start ( args,
|
||||
message );
|
||||
SetLocationMessage ( location, message, args );
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
InvalidBuildFileException::InvalidBuildFileException ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InvalidBuildFileException::SetLocationMessage ( const std::string& location,
|
||||
const char* message,
|
||||
va_list args )
|
||||
{
|
||||
Message = location + ": " + ssvprintf ( message, args );
|
||||
}
|
||||
|
||||
XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
|
||||
const char* message,
|
||||
... )
|
||||
{
|
||||
va_list args;
|
||||
va_start ( args,
|
||||
message );
|
||||
SetLocationMessage ( location, message, args );
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
|
||||
RequiredAttributeNotFoundException::RequiredAttributeNotFoundException (
|
||||
const string& location,
|
||||
const string& attributeName,
|
||||
const string& elementName )
|
||||
: InvalidBuildFileException ( location,
|
||||
"Required attribute '%s' not found on '%s'.",
|
||||
attributeName.c_str (),
|
||||
elementName.c_str ())
|
||||
{
|
||||
}
|
||||
|
||||
InvalidAttributeValueException::InvalidAttributeValueException (
|
||||
const string& location,
|
||||
const string& name,
|
||||
const string& value )
|
||||
: InvalidBuildFileException ( location,
|
||||
"Attribute '%s' has an invalid value '%s'.",
|
||||
name.c_str (),
|
||||
value.c_str () )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BackendNameConflictException::BackendNameConflictException ( const string& name )
|
||||
: Exception ( "Backend name conflict: '%s'",
|
||||
name.c_str() )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UnknownBackendException::UnknownBackendException ( const string& name )
|
||||
: Exception ( "Unknown Backend requested: '%s'",
|
||||
name.c_str() )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UnknownModuleTypeException::UnknownModuleTypeException ( const string& location,
|
||||
int moduletype )
|
||||
: InvalidBuildFileException ( location,
|
||||
"module type requested: %i",
|
||||
moduletype )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InvocationFailedException::InvocationFailedException ( const std::string& command,
|
||||
int exitcode )
|
||||
: Exception ( "Failed to execute '%s' (exit code %d)",
|
||||
command.c_str (),
|
||||
exitcode )
|
||||
{
|
||||
Command = command;
|
||||
ExitCode = exitcode;
|
||||
}
|
125
reactos/tools/buildno/exception.h
Normal file
125
reactos/tools/buildno/exception.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
#ifndef __EXCEPTION_H
|
||||
#define __EXCEPTION_H
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception ( const std::string& message );
|
||||
Exception ( const char* format,
|
||||
...);
|
||||
std::string Message;
|
||||
protected:
|
||||
Exception ();
|
||||
void SetMessage ( const char* message,
|
||||
va_list args);
|
||||
};
|
||||
|
||||
|
||||
class InvalidOperationException : public Exception
|
||||
{
|
||||
public:
|
||||
InvalidOperationException ( const char* filename,
|
||||
const int linenumber);
|
||||
InvalidOperationException ( const char* filename,
|
||||
const int linenumber,
|
||||
const char* message,
|
||||
... );
|
||||
};
|
||||
|
||||
|
||||
class OutOfMemoryException : public Exception
|
||||
{
|
||||
public:
|
||||
OutOfMemoryException ();
|
||||
};
|
||||
|
||||
|
||||
class FileNotFoundException : public Exception
|
||||
{
|
||||
public:
|
||||
FileNotFoundException ( const std::string& filename );
|
||||
std::string Filename;
|
||||
};
|
||||
|
||||
|
||||
class AccessDeniedException : public Exception
|
||||
{
|
||||
public:
|
||||
AccessDeniedException ( const std::string& filename );
|
||||
std::string Filename;
|
||||
};
|
||||
|
||||
class InvalidBuildFileException : public Exception
|
||||
{
|
||||
public:
|
||||
InvalidBuildFileException ( const std::string& location,
|
||||
const char* message,
|
||||
...);
|
||||
void SetLocationMessage ( const std::string& location,
|
||||
const char* message,
|
||||
va_list args );
|
||||
protected:
|
||||
InvalidBuildFileException ();
|
||||
};
|
||||
|
||||
|
||||
class XMLSyntaxErrorException : public InvalidBuildFileException
|
||||
{
|
||||
public:
|
||||
XMLSyntaxErrorException ( const std::string& location,
|
||||
const char* message,
|
||||
... );
|
||||
};
|
||||
|
||||
|
||||
class RequiredAttributeNotFoundException : public InvalidBuildFileException
|
||||
{
|
||||
public:
|
||||
RequiredAttributeNotFoundException ( const std::string& location,
|
||||
const std::string& attributeName,
|
||||
const std::string& elementName );
|
||||
};
|
||||
|
||||
|
||||
class InvalidAttributeValueException : public InvalidBuildFileException
|
||||
{
|
||||
public:
|
||||
InvalidAttributeValueException ( const std::string& location,
|
||||
const std::string& name,
|
||||
const std::string& value );
|
||||
};
|
||||
|
||||
|
||||
class BackendNameConflictException : public Exception
|
||||
{
|
||||
public:
|
||||
BackendNameConflictException ( const std::string& name );
|
||||
};
|
||||
|
||||
|
||||
class UnknownBackendException : public Exception
|
||||
{
|
||||
public:
|
||||
UnknownBackendException ( const std::string& name );
|
||||
};
|
||||
|
||||
class UnknownModuleTypeException : public InvalidBuildFileException
|
||||
{
|
||||
public:
|
||||
UnknownModuleTypeException ( const std::string& location,
|
||||
int moduletype );
|
||||
};
|
||||
|
||||
|
||||
class InvocationFailedException : public Exception
|
||||
{
|
||||
public:
|
||||
InvocationFailedException ( const std::string& command,
|
||||
int exitcode );
|
||||
std::string Command;
|
||||
int ExitCode;
|
||||
};
|
||||
|
||||
#endif /* __EXCEPTION_H */
|
44
reactos/tools/buildno/pch.h
Normal file
44
reactos/tools/buildno/pch.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// pre-compiled header stuff
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning ( disable : 4786 ) // identifier was truncated to '255' characters in the debug information
|
||||
#endif//_MSC_VER
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifndef RBUILD
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAX_PATH _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <wctype.h>
|
||||
#include <math.h>
|
||||
|
||||
inline char* strlwr ( char* str )
|
||||
{
|
||||
char* p = str;
|
||||
while ( *p )
|
||||
*p++ = tolower(*p);
|
||||
return str;
|
||||
}
|
||||
|
||||
#define _finite __finite
|
||||
#define _isnan __isnan
|
||||
#define stricmp strcasecmp
|
||||
#define MAX_PATH PATH_MAX
|
||||
#define _MAX_PATH PATH_MAX
|
||||
#endif
|
||||
|
||||
#endif//PCH_H
|
1920
reactos/tools/buildno/ssprintf.cpp
Normal file
1920
reactos/tools/buildno/ssprintf.cpp
Normal file
File diff suppressed because it is too large
Load diff
23
reactos/tools/buildno/ssprintf.h
Normal file
23
reactos/tools/buildno/ssprintf.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// ssprintf.h
|
||||
|
||||
#ifndef SSPRINTF_H
|
||||
#define SSPRINTF_H
|
||||
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
|
||||
std::string ssprintf ( const char* fmt, ... );
|
||||
std::string ssvprintf ( const char* fmt, va_list args );
|
||||
|
||||
std::wstring sswprintf ( const wchar_t* fmt, ... );
|
||||
std::wstring sswvprintf ( const wchar_t* fmt, va_list args );
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define sstprintf sswprintf
|
||||
#define sstvprintf sswvprintf
|
||||
#else
|
||||
#define sstprintf ssprintf
|
||||
#define sstvprintf ssvprintf
|
||||
#endif
|
||||
|
||||
#endif//SSPRINTF_H
|
Loading…
Reference in a new issue