diff options
Diffstat (limited to 'soltools')
71 files changed, 15825 insertions, 0 deletions
diff --git a/soltools/adjustvisibility/adjustvisibility.cxx b/soltools/adjustvisibility/adjustvisibility.cxx new file mode 100644 index 000000000000..e67017018b1a --- /dev/null +++ b/soltools/adjustvisibility/adjustvisibility.cxx @@ -0,0 +1,311 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +/* + * adjustvisibilty -- a tool to adjust the visibility of the so called + * 'fix and continue' globalized symbols generated by + * the Sun Studio 8 compiler from 'DEFAULT' to 'HIDDEN' + * + * References: "Linker and Libraries Guide", Solaris 9 documentation + * "Stabs Interface", SunStudio 8 documentation + */ + +#include <string> +#include <iostream> +#include <exception> +#include <stdexcept> +#include <cerrno> +#include <fcntl.h> +#include <unistd.h> +#include <libelf.h> +#include <gelf.h> +#include <utime.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <limits> +#include <stdio.h> + +// Note: There is no GELF_ST_VISIBILITY macro in gelf.h, we roll our own. +#define GELF_ST_VISIBILITY(o) ((o)&0x3) // See "Linker and Libraries Guide". + +// See "Linker and Libraries Guide", ELF object format description. +static const char* SymbolType[STT_NUM] = { + "NOTYPE", + "OBJECT", + "FUNC ", + "SECT ", + "FILE ", + "COMM ", + "TLS " +}; + +static const char* SymbolBinding[STB_NUM] = { + "LOCAL ", + "GLOBAL", + "WEAK " +}; + +static const char* SymbolVisibility[4] = { // Note: There is no STV_NUM macro + "DEFAULT ", + "INTERNAL ", + "HIDDEN ", + "PROTECTED" +}; + +class ElfError : public std::exception +{ + public: + ElfError(const std::string& rFile, const std::string& rMessage); + ~ElfError() throw() {}; + virtual const char* what() const throw() { return m_sMessage.c_str(); } + + private: + std::string m_sMessage; +}; + +ElfError::ElfError(const std::string& rFile, const std::string& rMessage) +{ + if ( rFile != "" ) { + m_sMessage = rFile; + m_sMessage += ": "; + } + m_sMessage += rMessage; + const char *pElfMsg = elf_errmsg(0); + if ( pElfMsg ) { + m_sMessage += ": "; + m_sMessage += pElfMsg; + } +} + +void initElfLib() +{ + if ( elf_version(EV_CURRENT) == EV_NONE) { + throw ElfError("", "elf_version() failed"); + } + return; +} + +bool isFixAndContinueSymbol(const std::string& rSymbol) +{ + // The globalized 'fix and continue' symbols have the following + // form, see "Stabs interface", page 164: + // {.$}X{ABC}uniquepattern[.function_name][EQUIVn][.variable_name] + char c0 = rSymbol[0]; + char c1 = rSymbol[1]; + char c2 = rSymbol[2]; + if ( c0 == '.' || c0 == '$' ) { + if ( c1 == 'X' ) { + if ( c2 == 'A' || c2 == 'B' || c2 == 'C' || c2 == 'D' ) { + return true; + } + } + } + return false; +} + +void adjustVisibility( const std::string& rFile, int fd, bool bVerbose) +{ + if ( bVerbose ) { + std::cout << "File: " << rFile << ": adjusting 'fix and continue' symbol visibility\n"; + } + + try { + Elf* pElf; + if ((pElf = elf_begin(fd, ELF_C_RDWR, 0)) == NULL) { + throw ElfError(rFile, "elf_begin() failed"); + } + // Check if file is ELF file. + if ( elf_kind(pElf) != ELF_K_ELF ) { + throw ElfError(rFile, "elf_kind() failed, file is not an ELF object file"); + } + + // Iterate over sections. + Elf_Scn* pScn = 0; + while ( (pScn = elf_nextscn(pElf, pScn)) != 0 ) { + GElf_Shdr aShdr; + if ( gelf_getshdr(pScn, &aShdr) == 0 ) { + throw ElfError(rFile, "gelf_getshdr() failed"); + } + if ( aShdr.sh_type != SHT_SYMTAB ) { + continue; + } + // Section is a symbol section. Get the assiociated data. + Elf_Data* pSymbolData; + if ( (pSymbolData = elf_getdata(pScn, 0)) == NULL ) { + throw ElfError(rFile, "elf_getdata() failed"); + } + // Iterate over symbol table. + GElf_Xword nSymbols = aShdr.sh_size / aShdr.sh_entsize; + if ( nSymbols > std::numeric_limits< int >::max() ) + { + throw ElfError(rFile, "too many symbols"); + } + for ( int nIndex = 0; nIndex < nSymbols; ++nIndex) { + // Get symbol. + GElf_Sym aSymbol; + if ( gelf_getsym(pSymbolData, nIndex, &aSymbol) == NULL ) + { + throw ElfError(rFile, "gelf_getsym() failed"); + } + std::string sSymbolName(elf_strptr(pElf, aShdr.sh_link, aSymbol.st_name)); + if ( isFixAndContinueSymbol(sSymbolName) ) { + // Get the symbol visibility. + unsigned int nSymbolVisibility = GELF_ST_VISIBILITY(aSymbol.st_other); + if ( bVerbose ) { + // Get the symbol type and binding. + unsigned int nSymbolType = GELF_ST_TYPE(aSymbol.st_info); + unsigned int nSymbolBind = GELF_ST_BIND(aSymbol.st_info); + std::cout << "Symbol: " << sSymbolName << ", " + << "Type: "; + if ( SymbolType[nSymbolType] ) { + std::cout << SymbolType[nSymbolType]; + } else { + std::cout << nSymbolType; + } + std::cout << ", Binding: "; + if ( SymbolBinding[nSymbolBind] ) { + std::cout << SymbolBinding[nSymbolBind]; + } else { + std::cout << nSymbolBind; + } + std::cout << ", Visibility: "; + if ( SymbolVisibility[nSymbolVisibility] ) { + std::cout << SymbolVisibility[nSymbolVisibility]; + } else { + std::cout << nSymbolVisibility; + } + std::cout << "-> " << SymbolVisibility[STV_HIDDEN] << "\n"; + } + // Toggle visibility to "hidden". + aSymbol.st_other = GELF_ST_VISIBILITY(STV_HIDDEN); + // Write back symbol data to underlying structure. + if ( gelf_update_sym(pSymbolData, nIndex, &aSymbol) == NULL ) + { + throw ElfError(rFile, "gelf_update_sym() failed"); + } + } + } + } + // Write changed object file to disk. + if ( elf_update(pElf, ELF_C_WRITE) == -1 ) { + throw ElfError(rFile, "elf_update() failed"); + } + elf_end(pElf); + + } catch (ElfError& e) { + close(fd); + throw; + } + return; +} + +void processObject(const std::string& rFile, bool bPreserve, bool bVerbose) +{ + int fd; + struct stat aStatBuf; + + if ((fd = open(rFile.c_str(), O_RDWR)) == -1) { + std::string sMessage("adjustVisibilty() failed: can't open file "); + sMessage += rFile; + sMessage += ": "; + sMessage += std::strerror(errno); + throw std::runtime_error(sMessage); + } + + if ( bPreserve ) { + if ( fstat(fd, &aStatBuf) == -1) { + std::string sMessage("adjustVisibilty() failed: can't stat file "); + sMessage += rFile; + sMessage += ": "; + sMessage += std::strerror(errno); + throw std::runtime_error(sMessage); + } + } + + adjustVisibility(rFile, fd, bVerbose); + + close(fd); + + if ( bPreserve ) { + struct utimbuf aUtimBuf = {aStatBuf.st_atime, aStatBuf.st_mtime}; + if ( utime(rFile.c_str(), &aUtimBuf) == -1 ) { + std::string sMessage("adjustVisibilty() failed: can't reset timestamp "); + sMessage += rFile; + sMessage += ": "; + sMessage += std::strerror(errno); + throw std::runtime_error(sMessage); + } + } + return; +} + +int main(int argc, char* argv[]) +{ + int c; + bool bPreserve = false; + bool bVerbose = false; + + while ( (c = getopt(argc, argv, "pv")) != -1 ) { + switch(c) { + case 'p': + bPreserve = true; + break; + case 'v': + bVerbose = true; + break; + case '?': + std::cerr << "Unrecognized option: -" << optopt << "\n"; + break; + default: + break; + } + } + + if ( optind == argc ) { + std::cout << "usage: " << argv[0] << " [-pv] <elf-object> ...\n"; + std::cout << " -p preserve time stamps\n"; + std::cout << " -v verbose\n"; + return 1; + } + + try { + initElfLib(); + + for ( ; optind < argc; optind++ ) { + processObject(std::string(argv[optind]), bPreserve, bVerbose); + } + + } catch (std::exception& e) { + std::cerr << argv[0] << ": " << e.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/soltools/adjustvisibility/makefile.mk b/soltools/adjustvisibility/makefile.mk new file mode 100644 index 000000000000..ea0d09c2cf96 --- /dev/null +++ b/soltools/adjustvisibility/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=adjustvisibility +TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE +noadjust=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +# This tool is for Solaris only +.IF "$(OS)"=="SOLARIS" + +APP1TARGET = adjustvisibility +APP1OBJS = $(OBJ)$/adjustvisibility.obj +DEPOBJFILES = $(APP1OBJ) +APP1STDLIBS = -lelf +APP1RPATH = NONE + +#APP1STDLIBS+=-lstlport +APP1STDLIBS+=-lCstd + +.ENDIF "$(OS)"=="SOLARIS" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/checkdll/checkdll.c b/soltools/checkdll/checkdll.c new file mode 100644 index 000000000000..7c5473fb2510 --- /dev/null +++ b/soltools/checkdll/checkdll.c @@ -0,0 +1,97 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <dlfcn.h> + +/* + * NOTE: Since no one is really interested in correct unload behavior I've + * disabled the shared library unload check. If you want to reenable it comment + * the following line out + */ +#define NO_UNLOAD_CHECK + +static const char *pprog_name = "checkdll"; +static const char *psymbol = "GetVersionInfo"; + +void usage() +{ + fprintf(stderr, "usage: %s [-s] <dllname>\n", pprog_name); + return; +} + +int main(int argc, char *argv[]) +{ + int rc; + int silent=0; + void *phandle; + char *(*pfun)(void); + + if ( argc < 2 || argc > 4) { + usage(); + return 1; + } + + if ( !strcmp(argv[1],"-s") ) { + silent = 1; + ++argv, --argc; + } + + if ( (rc = access( argv[1], R_OK )) == -1 ) { + fprintf(stderr, "%s: ERROR: %s: %s\n", + pprog_name, argv[1], strerror(errno)); + return 2; + } + + if (!silent) printf("Checking DLL %s ...", argv[1]); + fflush(stdout); + + if ( (phandle = dlopen(argv[1], RTLD_NOW)) != NULL ) { + if ( (pfun = (char *(*)(void))dlsym(phandle, psymbol)) != NULL ) { + if (!silent) printf(": ok\n"); + } + else + { + printf(": WARNING: %s\n", dlerror()); + } +#ifdef NO_UNLOAD_CHECK + _exit(0); +#else + dlclose(phandle); +#endif + return 0; + } + + printf(": ERROR: %s\n", dlerror()); + return 3; +} + + diff --git a/soltools/checkdll/makefile.mk b/soltools/checkdll/makefile.mk new file mode 100644 index 000000000000..fc09a566005e --- /dev/null +++ b/soltools/checkdll/makefile.mk @@ -0,0 +1,58 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=checkdll +TARGETTYPE=CUI +NO_DEFAULT_STL=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + + +.IF "$(GUI)"=="UNX" +LIBSALCPPRT=$(0) +APP1TARGET = checkdll +APP1OBJS = $(OBJ)$/checkdll.obj +DEPOBJFILES = $(APP1OBJS) +.IF "$(OS)"!="FREEBSD" && "$(OS)"!="MACOSX" && "$(OS)"!="NETBSD" +STDLIB += -ldl +.ENDIF +.IF "$(OS)"=="NETBSD" +APP1STDLIBS += -Wl,--whole-archive -lgcc -Wl,--no-whole-archive +.ENDIF +.ENDIF # "$(GUI)"=="UNX" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/cpp/Test.txt b/soltools/cpp/Test.txt new file mode 100644 index 000000000000..62c1ae40f218 --- /dev/null +++ b/soltools/cpp/Test.txt @@ -0,0 +1,101 @@ + +#define ABC \ + ggg + +ABC + +/* Standards --------------------------------------------------------------- */ + +#define NOTHING +NOTHING + +#define SYMBOL symbol +#undef SYMBOL +#define SYMBOL _symbol_ + +< SYMBOL > // < _symbol_ > +xSYMBOLx // xSYMBOLx ++SYMBOL- // +_symbol_- +>SYMBOL< // >_symbol_< +<SYMBOL> // <_symbol_> + +#define FALSE 0 +#define TRUE !FALSE +a = x > 0 ? TRUE : FALSE // a = x > 0 ? !0 : 0 + +#define A x +#define B y +#define MAC(a, b) \ + T() { a(); return b; } // T() { x(); return y; } +MAC(A,B); + +#ifdef MAC +MAC(X,Y) +#endif // MAC + +/* Recursions -------------------------------------------------------------- */ + +#define y x +#define x y +x // x + +#define Test(a) a +#define b Test(b) +a = b; // a = b; + +#define func abc(func) +a = func // a = abc(func) + +#define func1 func(abc) +a = func1 // a = abc(func)(abc) + +#define args(func, args) func args +args(t1, (args(t2, (x, y)))) // t1 (t2 (x, y)) + +#define ARGS(a) a +#define __ ARGS +int foo __((int x)); // int foo (int x); + +/* Concatinations ---------------------------------------------------------- */ + +#define tail _Test +// Txt_##tail // Txt_##_Test + +#define z(e,f) e##_##f +z ( abc, xyz ) // abc_xyz + + +#define CAT( var ) fix##.var +CAT( a ) // fix.a + +#define CAT3( class, ref ) class##ref::class##ref +CAT3( a, b ) // ab::ab + +#define CAT2( var ) fix##var::fix##var +CAT2( a ) // fixa::fixa + +/* Extrems ----------------------------------------------------------------- */ + +#define MAKE_X( name ) name##_Test +#define MAKE_Y( name ) MAKE_X( name##_Sym ) +MAKE_Y( Txt ); // Txt_Sym_Test; + + +/* Extensions -------------------------------------------------------------- */ + +/* +#ident "(c)# Test.txt" + +#if #machine(i386) +# error illegal machine +#endif +char machine[6]; +*/ + +/* Last bug ----------------------------------------------------------------- */ +#define Cfstrcpy Cstrcpy +#define Cstrcpy( s1, s2 ) strcpy( s1, s2 ) + +Cfstrcpy(Par1,Par2 ) // blub( Par1, Par2 ) + +/* ---------------------------------------------------------------------- */ diff --git a/soltools/cpp/_cpp.c b/soltools/cpp/_cpp.c new file mode 100644 index 000000000000..134bf0075cf2 --- /dev/null +++ b/soltools/cpp/_cpp.c @@ -0,0 +1,383 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <stdarg.h> +#include "cpp.h" + +#define OUTS 16384 +char outbuf[OUTS]; +char *outptr = outbuf; +Source *cursource; +int nerrs; +struct token nltoken = {NL, 0, 0, 1, (uchar *) "\n", 0}; +char *curtime; +int incdepth; +int ifdepth; +int ifsatisfied[NIF]; +int skipping; + +char rcsid[] = "$Version 1.2 $ $Revision: 1.5 $ $Date: 2006-06-20 05:05:46 $"; + +int +#ifdef _WIN32 +__cdecl +#endif // _WIN32 + main(int argc, char **argv) +{ + + Tokenrow tr; + time_t t; + char ebuf[BUFSIZ]; + + setbuf(stderr, ebuf); + t = time(NULL); + curtime = ctime(&t); + maketokenrow(3, &tr); + expandlex(); + setup(argc, argv); + fixlex(); + if (!Pflag) + genline(); + process(&tr); + flushout(); + fflush(stderr); + exit(nerrs > 0); +} + +void + process(Tokenrow * trp) +{ + int anymacros = 0; + + for (;;) + { + if (trp->tp >= trp->lp) + { + trp->tp = trp->lp = trp->bp; + outptr = outbuf; + anymacros |= gettokens(trp, 1); + trp->tp = trp->bp; + } + if (trp->tp->type == END) + { + if (--incdepth >= 0) + { + if (cursource->ifdepth) + error(ERROR, + "Unterminated conditional in #include"); + unsetsource(); + cursource->line += cursource->lineinc; + trp->tp = trp->lp; + if (!Pflag) + genline(); + continue; + } + if (ifdepth) + error(ERROR, "Unterminated #if/#ifdef/#ifndef"); + break; + } + if (trp->tp->type == SHARP) + { + trp->tp += 1; + control(trp); + } + else + if (!skipping && anymacros) + expandrow(trp, NULL); + if (skipping) + setempty(trp); + puttokens(trp); + anymacros = 0; + cursource->line += cursource->lineinc; + if (cursource->lineinc > 1) + { + if (!Pflag) + genline(); + } + } +} + +void + control(Tokenrow * trp) +{ + Nlist *np; + Token *tp; + + tp = trp->tp; + if (tp->type != NAME) + { + if (tp->type == NUMBER) + goto kline; + if (tp->type != NL) + error(ERROR, "Unidentifiable control line"); + return; /* else empty line */ + } + if ((np = lookup(tp, 0)) == NULL || ((np->flag & ISKW) == 0 && !skipping)) + { + error(WARNING, "Unknown preprocessor control %t", tp); + return; + } + if (skipping) + { + switch (np->val) + { + case KENDIF: + if (--ifdepth < skipping) + skipping = 0; + --cursource->ifdepth; + setempty(trp); + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + return; + + case KELIF: + case KELSE: + if (ifdepth <= skipping) + break; + return; + + default: + return; + } + } + switch (np->val) + { + case KDEFINE: + dodefine(trp); + break; + + case KUNDEF: + tp += 1; + if (tp->type != NAME || trp->lp - trp->bp != 4) + { + error(ERROR, "Syntax error in #undef"); + break; + } + if ((np = lookup(tp, 0)) != NULL) + { + np->flag &= ~ISDEFINED; + + if (Mflag) + { + if (np->ap) + error(INFO, "Macro deletion of %s(%r)", np->name, np->ap); + else + error(INFO, "Macro deletion of %s", np->name); + } + } + break; + + case KPRAGMA: + case KIDENT: + for (tp = trp->tp - 1; ((tp->type != NL) && (tp < trp->lp)); tp++) + tp->type = UNCLASS; + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + ifsatisfied[ifdepth] = 0; + if (eval(trp, np->val)) + ifsatisfied[ifdepth] = 1; + else + skipping = ifdepth; + break; + + case KELIF: + if (ifdepth == 0) + { + error(ERROR, "#elif with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#elif after #else"); + if (eval(trp, np->val)) + { + if (ifsatisfied[ifdepth]) + skipping = ifdepth; + else + { + skipping = 0; + ifsatisfied[ifdepth] = 1; + } + } + else + skipping = ifdepth; + break; + + case KELSE: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#else with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#else after #else"); + if (trp->lp - trp->bp != 3) + error(ERROR, "Syntax error in #else"); + skipping = ifsatisfied[ifdepth] ? ifdepth : 0; + ifsatisfied[ifdepth] = 2; + break; + + case KENDIF: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#endif with no #if"); + return; + } + --ifdepth; + --cursource->ifdepth; + if (trp->lp - trp->bp != 3) + error(WARNING, "Syntax error in #endif"); + break; + + case KERROR: + trp->tp = tp + 1; + error(WARNING, "#error directive: %r", trp); + break; + + case KLINE: + trp->tp = tp + 1; + expandrow(trp, "<line>"); + tp = trp->bp + 2; + kline: + if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp + || (tp + 3 == trp->lp + && ((tp + 1)->type != STRING || *(tp + 1)->t == 'L'))) + { + error(ERROR, "Syntax error in #line"); + return; + } + cursource->line = atol((char *) tp->t) - 1; + if (cursource->line < 0 || cursource->line >= 32768) + error(WARNING, "#line specifies number out of range"); + tp = tp + 1; + if (tp + 1 < trp->lp) + cursource->filename = (char *) newstring(tp->t + 1, tp->len - 2, 0); + return; + + case KDEFINED: + error(ERROR, "Bad syntax for control line"); + break; + + case KIMPORT: + doinclude(trp, -1, 1); + trp->lp = trp->bp; + return; + + case KINCLUDE: + doinclude(trp, -1, 0); + trp->lp = trp->bp; + return; + + case KINCLUDENEXT: + doinclude(trp, cursource->pathdepth, 0); + trp->lp = trp->bp; + return; + + case KEVAL: + eval(trp, np->val); + break; + + default: + error(ERROR, "Preprocessor control `%t' not yet implemented", tp); + break; + } + setempty(trp); + return; +} + +void * + domalloc(int size) +{ + void *p = malloc(size); + + if (p == NULL) + error(FATAL, "Out of memory from malloc"); + return p; +} + +void + dofree(void *p) +{ + free(p); +} + +void + error(enum errtype type, char *string,...) +{ + va_list ap; + char c, *cp, *ep; + Token *tp; + Tokenrow *trp; + Source *s; + int i; + + fprintf(stderr, "cpp: "); + for (s = cursource; s; s = s->next) + if (*s->filename) + fprintf(stderr, "%s:%d ", s->filename, s->line); + va_start(ap, string); + for (ep = string; *ep; ep++) + { + if (*ep == '%') + { + switch (*++ep) + { + + case 'c': + c = (char) va_arg(ap, int); + fprintf(stderr, "%c", c); + break; + + case 's': + cp = va_arg(ap, char *); + fprintf(stderr, "%s", cp); + break; + + case 'd': + i = va_arg(ap, int); + fprintf(stderr, "%d", i); + break; + + case 't': + tp = va_arg(ap, Token *); + fprintf(stderr, "%.*s", (int)tp->len, tp->t); + break; + + case 'r': + trp = va_arg(ap, Tokenrow *); + for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++) + { + if (tp > trp->tp && tp->wslen) + fputc(' ', stderr); + fprintf(stderr, "%.*s", (int)tp->len, tp->t); + } + break; + + default: + fputc(*ep, stderr); + break; + } + } + else + fputc(*ep, stderr); + } + va_end(ap); + fputc('\n', stderr); + if (type == FATAL) + exit(1); + if (type != WARNING) + nerrs = 1; + fflush(stderr); +} diff --git a/soltools/cpp/_eval.c b/soltools/cpp/_eval.c new file mode 100644 index 000000000000..a652e488d78f --- /dev/null +++ b/soltools/cpp/_eval.c @@ -0,0 +1,766 @@ +#include <stdlib.h> +#include <string.h> +#include "cpp.h" + +#define NSTAK 32 +#define SGN 0 +#define UNS 1 +#define UND 2 + +#define UNSMARK 0x1000 + +struct value +{ + long val; + int type; +}; + +/* conversion types */ +#define RELAT 1 +#define ARITH 2 +#define LOGIC 3 +#define SPCL 4 +#define SHIFT 5 +#define UNARY 6 + +/* operator priority, arity, and conversion type, indexed by tokentype */ +struct pri +{ + char pri; + char arity; + char ctype; +} priority[] = + +{ + { + 0, 0, 0 + }, /* END */ + { + 0, 0, 0 + }, /* UNCLASS */ + { + 0, 0, 0 + }, /* NAME */ + { + 0, 0, 0 + }, /* NUMBER */ + { + 0, 0, 0 + }, /* STRING */ + { + 0, 0, 0 + }, /* CCON */ + { + 0, 0, 0 + }, /* NL */ + { + 0, 0, 0 + }, /* WS */ + { + 0, 0, 0 + }, /* DSHARP */ + { + 11, 2, RELAT + }, /* EQ */ + { + 11, 2, RELAT + }, /* NEQ */ + { + 12, 2, RELAT + }, /* LEQ */ + { + 12, 2, RELAT + }, /* GEQ */ + { + 13, 2, SHIFT + }, /* LSH */ + { + 13, 2, SHIFT + }, /* RSH */ + { + 7, 2, LOGIC + }, /* LAND */ + { + 6, 2, LOGIC + }, /* LOR */ + { + 0, 0, 0 + }, /* PPLUS */ + { + 0, 0, 0 + }, /* MMINUS */ + { + 0, 0, 0 + }, /* ARROW */ + { + 0, 0, 0 + }, /* SBRA */ + { + 0, 0, 0 + }, /* SKET */ + { + 3, 0, 0 + }, /* LP */ + { + 3, 0, 0 + }, /* RP */ + { + 0, 0, 0 + }, /* DOT */ + { + 10, 2, ARITH + }, /* AND */ + { + 15, 2, ARITH + }, /* STAR */ + { + 14, 2, ARITH + }, /* PLUS */ + { + 14, 2, ARITH + }, /* MINUS */ + { + 16, 1, UNARY + }, /* TILDE */ + { + 16, 1, UNARY + }, /* NOT */ + { + 15, 2, ARITH + }, /* SLASH */ + { + 15, 2, ARITH + }, /* PCT */ + { + 12, 2, RELAT + }, /* LT */ + { + 12, 2, RELAT + }, /* GT */ + { + 9, 2, ARITH + }, /* CIRC */ + { + 8, 2, ARITH + }, /* OR */ + { + 5, 2, SPCL + }, /* QUEST */ + { + 5, 2, SPCL + }, /* COLON */ + { + 0, 0, 0 + }, /* ASGN */ + { + 4, 2, 0 + }, /* COMMA */ + { + 0, 0, 0 + }, /* SHARP */ + { + 0, 0, 0 + }, /* SEMIC */ + { + 0, 0, 0 + }, /* CBRA */ + { + 0, 0, 0 + }, /* CKET */ + { + 0, 0, 0 + }, /* ASPLUS */ + { + 0, 0, 0 + }, /* ASMINUS */ + { + 0, 0, 0 + }, /* ASSTAR */ + { + 0, 0, 0 + }, /* ASSLASH */ + { + 0, 0, 0 + }, /* ASPCT */ + { + 0, 0, 0 + }, /* ASCIRC */ + { + 0, 0, 0 + }, /* ASLSH */ + { + 0, 0, 0 + }, /* ASRSH */ + { + 0, 0, 0 + }, /* ASOR */ + { + 0, 0, 0 + }, /* ASAND */ + { + 0, 0, 0 + }, /* ELLIPS */ + { + 0, 0, 0 + }, /* DSHARP1 */ + { + 0, 0, 0 + }, /* NAME1 */ + { + 0, 0, 0 + }, /* NAME2 */ + { + 16, 1, UNARY + }, /* DEFINED */ + { + 16, 0, UNARY + }, /* UMINUS */ + { + 16, 1, UNARY + }, /* ARCHITECTURE */ +}; + +int evalop(struct pri); +struct value tokval(Token *); +struct value vals[NSTAK], *vp; +enum toktype ops[NSTAK], *op; + +/* + * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. + */ +long + eval(Tokenrow * trp, int kw) +{ + Token *tp; + Nlist *np; + int ntok, rnd; + + trp->tp++; + if (kw == KIFDEF || kw == KIFNDEF) + { + if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) + { + error(ERROR, "Syntax error in #ifdef/#ifndef"); + return 0; + } + np = lookup(trp->tp, 0); + return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC)); + } + ntok = trp->tp - trp->bp; + kwdefined->val = KDEFINED; /* activate special meaning of + * defined */ + expandrow(trp, "<if>"); + kwdefined->val = NAME; + vp = vals; + op = ops; + *op++ = END; + for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) + { + switch (tp->type) + { + case WS: + case NL: + continue; + + /* nilary */ + case NAME: + case NAME1: + case NAME2: + case NUMBER: + case CCON: + case STRING: + if (rnd) + goto syntax; + *vp++ = tokval(tp); + rnd = 1; + continue; + + /* unary */ + case DEFINED: + case TILDE: + case NOT: + if (rnd) + goto syntax; + *op++ = tp->type; + continue; + + /* unary-binary */ + case PLUS: + case MINUS: + case STAR: + case AND: + if (rnd == 0) + { + if (tp->type == MINUS) + *op++ = UMINUS; + if (tp->type == STAR || tp->type == AND) + { + error(ERROR, "Illegal operator * or & in #if/#elsif"); + return 0; + } + continue; + } + /* flow through */ + + /* plain binary */ + case EQ: + case NEQ: + case LEQ: + case GEQ: + case LSH: + case RSH: + case LAND: + case LOR: + case SLASH: + case PCT: + case LT: + case GT: + case CIRC: + case OR: + case QUEST: + case COLON: + case COMMA: + if (rnd == 0) + goto syntax; + if (evalop(priority[tp->type]) != 0) + return 0; + *op++ = tp->type; + rnd = 0; + continue; + + case LP: + if (rnd) + goto syntax; + *op++ = LP; + continue; + + case RP: + if (!rnd) + goto syntax; + if (evalop(priority[RP]) != 0) + return 0; + if (op <= ops || op[-1] != LP) + { + goto syntax; + } + op--; + continue; + + case SHARP: + if ((tp + 1) < trp->lp) + { + np = lookup(tp + 1, 0); + if (np && (np->val == KMACHINE)) + { + tp++; + if (rnd) + goto syntax; + *op++ = ARCHITECTURE; + continue; + } + } + /* fall through */ + + default: + error(ERROR, "Bad operator (%t) in #if/#elsif", tp); + return 0; + } + } + if (rnd == 0) + goto syntax; + if (evalop(priority[END]) != 0) + return 0; + if (op != &ops[1] || vp != &vals[1]) + { + error(ERROR, "Botch in #if/#elsif"); + return 0; + } + if (vals[0].type == UND) + error(ERROR, "Undefined expression value"); + return vals[0].val; +syntax: + error(ERROR, "Syntax error in #if/#elsif"); + return 0; +} + +int + evalop(struct pri pri) +{ + struct value v1; + struct value v2 = { 0, UND }; + long rv1, rv2; + int rtype, oper; + + rv2 = 0; + rtype = 0; + while (pri.pri < priority[op[-1]].pri) + { + oper = *--op; + if (priority[oper].arity == 2) + { + v2 = *--vp; + rv2 = v2.val; + } + v1 = *--vp; + rv1 = v1.val; +/*lint -e574 -e644 */ + switch (priority[oper].ctype) + { + case 0: + default: + error(WARNING, "Syntax error in #if/#endif"); + return 1; + case ARITH: + case RELAT: + if (v1.type == UNS || v2.type == UNS) + rtype = UNS; + else + rtype = SGN; + if (v1.type == UND || v2.type == UND) + rtype = UND; + if (priority[oper].ctype == RELAT && rtype == UNS) + { + oper |= UNSMARK; + rtype = SGN; + } + break; + case SHIFT: + if (v1.type == UND || v2.type == UND) + rtype = UND; + else + rtype = v1.type; + if (rtype == UNS) + oper |= UNSMARK; + break; + case UNARY: + rtype = v1.type; + break; + case LOGIC: + case SPCL: + break; + } + switch (oper) + { + case EQ: + case EQ | UNSMARK: + rv1 = rv1 == rv2; + break; + case NEQ: + case NEQ | UNSMARK: + rv1 = rv1 != rv2; + break; + case LEQ: + rv1 = rv1 <= rv2; + break; + case GEQ: + rv1 = rv1 >= rv2; + break; + case LT: + rv1 = rv1 < rv2; + break; + case GT: + rv1 = rv1 > rv2; + break; + case LEQ | UNSMARK: + rv1 = (unsigned long)rv1 <= (unsigned long)rv2; + break; + case GEQ | UNSMARK: + rv1 = (unsigned long)rv1 >= (unsigned long)rv2; + break; + case LT | UNSMARK: + rv1 = (unsigned long)rv1 < (unsigned long)rv2; + break; + case GT | UNSMARK: + rv1 = (unsigned long)rv1 > (unsigned long)rv2; + break; + case LSH: + rv1 <<= rv2; + break; + case LSH | UNSMARK: + rv1 = (unsigned long) rv1 << rv2; + break; + case RSH: + rv1 >>= rv2; + break; + case RSH | UNSMARK: + rv1 = (unsigned long) rv1 >> rv2; + break; + case LAND: + rtype = UND; + if (v1.type == UND) + break; + if (rv1 != 0) + { + if (v2.type == UND) + break; + rv1 = rv2 != 0; + } + else + rv1 = 0; + rtype = SGN; + break; + case LOR: + rtype = UND; + if (v1.type == UND) + break; + if (rv1 == 0) + { + if (v2.type == UND) + break; + rv1 = rv2 != 0; + } + else + rv1 = 1; + rtype = SGN; + break; + case AND: + rv1 &= rv2; + break; + case STAR: + rv1 *= rv2; + break; + case PLUS: + rv1 += rv2; + break; + case MINUS: + rv1 -= rv2; + break; + case UMINUS: + if (v1.type == UND) + rtype = UND; + rv1 = -rv1; + break; + case OR: + rv1 |= rv2; + break; + case CIRC: + rv1 ^= rv2; + break; + case TILDE: + rv1 = ~rv1; + break; + case NOT: + rv1 = !rv1; + if (rtype != UND) + rtype = SGN; + break; + case SLASH: + if (rv2 == 0) + { + rtype = UND; + break; + } + if (rtype == UNS) + rv1 /= (unsigned long) rv2; + else + rv1 /= rv2; + break; + case PCT: + if (rv2 == 0) + { + rtype = UND; + break; + } + if (rtype == UNS) + rv1 %= (unsigned long) rv2; + else + rv1 %= rv2; + break; + case COLON: + if (op[-1] != QUEST) + error(ERROR, "Bad ?: in #if/endif"); + else + { + op--; + if ((--vp)->val == 0) + v1 = v2; + rtype = v1.type; + rv1 = v1.val; + } + break; + + case DEFINED: + case ARCHITECTURE: + break; + + default: + error(ERROR, "Eval botch (unknown operator)"); + return 1; + } +/*lint +e574 +e644 */ + v1.val = rv1; + v1.type = rtype; + *vp++ = v1; + } + return 0; +} + +struct value + tokval(Token * tp) +{ + struct value v; + Nlist *np; + int i, base; + unsigned long n; + uchar *p, c; + + v.type = SGN; + v.val = 0; + switch (tp->type) + { + + case NAME: + v.val = 0; + break; + + case NAME1: + if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC)) + v.val = 1; + break; + + case NAME2: + if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE)) + v.val = 1; + break; + + case NUMBER: + n = 0; + base = 10; + p = tp->t; + c = p[tp->len]; + p[tp->len] = '\0'; + if (*p == '0') + { + base = 8; + if (p[1] == 'x' || p[1] == 'X') + { + base = 16; + p++; + } + p++; + } + for (;; p++) + { + if ((i = digit(*p)) < 0) + break; + if (i >= base) + error(WARNING, + "Bad digit in number %t", tp); + n *= base; + n += i; + } + if (n >= 0x80000000 && base != 10) + v.type = UNS; + for (; *p; p++) + { + if (*p == 'u' || *p == 'U') + v.type = UNS; + else + if (*p == 'l' || *p == 'L') + ; + else + { + error(ERROR, + "Bad number %t in #if/#elsif", tp); + break; + } + } + v.val = n; + tp->t[tp->len] = c; + break; + + case CCON: + n = 0; + p = tp->t; + if (*p == 'L') + { + p += 1; + error(WARNING, "Wide char constant value undefined"); + } + p += 1; + if (*p == '\\') + { + p += 1; + if ((i = digit(*p)) >= 0 && i <= 7) + { + n = i; + p += 1; + if ((i = digit(*p)) >= 0 && i <= 7) + { + p += 1; + n <<= 3; + n += i; + if ((i = digit(*p)) >= 0 && i <= 7) + { + p += 1; + n <<= 3; + n += i; + } + } + } + else + if (*p == 'x') + { + p += 1; + while ((i = digit(*p)) >= 0 && i <= 15) + { + p += 1; + n <<= 4; + n += i; + } + } + else + { + static char cvcon[] + = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; + size_t j; + + for (j = 0; j < sizeof(cvcon); j += 2) + { + if (*p == cvcon[j]) + { + n = cvcon[j + 1]; + break; + } + } + p += 1; + if (j >= sizeof(cvcon)) + error(WARNING, + "Undefined escape in character constant"); + } + } + else + if (*p == '\'') + error(ERROR, "Empty character constant"); + else + n = *p++; + if (*p != '\'') + error(WARNING, "Multibyte character constant undefined"); + else + if (n > 127) + error(WARNING, "Character constant taken as not signed"); + v.val = n; + break; + + case STRING: + error(ERROR, "String in #if/#elsif"); + break; + } + return v; +} + +int + digit(int i) +{ + if ('0' <= i && i <= '9') + i -= '0'; + else + if ('a' <= i && i <= 'f') + i -= 'a' - 10; + else + if ('A' <= i && i <= 'F') + i -= 'A' - 10; + else + i = -1; + return i; +} diff --git a/soltools/cpp/_getopt.c b/soltools/cpp/_getopt.c new file mode 100644 index 000000000000..589638936efb --- /dev/null +++ b/soltools/cpp/_getopt.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <string.h> + +#define EPR fprintf(stderr, +#define ERR(str, chr) if(opterr) { EPR "%s%c\n", str, chr); } + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int + stgetopt(int argc, char *const argv[], const char *opts) +{ + static int sp = 1; + register int c; + register char *cp; + + if (sp == 1) + { + if (optind >= argc || + argv[optind][0] != '-' || argv[optind][1] == '\0') + return -1; + else if (strcmp(argv[optind], "--") == 0) + { + optind++; + return -1; + } + else if (strcmp(argv[optind], "-isysroot") == 0) + { + // skip Mac OS X SDK selection flags + optind++; optind++; + } + } + optopt = c = argv[optind][sp]; + if (c == ':' || (cp = strchr(opts, c)) == 0) + { + ERR(": illegal option -- ", c); + if (argv[optind][++sp] == '\0') + { + optind++; + sp = 1; + } + return '?'; + } + if (*++cp == ':') + { + if (argv[optind][sp + 1] != '\0') + optarg = &argv[optind++][sp + 1]; + else + if (++optind >= argc) + { + ERR(": option requires an argument -- ", c); + sp = 1; + return '?'; + } + else + optarg = argv[optind++]; + sp = 1; + } + else + { + if (argv[optind][++sp] == '\0') + { + sp = 1; + optind++; + } + optarg = 0; + } + return c; +} diff --git a/soltools/cpp/_include.c b/soltools/cpp/_include.c new file mode 100644 index 000000000000..da2bf03c8ff4 --- /dev/null +++ b/soltools/cpp/_include.c @@ -0,0 +1,235 @@ +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +# include <io.h> +#else +# include <unistd.h> +#endif + +#ifdef _MSC_VER +# define _POSIX_ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> + + +#ifdef __hpux +# define _HPUX_SOURCE +#endif +#if defined(__IBMC__) || defined(__EMX__) +# include <fcntl.h> +# define PATH_MAX _MAX_PATH +#endif +#include <limits.h> + +#include "cpp.h" + +Includelist includelist[NINCLUDE]; +Wraplist wraplist[NINCLUDE]; + +void + doinclude(Tokenrow * trp, int depth, int import) +{ + char fname[PATH_MAX], iname[PATH_MAX]; + Includelist *ip; + int angled, fd, i; + size_t len; + + trp->tp += 1; + if (trp->tp >= trp->lp) + goto syntax; + if (trp->tp->type != STRING && trp->tp->type != LT) + { + len = trp->tp - trp->bp; + expandrow(trp, "<include>"); + trp->tp = trp->bp + len; + } + if (trp->tp->type == STRING) + { + len = trp->tp->len - 2; + if (len > sizeof(fname) - 1) + len = sizeof(fname) - 1; + strncpy(fname, (char *) trp->tp->t + 1, len); + angled = 0; + } + else + { + if (trp->tp->type == LT) + { + len = 0; + trp->tp++; + while (trp->tp->type != GT) + { + if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname)) + goto syntax; + strncpy(fname + len, (char *) trp->tp->t, trp->tp->len); + len += trp->tp->len; + trp->tp++; + } + angled = 1; + } + else + goto syntax; + } + trp->tp += 2; + if (trp->tp < trp->lp || len == 0) + goto syntax; + fname[len] = '\0'; + if (fname[0] == '/') + { + fd = open(fname, O_RDONLY); + strcpy(iname, fname); + } + else + { + for (fd = -1, i = (depth < 0) ? (NINCLUDE - 1) : (depth - 1); i >= 0; i--) + { + ip = &includelist[i]; + if (ip->file == NULL || ip->deleted || (angled && ip->always == 0)) + continue; + if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname)) + continue; + strcpy(iname, ip->file); + strcat(iname, "/"); + strcat(iname, fname); + if ((fd = open(iname, O_RDONLY)) >= 0) + break; + } + } + + if (fd >= 0) + { + if (++incdepth > NINC ) + error(FATAL, "#%s too deeply nested", import ? "import" : "include"); + if (Xflag) + genimport(fname, angled, iname, import); + if (Iflag) + error(INFO, "Open %s file [%s]", import ? "import" : "include", iname ); + + for (i = NINCLUDE - 1; i >= 0; i--) + { + if ((wraplist[i].file != NULL) && + (strncmp(wraplist[i].file, iname, strlen(wraplist[i].file)) == 0)) + break; + } + + setsource((char *) newstring((uchar *) iname, strlen(iname), 0), i, fd, NULL, (i >= 0) ? 1 : 0); + + if (!Pflag) + genline(); + } + else + { + trp->tp = trp->bp + 2; + error(ERROR, "Could not find %s file %r", import ? "import" : "include", trp); + } + return; +syntax: + error(ERROR, "Syntax error in #%s", import ? "import" : "include"); + return; +} + +/* + * Generate a line directive for cursource + */ +void + genline(void) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + ta.t = p = (uchar *) outptr; + strcpy((char *) p, "#line "); + p += sizeof("#line ") - 1; + p = (uchar *) outnum((char *) p, cursource->line); + *p++ = ' '; + *p++ = '"'; + if (cursource->filename[0] != '/' && wd[0]) + { + strcpy((char *) p, wd); + p += strlen(wd); + *p++ = '/'; + } + strcpy((char *) p, cursource->filename); + p += strlen((char *) p); + *p++ = '"'; + *p++ = '\n'; + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); +} + +/* + * Generate a pragma import/include directive + */ +void + genimport(char *fname, int angled, char *iname, int import) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + ta.t = p = (uchar *) outptr; + + if (import) + strcpy((char *) p, "#pragma import"); + else + strcpy((char *) p, "#pragma include"); + + p += strlen((char *) p); + + *p++ = '('; + + *p++ = angled ? '<' : '"'; + strcpy((char *) p, fname); + p += strlen(fname); + *p++ = angled ? '>' : '"'; + + *p++ = ','; + + *p++ = '"'; + strcpy((char *) p, iname); + p += strlen(iname); + *p++ = '"'; + + *p++ = ')'; + *p++ = '\n'; + + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); +} + +/* + * Generate a extern C directive + */ +void + genwrap(int end) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + if (Cplusplus) + { + ta.t = p = (uchar *) outptr; + + if (! end) + strcpy((char *) p, "extern \"C\" {"); + else + strcpy((char *) p, "}"); + + p += strlen((char *) p); + + *p++ = '\n'; + + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); + } +} + diff --git a/soltools/cpp/_lex.c b/soltools/cpp/_lex.c new file mode 100644 index 000000000000..2ff188ff2264 --- /dev/null +++ b/soltools/cpp/_lex.c @@ -0,0 +1,688 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#else +#include <unistd.h> +#endif +#include "cpp.h" +/* + * lexical FSM encoding + * when in state state, and one of the characters + * in ch arrives, enter nextstate. + * States >= S_SELF are either final, or at least require special action. + * In 'fsm' there is a line for each state X charset X nextstate. + * List chars that overwrite previous entries later (e.g. C_ALPH + * can be overridden by '_' by a later entry; and C_XX is the + * the universal set, and should always be first. + * States above S_SELF are represented in the big table as negative values. + * S_SELF and S_SELFB encode the resulting token type in the upper bits. + * These actions differ in that S_SELF doesn't have a lookahead char, + * S_SELFB does. + * + * The encoding is blown out into a big table for time-efficiency. + * Entries have + * nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits. + */ + +#define MAXSTATE 32 +#define ACT(tok,act) ((tok<<7)+act) +#define QBSBIT 0100 +#define GETACT(st) ((st>>7)&0x1ff) + +/* character classes */ +#define C_WS 1 +#define C_ALPH 2 +#define C_NUM 3 +#define C_EOF 4 +#define C_XX 5 + +enum state +{ + START = 0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4, + CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1, + CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1, + S_SELF = MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR, + S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME +}; + +int tottok; +int tokkind[256]; +struct fsm +{ + int state; /* if in this state */ + uchar ch[4]; /* and see one of these characters */ + int nextstate; /* enter this state if +ve */ +}; + + /*const*/ struct fsm fsm[] = { + /* start state */ + {START, {C_XX}, ACT(UNCLASS, S_SELF)}, + {START, {' ', '\t', '\v'}, WS1}, + {START, {C_NUM}, NUM1}, + {START, {'.'}, NUM3}, + {START, {C_ALPH}, ID1}, + {START, {'L'}, ST1}, + {START, {'"'}, ST2}, + {START, {'\''}, CC1}, + {START, {'/'}, COM1}, + {START, {EOFC}, S_EOF}, + {START, {'\n'}, S_NL}, + {START, {'-'}, MINUS1}, + {START, {'+'}, PLUS1}, + {START, {'<'}, LT1}, + {START, {'>'}, GT1}, + {START, {'='}, ASG1}, + {START, {'!'}, NOT1}, + {START, {'&'}, AND1}, + {START, {'|'}, OR1}, + {START, {'#'}, SHARP1}, + {START, {'%'}, PCT1}, + {START, {'['}, ACT(SBRA, S_SELF)}, + {START, {']'}, ACT(SKET, S_SELF)}, + {START, {'('}, ACT(LP, S_SELF)}, + {START, {')'}, ACT(RP, S_SELF)}, + {START, {'*'}, STAR1}, + {START, {','}, ACT(COMMA, S_SELF)}, + {START, {'?'}, ACT(QUEST, S_SELF)}, + {START, {':'}, ACT(COLON, S_SELF)}, + {START, {';'}, ACT(SEMIC, S_SELF)}, + {START, {'{'}, ACT(CBRA, S_SELF)}, + {START, {'}'}, ACT(CKET, S_SELF)}, + {START, {'~'}, ACT(TILDE, S_SELF)}, + {START, {'^'}, CIRC1}, + + /* saw a digit */ + {NUM1, {C_XX}, ACT(NUMBER, S_SELFB)}, + {NUM1, {C_NUM, C_ALPH, '.'}, NUM1}, + {NUM1, {'E', 'e'}, NUM2}, + {NUM1, {'_'}, ACT(NUMBER, S_SELFB)}, + + /* saw possible start of exponent, digits-e */ + {NUM2, {C_XX}, ACT(NUMBER, S_SELFB)}, + {NUM2, {'+', '-'}, NUM1}, + {NUM2, {C_NUM, C_ALPH}, NUM1}, + {NUM2, {'_'}, ACT(NUMBER, S_SELFB)}, + + /* saw a '.', which could be a number or an operator */ + {NUM3, {C_XX}, ACT(DOT, S_SELFB)}, + {NUM3, {'.'}, DOTS1}, + {NUM3, {C_NUM}, NUM1}, + + {DOTS1, {C_XX}, ACT(UNCLASS, S_SELFB)}, + {DOTS1, {C_NUM}, NUM1}, + {DOTS1, {'.'}, ACT(ELLIPS, S_SELF)}, + + /* saw a letter or _ */ + {ID1, {C_XX}, ACT(NAME, S_NAME)}, + {ID1, {C_ALPH, C_NUM}, ID1}, + + /* saw L (start of wide string?) */ + {ST1, {C_XX}, ACT(NAME, S_NAME)}, + {ST1, {C_ALPH, C_NUM}, ID1}, + {ST1, {'"'}, ST2}, + {ST1, {'\''}, CC1}, + + /* saw " beginning string */ + {ST2, {C_XX}, ST2}, + {ST2, {'"'}, ACT(STRING, S_SELF)}, + {ST2, {'\\'}, ST3}, + {ST2, {'\n'}, S_STNL}, + {ST2, {EOFC}, S_EOFSTR}, + + /* saw \ in string */ + {ST3, {C_XX}, ST2}, + {ST3, {'\n'}, S_STNL}, + {ST3, {EOFC}, S_EOFSTR}, + + /* saw ' beginning character const */ + {CC1, {C_XX}, CC1}, + {CC1, {'\''}, ACT(CCON, S_SELF)}, + {CC1, {'\\'}, CC2}, + {CC1, {'\n'}, S_STNL}, + {CC1, {EOFC}, S_EOFSTR}, + + /* saw \ in ccon */ + {CC2, {C_XX}, CC1}, + {CC2, {'\n'}, S_STNL}, + {CC2, {EOFC}, S_EOFSTR}, + + /* saw /, perhaps start of comment */ + {COM1, {C_XX}, ACT(SLASH, S_SELFB)}, + {COM1, {'='}, ACT(ASSLASH, S_SELF)}, + {COM1, {'*'}, COM2}, + {COM1, {'/'}, COM4}, + + /* saw / followed by *, start of comment */ + {COM2, {C_XX}, COM2}, + {COM2, {'\n'}, S_COMNL}, + {COM2, {'*'}, COM3}, + {COM2, {EOFC}, S_EOFCOM}, + + /* saw the * possibly ending a comment */ + {COM3, {C_XX}, COM2}, + {COM3, {'\n'}, S_COMNL}, + {COM3, {'*'}, COM3}, + {COM3, {'/'}, S_COMMENT}, + + /* // comment */ + {COM4, {C_XX}, COM4}, + {COM4, {'\n'}, S_NL}, + {COM4, {EOFC}, S_EOFCOM}, + + /* saw white space, eat it up */ + {WS1, {C_XX}, S_WS}, + {WS1, {'\t', '\v', ' '}, WS1}, + + /* saw -, check --, -=, -> */ + {MINUS1, {C_XX}, ACT(MINUS, S_SELFB)}, + {MINUS1, {'-'}, ACT(MMINUS, S_SELF)}, + {MINUS1, {'='}, ACT(ASMINUS, S_SELF)}, + {MINUS1, {'>'}, ACT(ARROW, S_SELF)}, + + /* saw +, check ++, += */ + {PLUS1, {C_XX}, ACT(PLUS, S_SELFB)}, + {PLUS1, {'+'}, ACT(PPLUS, S_SELF)}, + {PLUS1, {'='}, ACT(ASPLUS, S_SELF)}, + + /* saw <, check <<, <<=, <= */ + {LT1, {C_XX}, ACT(LT, S_SELFB)}, + {LT1, {'<'}, LT2}, + {LT1, {'='}, ACT(LEQ, S_SELF)}, + {LT2, {C_XX}, ACT(LSH, S_SELFB)}, + {LT2, {'='}, ACT(ASLSH, S_SELF)}, + + /* saw >, check >>, >>=, >= */ + {GT1, {C_XX}, ACT(GT, S_SELFB)}, + {GT1, {'>'}, GT2}, + {GT1, {'='}, ACT(GEQ, S_SELF)}, + {GT2, {C_XX}, ACT(RSH, S_SELFB)}, + {GT2, {'='}, ACT(ASRSH, S_SELF)}, + + /* = */ + {ASG1, {C_XX}, ACT(ASGN, S_SELFB)}, + {ASG1, {'='}, ACT(EQ, S_SELF)}, + + /* ! */ + {NOT1, {C_XX}, ACT(NOT, S_SELFB)}, + {NOT1, {'='}, ACT(NEQ, S_SELF)}, + + /* & */ + {AND1, {C_XX}, ACT(AND, S_SELFB)}, + {AND1, {'&'}, ACT(LAND, S_SELF)}, + {AND1, {'='}, ACT(ASAND, S_SELF)}, + + /* | */ + {OR1, {C_XX}, ACT(OR, S_SELFB)}, + {OR1, {'|'}, ACT(LOR, S_SELF)}, + {OR1, {'='}, ACT(ASOR, S_SELF)}, + + /* # */ + {SHARP1, {C_XX}, ACT(SHARP, S_SELFB)}, + {SHARP1, {'#'}, ACT(DSHARP, S_SELF)}, + + /* % */ + {PCT1, {C_XX}, ACT(PCT, S_SELFB)}, + {PCT1, {'='}, ACT(ASPCT, S_SELF)}, + + /* * */ + {STAR1, {C_XX}, ACT(STAR, S_SELFB)}, + {STAR1, {'='}, ACT(ASSTAR, S_SELF)}, + + /* ^ */ + {CIRC1, {C_XX}, ACT(CIRC, S_SELFB)}, + {CIRC1, {'='}, ACT(ASCIRC, S_SELF)}, + + {-1, "", 0} +}; + +/* first index is char, second is state */ +/* increase #states to power of 2 to encourage use of shift */ +short bigfsm[256][MAXSTATE]; + +void + expandlex(void) +{ + /* const */ struct fsm *fp; + int i, j, nstate; + + for (fp = fsm; fp->state >= 0; fp++) + { + for (i = 0; fp->ch[i]; i++) + { + nstate = fp->nextstate; + if (nstate >= S_SELF) + nstate = ~nstate; + switch (fp->ch[i]) + { + + case C_XX: /* random characters */ + for (j = 0; j < 256; j++) + bigfsm[j][fp->state] = (short) nstate; + continue; + case C_ALPH: + for (j = 0; j <= 256; j++) +#ifdef S390 + if( isalpha( j ) || (j == '_') ) +#else + if (('a' <= j && j <= 'z') || ('A' <= j && j <= 'Z') + || j == '_') +#endif + bigfsm[j][fp->state] = (short) nstate; + continue; + case C_NUM: + for (j = '0'; j <= '9'; j++) + bigfsm[j][fp->state] = (short) nstate; + continue; + default: + bigfsm[fp->ch[i]][fp->state] = (short) nstate; + } + } + } + + /* + * install special cases for ? (trigraphs), \ (splicing), runes, and + * EOB + */ + for (i = 0; i < MAXSTATE; i++) + { + for (j = 0; j < 0xFF; j++) + if (j == '?' || j == '\\' || j == '\n' || j == '\r') + { + if (bigfsm[j][i] > 0) + bigfsm[j][i] = ~bigfsm[j][i]; + bigfsm[j][i] &= ~QBSBIT; + } + bigfsm[EOB][i] = ~S_EOB; + if (bigfsm[EOFC][i] >= 0) + bigfsm[EOFC][i] = ~S_EOF; + } +} + +void + fixlex(void) +{ + /* do C++ comments? */ + if ((Cplusplus == 0) || (Cflag != 0)) + bigfsm['/'][COM1] = bigfsm['x'][COM1]; +} + +/* + * fill in a row of tokens from input, terminated by NL or END + * First token is put at trp->lp. + * Reset is non-zero when the input buffer can be "rewound." + * The value is a flag indicating that possible macros have + * been seen in the row. + */ +int + gettokens(Tokenrow * trp, int reset) +{ + register int c, state, oldstate; + register uchar *ip; + register Token *tp, *maxp; + int runelen; + Source *s = cursource; + int nmac = 0; + + tp = trp->lp; + ip = s->inp; + if (reset) + { + s->lineinc = 0; + if (ip >= s->inl) + { /* nothing in buffer */ + s->inl = s->inb; + fillbuf(s); + ip = s->inp = s->inb; + } + else + if (ip >= s->inb + (3 * INS / 4)) + { + memmove(s->inb, ip, 4 + s->inl - ip); + s->inl = s->inb + (s->inl - ip); + ip = s->inp = s->inb; + } + } + maxp = &trp->bp[trp->max]; + runelen = 1; + for (;;) + { +continue2: + if (tp >= maxp) + { + trp->lp = tp; + tp = growtokenrow(trp); + maxp = &trp->bp[trp->max]; + } + tp->type = UNCLASS; + tp->t = ip; + tp->wslen = 0; + tp->flag = 0; + state = START; + for (;;) + { + oldstate = state; + + c = *ip; + + if ((state = bigfsm[c][state]) >= 0) + { + ip += runelen; + runelen = 1; + continue; + } + state = ~state; + reswitch: + switch (state & 0177) + { + case S_SELF: + ip += runelen; + runelen = 1; + case S_SELFB: + tp->type = (unsigned char) GETACT(state); + tp->len = ip - tp->t; + tp++; + goto continue2; + + case S_NAME: /* like S_SELFB but with nmac check */ + tp->type = NAME; + tp->len = ip - tp->t; + nmac |= quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0); + tp++; + goto continue2; + + case S_WS: + tp->wslen = ip - tp->t; + tp->t = ip; + state = START; + continue; + + default: + if ((state & QBSBIT) == 0) + { + ip += runelen; + runelen = 1; + continue; + } + state &= ~QBSBIT; + s->inp = ip; + + if (c == '\n') + { + while (s->inp + 1 >= s->inl && fillbuf(s) != EOF); + + if (s->inp[1] == '\r') + { + memmove(s->inp + 1, s->inp + 2, s->inl - s->inp + 2); + s->inl -= 1; + } + + goto reswitch; + } + + if (c == '\r') + { + while (s->inp + 1 >= s->inl && fillbuf(s) != EOF); + + if (s->inp[1] == '\n') + { + memmove(s->inp, s->inp + 1, s->inl - s->inp + 1); + s->inl -= 1; + } + else + *s->inp = '\n'; + + state = oldstate; + continue; + } + + if (c == '?') + { /* check trigraph */ + if (trigraph(s)) + { + state = oldstate; + continue; + } + goto reswitch; + } + if (c == '\\') + { /* line-folding */ + if (foldline(s)) + { + s->lineinc++; + state = oldstate; + continue; + } + goto reswitch; + } + error(WARNING, "Lexical botch in cpp"); + ip += runelen; + runelen = 1; + continue; + + case S_EOB: + s->inp = ip; + fillbuf(cursource); + state = oldstate; + continue; + + case S_EOF: + tp->type = END; + tp->len = 0; + s->inp = ip; + if (tp != trp->bp && (tp - 1)->type != NL && cursource->fd != -1) + error(WARNING, "No newline at end of file"); + trp->lp = tp + 1; + return nmac; + + case S_STNL: + error(ERROR, "Unterminated string or char const"); + case S_NL: + tp->t = ip; + tp->type = NL; + tp->len = 1; + tp->wslen = 0; + s->lineinc++; + s->inp = ip + 1; + trp->lp = tp + 1; + return nmac; + + case S_EOFSTR: + error(FATAL, "EOF in string or char constant"); + break; + + case S_COMNL: + s->lineinc++; + state = COM2; + ip += runelen; + runelen = 1; + continue; + + case S_EOFCOM: + error(WARNING, "EOF inside comment"); + --ip; + case S_COMMENT: + if (!Cflag) + { + tp->t = ++ip; + tp->t[-1] = ' '; + tp->wslen = 1; + state = START; + continue; + } + else + { + runelen = 1; + s->lineinc = 0;; + tp->type = COMMENT; + tp->flag |= XTWS; + } + } + break; + } + ip += runelen; + runelen = 1; + tp->len = ip - tp->t; + tp++; + } +} + +/* have seen ?; handle the trigraph it starts (if any) else 0 */ +int + trigraph(Source * s) +{ + uchar c; + + while (s->inp + 2 >= s->inl && fillbuf(s) != EOF); + ; + if (s->inp[1] != '?') + return 0; + c = 0; + switch (s->inp[2]) + { + case '=': + c = '#'; + break; + case '(': + c = '['; + break; + case '/': + c = '\\'; + break; + case ')': + c = ']'; + break; + case '\'': + c = '^'; + break; + case '<': + c = '{'; + break; + case '!': + c = '|'; + break; + case '>': + c = '}'; + break; + case '-': + c = '~'; + break; + } + if (c) + { + *s->inp = c; + memmove(s->inp + 1, s->inp + 3, s->inl - s->inp + 2); + s->inl -= 2; + } + return c; +} + +int + foldline(Source * s) +{ + int n = 1; + + /* skip pending wihite spaces */ + while ((s->inp[n] == ' ') || (s->inp[n] == '\t')) + { + n++; + if ((s->inp + n >= s->inl) && (fillbuf(s) == EOF)) + break; + } + + /* refill buffer */ + while (s->inp + (n + 1) >= s->inl && fillbuf(s) != EOF); + + /* skip DOS line ends */ + if (((s->inp[n] == '\r') && (s->inp[n+1] == '\n')) || + ((s->inp[n] == '\n') && (s->inp[n+1] == '\r'))) + n++; + + if ((s->inp[n] == '\n') || (s->inp[n] == '\r')) + { + memmove(s->inp, s->inp + n + 1, s->inl - s->inp + n + 2); + s->inl -= n + 1; + return 1; + } + return 0; +} + +int + fillbuf(Source * s) +{ + int n; + + if (s->fd < 0 || (n = read(s->fd, (char *) s->inl, INS / 8)) <= 0) + n = 0; + s->inl += n; + s->inl[0] = s->inl[1] = s->inl[2] = s->inl[3] = EOB; + if (n == 0) + { + s->inl[0] = s->inl[1] = s->inl[2] = s->inl[3] = EOFC; + return EOF; + } + return 0; +} + +/* + * Push down to new source of characters. + * If fd>0 and str==NULL, then from a file `name'; + * if fd==-1 and str, then from the string. + */ +Source * + setsource(char *name, int path, int fd, char *str, int wrap) +{ + Source *s = new(Source); + int len; + + s->line = 1; + s->lineinc = 0; + s->fd = fd; + s->filename = name; + s->next = cursource; + s->ifdepth = 0; + s->pathdepth = path; + s->wrap = wrap; + + cursource = s; + + if (s->wrap) + genwrap(0); + + /* slop at right for EOB */ + if (str) + { + len = strlen(str); + s->inb = domalloc(len + 4); + s->inp = s->inb; + strncpy((char *) s->inp, str, len); + } + else + { + s->inb = domalloc(INS + 4); + s->inp = s->inb; + len = 0; + } + s->inl = s->inp + len; + s->inl[0] = s->inl[1] = EOB; + + return s; +} + +void + unsetsource(void) +{ + Source *s = cursource; + + if (s->wrap) + genwrap(1); + + if (s->fd >= 0) + { + close(s->fd); + dofree(s->inb); + } + cursource = s->next; + dofree(s); +} diff --git a/soltools/cpp/_macro.c b/soltools/cpp/_macro.c new file mode 100644 index 000000000000..fe7d22f82373 --- /dev/null +++ b/soltools/cpp/_macro.c @@ -0,0 +1,756 @@ +#ifdef _MSC_VER +# define _POSIX_ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef __hpux +# define _HPUX_SOURCE +#endif +#if defined(__IBMC__) || defined(__EMX__) +# define PATH_MAX _MAX_PATH +#endif +#include <limits.h> + +#include "cpp.h" + +#define NCONCAT 16384 + +/* + * do a macro definition. tp points to the name being defined in the line + */ +void + dodefine(Tokenrow * trp) +{ + Token *tp; + Nlist *np; + Source *s; + Tokenrow *def, *args; + static uchar location[(PATH_MAX + 8) * NINC], *cp; + + tp = trp->tp + 1; + if (tp >= trp->lp || tp->type != NAME) + { + error(ERROR, "#defined token is not a name"); + return; + } + np = lookup(tp, 1); + if (np->flag & ISUNCHANGE) + { + error(ERROR, "#defined token %t can't be redefined", tp); + return; + } + /* collect arguments */ + tp += 1; + args = NULL; + if (tp < trp->lp && tp->type == LP && tp->wslen == 0) + { + /* macro with args */ + int narg = 0; + + tp += 1; + args = new(Tokenrow); + maketokenrow(2, args); + if (tp->type != RP) + { + int err = 0; + + for (;;) + { + Token *atp; + + if (tp->type != NAME) + { + err++; + break; + } + if (narg >= args->max) + growtokenrow(args); + for (atp = args->bp; atp < args->lp; atp++) + if (atp->len == tp->len + && strncmp((char *) atp->t, (char *) tp->t, tp->len) == 0) + error(ERROR, "Duplicate macro argument"); + *args->lp++ = *tp; + narg++; + tp += 1; + if (tp->type == RP) + break; + if (tp->type != COMMA) + { + err++; + break; + } + tp += 1; + } + if (err) + { + error(ERROR, "Syntax error in macro parameters"); + return; + } + } + tp += 1; + } + trp->tp = tp; + if (((trp->lp) - 1)->type == NL) + trp->lp -= 1; + def = normtokenrow(trp); + if (np->flag & ISDEFINED) + { + if (comparetokens(def, np->vp) + || (np->ap == NULL) != (args == NULL) + || (np->ap && comparetokens(args, np->ap))) + { + if ( np->loc ) + error(ERROR, + "Macro redefinition of %t (already defined at %s)", + trp->bp + 2, np->loc); + else + error(ERROR, + "Macro redefinition of %t (already defined at %s)", + trp->bp + 2, "commandline" ); + } + } + if (args) + { + Tokenrow *tap; + + tap = normtokenrow(args); + dofree(args->bp); + args = tap; + } + np->ap = args; + np->vp = def; + np->flag |= ISDEFINED; + + /* build location string of macro definition */ + for (cp = location, s = cursource; s; s = s->next) + if (*s->filename) + { + if (cp != location) + *cp++ = ' '; + sprintf((char *)cp, "%s:%d", s->filename, s->line); + cp += strlen((char *)cp); + } + + np->loc = newstring(location, strlen((char *)location), 0); + + if (Mflag) + { + if (np->ap) + error(INFO, "Macro definition of %s(%r) [%r]", np->name, np->ap, np->vp); + else + error(INFO, "Macro definition of %s [%r]", np->name, np->vp); + } +} + +/* + * Definition received via -D or -U + */ +void + doadefine(Tokenrow * trp, int type) +{ + Nlist *np; + static uchar onestr[2] = "1"; + static Token onetoken[1] = {{NUMBER, 0, 0, 1, onestr, 0}}; + static Tokenrow onetr = {onetoken, onetoken, onetoken + 1, 1}; + + trp->tp = trp->bp; + if (type == 'U') + { + if (trp->lp - trp->tp != 2 || trp->tp->type != NAME) + goto syntax; + if ((np = lookup(trp->tp, 0)) == NULL) + return; + np->flag &= ~ISDEFINED; + return; + } + + if (type == 'A') + { + if (trp->tp >= trp->lp || trp->tp->type != NAME) + goto syntax; + trp->tp->type = ARCHITECTURE; + np = lookup(trp->tp, 1); + np->flag |= ISARCHITECTURE; + trp->tp += 1; + if (trp->tp >= trp->lp || trp->tp->type == END) + { + np->vp = &onetr; + return; + } + else + error(FATAL, "Illegal -A argument %r", trp); + } + + if (trp->tp >= trp->lp || trp->tp->type != NAME) + goto syntax; + np = lookup(trp->tp, 1); + np->flag |= ISDEFINED; + trp->tp += 1; + if (trp->tp >= trp->lp || trp->tp->type == END) + { + np->vp = &onetr; + return; + } + if (trp->tp->type != ASGN) + goto syntax; + trp->tp += 1; + if ((trp->lp - 1)->type == END) + trp->lp -= 1; + np->vp = normtokenrow(trp); + return; +syntax: + error(FATAL, "Illegal -D or -U argument %r", trp); +} + + + +/* + * Do macro expansion in a row of tokens. + * Flag is NULL if more input can be gathered. + */ +void + expandrow(Tokenrow * trp, char *flag) +{ + Token * tp; + Nlist * np; + + MacroValidatorList validators; + mvl_init(&validators); + /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */ + tokenrow_zeroTokenIdentifiers(trp); + + if (flag) + setsource(flag, -1, -1, "", 0); + for (tp = trp->tp; tp < trp->lp;) + { + mvl_check(&validators, tp); + + if (tp->type != NAME + || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0 + || (np = lookup(tp, 0)) == NULL + || (np->flag & (ISDEFINED | ISMAC)) == 0 + || (np->flag & ISACTIVE) != 0) + { + tp++; + continue; + } + trp->tp = tp; + if (np->val == KDEFINED) + { + tp->type = DEFINED; + if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) + (tp + 1)->type = NAME1; + else + if ((tp + 3) < trp->lp && (tp + 1)->type == LP + && (tp + 2)->type == NAME && (tp + 3)->type == RP) + (tp + 2)->type = NAME1; + else + error(ERROR, "Incorrect syntax for `defined'"); + tp++; + continue; + } + else + if (np->val == KMACHINE) + { + if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP)) + { + tp->type = ARCHITECTURE; + if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) + (tp + 1)->type = NAME2; + else + if ((tp + 3) < trp->lp && (tp + 1)->type == LP + && (tp + 2)->type == NAME && (tp + 3)->type == RP) + (tp + 2)->type = NAME2; + else + error(ERROR, "Incorrect syntax for `#machine'"); + } + tp++; + continue; + } + + if (np->flag & ISMAC) + builtin(trp, np->val); + else + expand(trp, np, &validators); + tp = trp->tp; + } // end for + if (flag) + unsetsource(); + + mvl_destruct(&validators); +} + +/* + * Expand the macro whose name is np, at token trp->tp, in the tokenrow. + * Return trp->tp at the first token next to be expanded + * (ordinarily the beginning of the expansion) + * I.e.: the same position as before! + * Only one expansion is performed, then we return to the expandrow() + * loop and start at same position. + */ +void + expand(Tokenrow * trp, Nlist * np, MacroValidatorList * pValidators) +{ +// Token * pOldNextTp; + Tokenrow ntr; + int ntokc, narg, i; + Tokenrow *atr[NARG + 1]; + + if (Mflag == 2) + { + if (np->ap) + error(INFO, "Macro expansion of %t with %s(%r)", trp->tp, np->name, np->ap); + else + error(INFO, "Macro expansion of %t with %s", trp->tp, np->name); + } + + copytokenrow(&ntr, np->vp); /* copy macro value */ + if (np->ap == NULL) /* parameterless */ + ntokc = 1; + else + { + ntokc = gatherargs(trp, atr, &narg); + if (narg < 0) + { /* not actually a call (no '(') */ + trp->tp++; + return; + } + if (narg != rowlen(np->ap)) + { + error(ERROR, "Disagreement in number of macro arguments"); + trp->tp += ntokc; + return; + } + + /** If gatherargs passed a macro validating token, this token + must become valid here. + trp->tp+0 was checked in expandrow(), so we dont need to do it + again here: + */ + for (i = 1; i < ntokc; i++) + { + mvl_check(pValidators,trp->tp+i); + } + + substargs(np, &ntr, atr); /* put args into replacement */ + for (i = 0; i < narg; i++) + { + dofree(atr[i]->bp); + dofree(atr[i]); + } + } + +/* old + np->flag |= ISACTIVE; +*/ + +/* rh +*/ + doconcat(&ntr); /* execute ## operators */ + ntr.tp = ntr.bp; + makespace(&ntr, trp->tp); + +/* old +// expandrow(&ntr, "<expand>"); +// insertrow(trp, ntokc, &ntr); +// dofree(ntr.bp); +// np->flag &= ~ISACTIVE; +*/ + +/* NP + // Replace macro by its value: +*/ +// pOldNextTp = trp->tp+ntokc; + tokenrow_zeroTokenIdentifiers(&ntr); + insertrow(trp, ntokc, &ntr); + /* Reassign old macro validators: + */ +// mvl_move(pValidators, trp->tp - pOldNextTp); + + /* add validator for just invalidated macro: + */ + np->flag |= ISACTIVE; + if (trp->tp != trp->lp) + { /* tp is a valid pointer: */ + mvl_add(pValidators,np,trp->tp); + } + else + { /* tp is == lp, therefore does not point to valid memory: */ + mvl_add(pValidators,np,0); + } + /* reset trp->tp to original position: + */ + trp->tp -= ntr.lp - ntr.bp; /* so the result will be tested for macros from the same position again */ + + dofree(ntr.bp); + + return; +} + +/* + * Gather an arglist, starting in trp with tp pointing at the macro name. + * Return total number of tokens passed, stash number of args found. + * trp->tp is not changed relative to the tokenrow. + */ +int + gatherargs(Tokenrow * trp, Tokenrow ** atr, int *narg) +{ + int parens = 1; + int ntok = 0; + Token *bp, *lp; + Tokenrow ttr; + int ntokp; + int needspace; + + *narg = -1; /* means that there is no macro + * call */ + /* look for the ( */ + for (;;) + { + trp->tp++; + ntok++; + if (trp->tp >= trp->lp) + { + gettokens(trp, 0); + if ((trp->lp - 1)->type == END) + { + trp->lp -= 1; + trp->tp -= ntok; + return ntok; + } + } + if (trp->tp->type == LP) + break; + if (trp->tp->type != NL) + return ntok; + } + *narg = 0; + ntok++; + ntokp = ntok; + trp->tp++; + /* search for the terminating ), possibly extending the row */ + needspace = 0; + while (parens > 0) + { + if (trp->tp >= trp->lp) + gettokens(trp, 0); + if (needspace) + { + needspace = 0; + /* makespace(trp); [rh] */ + } + if (trp->tp->type == END) + { + trp->lp -= 1; + trp->tp -= ntok; + error(ERROR, "EOF in macro arglist"); + return ntok; + } + if (trp->tp->type == NL) + { + trp->tp += 1; + adjustrow(trp, -1); + trp->tp -= 1; + /* makespace(trp); [rh] */ + needspace = 1; + continue; + } + if (trp->tp->type == LP) + parens++; + else + if (trp->tp->type == RP) + parens--; + trp->tp++; + ntok++; + } + trp->tp -= ntok; + /* Now trp->tp won't move underneath us */ + lp = bp = trp->tp + ntokp; + for (; parens >= 0; lp++) + { + if (lp->type == LP) + { + parens++; + continue; + } + if (lp->type == RP) + parens--; + if (lp->type == DSHARP) + lp->type = DSHARP1; /* ## not special in arg */ + if ((lp->type == COMMA && parens == 0) || + ( parens < 0 && ((lp - 1)->type != LP))) + { + if (*narg >= NARG - 1) + error(FATAL, "Sorry, too many macro arguments"); + ttr.bp = ttr.tp = bp; + ttr.lp = lp; + atr[(*narg)++] = normtokenrow(&ttr); + bp = lp + 1; + } + } + return ntok; +} + +/* + * substitute the argument list into the replacement string + * This would be simple except for ## and # + */ +void + substargs(Nlist * np, Tokenrow * rtr, Tokenrow ** atr) +{ + Tokenrow tatr; + Token *tp; + int ntok, argno; + + for (rtr->tp = rtr->bp; rtr->tp < rtr->lp;) + { + if (rtr->tp->type == SHARP) + { /* string operator */ + tp = rtr->tp; + rtr->tp += 1; + if ((argno = lookuparg(np, rtr->tp)) < 0) + { + error(ERROR, "# not followed by macro parameter"); + continue; + } + ntok = 1 + (rtr->tp - tp); + rtr->tp = tp; + insertrow(rtr, ntok, stringify(atr[argno])); + continue; + } + if (rtr->tp->type == NAME + && (argno = lookuparg(np, rtr->tp)) >= 0) + { + if (((rtr->tp + 1) < rtr->lp && (rtr->tp + 1)->type == DSHARP) + || (rtr->tp != rtr->bp && (rtr->tp - 1)->type == DSHARP)) + { + copytokenrow(&tatr, atr[argno]); + makespace(&tatr, rtr->tp); + insertrow(rtr, 1, &tatr); + dofree(tatr.bp); + } + else + { + copytokenrow(&tatr, atr[argno]); + makespace(&tatr, rtr->tp); + expandrow(&tatr, "<macro>"); + insertrow(rtr, 1, &tatr); + dofree(tatr.bp); + } + continue; + } + rtr->tp++; + } +} + +/* + * Evaluate the ## operators in a tokenrow + */ +void + doconcat(Tokenrow * trp) +{ + Token *ltp, *ntp; + Tokenrow ntr; + int len; + + for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++) + { + if (trp->tp->type == DSHARP1) + trp->tp->type = DSHARP; + else + if (trp->tp->type == DSHARP) + { + int i; + char tt[NCONCAT]; + + ltp = trp->tp - 1; + ntp = trp->tp + 1; + + if (ltp < trp->bp || ntp >= trp->lp) + { + error(ERROR, "## occurs at border of replacement"); + continue; + } + + ntp = ltp; + i = 1; + len = 0; + + do + { + if (len + ntp->len + ntp->wslen > sizeof(tt)) + { + error(ERROR, "## string concatination buffer overrun"); + break; + } + + if (ntp != trp->tp + 1) + { + strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen, + ntp->len + ntp->wslen); + len += ntp->len + ntp->wslen; + } + else // Leerzeichen um ## herum entfernen: + { + strncpy((char *) tt + len, (char *) ntp->t, ntp->len); + len += ntp->len; + } + + ntp = trp->tp + i; + i++; + } + while (ntp < trp->lp); + + tt[len] = '\0'; + setsource("<##>", -1, -1, tt, 0); + maketokenrow(3, &ntr); + gettokens(&ntr, 1); + unsetsource(); + if (ntr.bp->type == UNCLASS) + error(WARNING, "Bad token %r produced by ##", &ntr); + while ((ntr.lp-1)->len == 0 && ntr.lp != ntr.bp) + ntr.lp--; + + doconcat(&ntr); + trp->tp = ltp; + makespace(&ntr, ltp); + insertrow(trp, ntp - ltp, &ntr); + dofree(ntr.bp); + trp->tp--; + } + } +} + +/* + * tp is a potential parameter name of macro mac; + * look it up in mac's arglist, and if found, return the + * corresponding index in the argname array. Return -1 if not found. + */ +int + lookuparg(Nlist * mac, Token * tp) +{ + Token *ap; + + if (tp->type != NAME || mac->ap == NULL) + return -1; + for (ap = mac->ap->bp; ap < mac->ap->lp; ap++) + { + if (ap->len == tp->len && strncmp((char *) ap->t, (char *) tp->t, ap->len) == 0) + return ap - mac->ap->bp; + } + return -1; +} + +/* + * Return a quoted version of the tokenrow (from # arg) + */ +#define STRLEN 512 +Tokenrow * + stringify(Tokenrow * vp) +{ + static Token t = {STRING, 0, 0, 0, NULL, 0}; + static Tokenrow tr = {&t, &t, &t + 1, 1}; + Token *tp; + uchar s[STRLEN]; + uchar *sp = s, *cp; + int i, instring; + + *sp++ = '"'; + for (tp = vp->bp; tp < vp->lp; tp++) + { + instring = tp->type == STRING || tp->type == CCON; + if (sp + 2 * tp->len + tp->wslen >= &s[STRLEN - 10]) + { + error(ERROR, "Stringified macro arg is too long"); + break; + } + + // Change by np 31.10.2001, #93725 - begin + if ( tp->wslen > 0 ) + *sp++ = ' '; + // change end. + + for (i = 0, cp = tp->t; (unsigned int)i < tp->len; i++) + { + if (instring && (*cp == '"' || *cp == '\\')) + *sp++ = '\\'; + *sp++ = *cp++; + } + } + *sp++ = '"'; + *sp = '\0'; + sp = s; + t.len = strlen((char *) sp); + t.t = newstring(sp, t.len, 0); + return &tr; +} + +/* + * expand a builtin name + */ +void + builtin(Tokenrow * trp, int biname) +{ + char *op; + Token *tp; + Source *s; + + tp = trp->tp; + trp->tp++; + /* need to find the real source */ + s = cursource; + while (s && s->fd == -1) + s = s->next; + if (s == NULL) + s = cursource; + /* most are strings */ + tp->type = STRING; + if (tp->wslen) + { + *outptr++ = ' '; + tp->wslen = 1; + } + op = outptr; + *op++ = '"'; + switch (biname) + { + + case KLINENO: + tp->type = NUMBER; + op = outnum(op - 1, s->line); + break; + + case KFILE: + { + char *src = s->filename; + + while ((*op++ = *src++) != 0) + if (src[-1] == '\\') + *op++ = '\\'; + op--; + break; + } + + case KDATE: + strncpy(op, curtime + 4, 7); + strncpy(op + 7, curtime + 20, 4); + op += 11; + break; + + case KTIME: + strncpy(op, curtime + 11, 8); + op += 8; + break; + + default: + error(ERROR, "cpp botch: unknown internal macro"); + return; + } + if (tp->type == STRING) + *op++ = '"'; + tp->t = (uchar *) outptr; + tp->len = op - outptr; + outptr = op; +} + diff --git a/soltools/cpp/_mcrvalid.c b/soltools/cpp/_mcrvalid.c new file mode 100644 index 000000000000..75813837d470 --- /dev/null +++ b/soltools/cpp/_mcrvalid.c @@ -0,0 +1,129 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "cpp.h" + +/* + Nlist * pMacro; + Token * pTokenWhereMacroBecomesValid; + struct macroValidator * + pNext; +*/ + +void +mvl_init(MacroValidatorList * out_pValidators) +{ + out_pValidators->pFirst = 0; + out_pValidators->nextFreeIdentifier = 1; +} + +void +mvl_destruct(MacroValidatorList * out_pValidators) +{ + MacroValidator * pV = out_pValidators->pFirst; + MacroValidator * pDel; + for ( pDel = out_pValidators->pFirst; + pDel != 0; + pDel = pV ) + { + pV = pV->pNext; + + pDel->pMacro->flag &= (~ISACTIVE); + dofree(pDel); + } +} + + +#define INVALID_TILL_ENDOFROW 32000 + +/* If in_pTokenWhereMacroBecomesValid == 0, the macro is at row end + and therefore there does not exist any token, where the macro becomes + valid again. It is revalidated, when the row was processed complete. +*/ +void +mvl_add( MacroValidatorList * inout_pValidators, + Nlist * in_pMacro, + Token * in_pTokenWhereMacroBecomesValid ) +{ + + MacroValidator * pNew = new(MacroValidator); + pNew->pMacro = in_pMacro; + + if (in_pTokenWhereMacroBecomesValid == 0) + { + pNew->nTokenWhereMacroBecomesValid = INVALID_TILL_ENDOFROW; + } + else if (in_pTokenWhereMacroBecomesValid->identifier > 0) + { + pNew->nTokenWhereMacroBecomesValid = in_pTokenWhereMacroBecomesValid->identifier; + } + else + { + pNew->nTokenWhereMacroBecomesValid = inout_pValidators->nextFreeIdentifier; + in_pTokenWhereMacroBecomesValid->identifier = inout_pValidators->nextFreeIdentifier; + inout_pValidators->nextFreeIdentifier++; + } + + pNew->pNext = inout_pValidators->pFirst; + inout_pValidators->pFirst = pNew; +} + +/* +void +mvl_move( MacroValidatorList * inout_pValidators, + int in_nSpace ) +{ + MacroValidator * pV; + for ( pV = inout_pValidators->pFirst; + pV != 0; + pV = pV->pNext ) + { + pV->pTokenWhereMacroBecomesValid += in_nSpace; + } +} +*/ + +void +mvl_check( MacroValidatorList * inout_pValidators, + Token * inout_pTokenToCheck) +{ + MacroValidator * pV; /* Running pointer */ + MacroValidator * pCheckedOnes; /* Here new list is built. */ + pCheckedOnes = 0; + + for ( pV = inout_pValidators->pFirst; + pV != 0; + pV = inout_pValidators->pFirst ) + { + inout_pValidators->pFirst = pV->pNext; + + if (pV->nTokenWhereMacroBecomesValid == inout_pTokenToCheck->identifier) + { + pV->pMacro->flag &= (~ISACTIVE); + dofree(pV); + } + else + { + pV->pNext = pCheckedOnes; + pCheckedOnes = pV; + } + } /* end for */ + + /* Assign new built list (too old ones were removed) to + original list: + */ + inout_pValidators->pFirst = pCheckedOnes; +} + + +void +tokenrow_zeroTokenIdentifiers(Tokenrow* trp) +{ + Token * tp; + for (tp = trp->bp; tp < trp->lp; tp++) + { + tp->identifier = 0; + } +} + diff --git a/soltools/cpp/_nlist.c b/soltools/cpp/_nlist.c new file mode 100644 index 000000000000..a71085bfbbf9 --- /dev/null +++ b/soltools/cpp/_nlist.c @@ -0,0 +1,117 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "cpp.h" + +extern int Cplusplus; +Nlist *kwdefined; +char wd[128]; + +/* + ER: Tabelle extra gross gemacht, da es anscheinend ein Problem mit der + der Verkettung gibt, irgendwann irgendwo wird mal ein nlist->next + ueberschrieben, was in eineme SIGSEGV resultiert. + Den GDB mit watchpoint hab ich aber nach 2 Tagen abgebrochen.. + so loeppt's jedenfalls erstmal.. + */ +#define NLSIZE 15000 + +static Nlist *nlist[NLSIZE]; + +struct kwtab +{ + char *kw; + int val; + int flag; +} kwtab[] = + +{ + {"if", KIF, ISKW}, + {"ifdef", KIFDEF, ISKW}, + {"ifndef", KIFNDEF, ISKW}, + {"elif", KELIF, ISKW}, + {"else", KELSE, ISKW}, + {"endif", KENDIF, ISKW}, + {"include", KINCLUDE, ISKW}, + {"include_next", KINCLUDENEXT, ISKW}, + {"import", KIMPORT, ISKW}, + {"define", KDEFINE, ISKW}, + {"undef", KUNDEF, ISKW}, + {"line", KLINE, ISKW}, + {"error", KERROR, ISKW}, + {"pragma", KPRAGMA, ISKW}, + {"ident", KIDENT, ISKW}, + {"eval", KEVAL, ISKW}, + {"defined", KDEFINED, ISDEFINED + ISUNCHANGE}, + {"machine", KMACHINE, ISDEFINED + ISUNCHANGE}, + {"__LINE__", KLINENO, ISMAC + ISUNCHANGE}, + {"__FILE__", KFILE, ISMAC + ISUNCHANGE}, + {"__DATE__", KDATE, ISMAC + ISUNCHANGE}, + {"__TIME__", KTIME, ISMAC + ISUNCHANGE}, + {"__STDC__", KSTDC, ISUNCHANGE}, + {NULL, 0, 0} +}; + +unsigned long namebit[077 + 1]; + +void + setup_kwtab(void) +{ + struct kwtab *kp; + Nlist *np; + Token t; + static Token deftoken[1] = {{NAME, 0, 0, 7, (uchar *) "defined", 0}}; + static Tokenrow deftr = {deftoken, deftoken, deftoken + 1, 1}; + + for (kp = kwtab; kp->kw; kp++) + { + t.t = (uchar *) kp->kw; + t.len = strlen(kp->kw); + np = lookup(&t, 1); + np->flag = (char) kp->flag; + np->val = (char) kp->val; + if (np->val == KDEFINED) + { + kwdefined = np; + np->val = NAME; + np->vp = &deftr; + np->ap = 0; + } + } +} + +Nlist * + lookup(Token * tp, int install) +{ + unsigned int h; + Nlist *np; + uchar *cp, *cpe; + + h = 0; + for (cp = tp->t, cpe = cp + tp->len; cp < cpe;) + h += *cp++; + h %= NLSIZE; + np = nlist[h]; + while (np) + { + if (*tp->t == *np->name && tp->len == (unsigned int)np->len + && strncmp((char *)tp->t, (char *)np->name, tp->len) == 0) + return np; + np = np->next; + } + if (install) + { + np = new(Nlist); + np->vp = NULL; + np->ap = NULL; + np->flag = 0; + np->val = 0; + np->len = tp->len; + np->name = newstring(tp->t, tp->len, 0); + np->next = nlist[h]; + nlist[h] = np; + quickset(tp->t[0], tp->len > 1 ? tp->t[1] : 0); + return np; + } + return NULL; +} diff --git a/soltools/cpp/_tokens.c b/soltools/cpp/_tokens.c new file mode 100644 index 000000000000..863de2fbef02 --- /dev/null +++ b/soltools/cpp/_tokens.c @@ -0,0 +1,535 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#else +#include <unistd.h> +#endif +#include "cpp.h" + + +static char wbuf[4 * OBS]; +static char *wbp = wbuf; +static int EBCDIC_ExternTokenDetected = 0; +static int EBCDIC_StartTokenDetected = 0; + +unsigned char toLatin1[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f, 0x97, 0x8d, + 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x9d, 0x0a, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, + 0x1e, 0x1f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, 0x90, 0x91, + 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9a, 0x9b, + 0x14, 0x15, 0x9e, 0x1a, 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, + 0xe3, 0xe5, 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, 0xec, 0xdf, + 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, 0x2d, 0x2f, 0xc2, 0xc4, + 0xc0, 0xc1, 0xc3, 0xc5, 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, + 0x3e, 0x3f, 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, 0xb0, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, + 0xc6, 0xa4, 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, 0xac, 0xa3, + 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, 0xbd, 0xbe, 0xdd, 0xa8, + 0xaf, 0x5d, 0xb4, 0xd7, 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, + 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, 0x5c, 0xf7, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, + 0xd3, 0xd5, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f +}; + +#define MASK "\\x%x" + +int + memcpy_EBCDIC( char * pwbuf, uchar *p, int len ) +{ + int currpos = 0; + int processedchars = 0; + + if( len == 0 ) + return 0; + + if( len == 1 ) + { + *pwbuf = *p; + return 1; + } + + /* copy spaces until " or ' */ + while( (p[ processedchars ] != '\"') && (p[ processedchars ] != '\'') ) + pwbuf[ currpos++ ] = p[ processedchars++ ]; + + /* copy first " or ' */ + pwbuf[ currpos++ ] = p[ processedchars++ ]; + + /* convert all characters until " or ' */ + while( processedchars < (len - 1) ) + { + if( p[ processedchars ] == '\\' ) + { + switch( p[ ++processedchars ] ) + { + case 'n': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\n'] ); + processedchars++; + break; + + case 't': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\t'] ); + processedchars++; + break; + + case 'v': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\v'] ); + processedchars++; + break; + + case 'b': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\b'] ); + processedchars++; + break; + + case 'r': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\r'] ); + processedchars++; + break; + + case 'f': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\f'] ); + processedchars++; + break; + + case 'a': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\a'] ); + processedchars++; + break; + + case '\\': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\\'] ); + processedchars++; + break; + + case '?': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\?'] ); + processedchars++; + break; + + case '\'': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\''] ); + processedchars++; + break; + + case '"': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\"'] ); + processedchars++; + break; + + /* octal coded character? -> copy */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int startpos = currpos; + + pwbuf[ currpos++ ] = '\\'; + + while( p[ processedchars ] >= '0' && p[ processedchars ] <= '7' && (currpos < startpos + 4) ) + pwbuf[ currpos++ ] = (unsigned char)p[ processedchars++ ]; + break; + } + + /* hex coded character? -> copy */ + case 'x': + case 'X': + { + int startpos = currpos; + + pwbuf[ currpos++ ] = '\\'; + pwbuf[ currpos++ ] = 'x'; + processedchars++; + + while( isxdigit( p[ processedchars ] ) && (currpos < startpos + 4) ) + pwbuf[ currpos++ ] = (unsigned char)p[ processedchars++ ]; + break; + } + + } + } + else + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1[p[ processedchars++ ]] ); + + } + + /* copy last " or ' */ + pwbuf[ currpos++ ] = p[ processedchars ]; + + return currpos; +} + +void + maketokenrow(int size, Tokenrow * trp) +{ + trp->max = size; + if (size > 0) + trp->bp = (Token *) domalloc(size * sizeof(Token)); + else + trp->bp = NULL; + trp->tp = trp->bp; + trp->lp = trp->bp; +} + +Token * + growtokenrow(Tokenrow * trp) +{ + int ncur = trp->tp - trp->bp; + int nlast = trp->lp - trp->bp; + + trp->max = 3 * trp->max / 2 + 1; + trp->bp = (Token *) realloc(trp->bp, trp->max * sizeof(Token)); + trp->lp = &trp->bp[nlast]; + trp->tp = &trp->bp[ncur]; + return trp->lp; +} + +/* + * Compare a row of tokens, ignoring the content of WS; return !=0 if different + */ +int + comparetokens(Tokenrow * tr1, Tokenrow * tr2) +{ + Token *tp1, *tp2; + + tp1 = tr1->tp; + tp2 = tr2->tp; + if (tr1->lp - tp1 != tr2->lp - tp2) + return 1; + for (; tp1 < tr1->lp; tp1++, tp2++) + { + if (tp1->type != tp2->type + || (tp1->wslen == 0) != (tp2->wslen == 0) + || tp1->len != tp2->len + || strncmp((char *) tp1->t, (char *) tp2->t, tp1->len) != 0) + return 1; + } + return 0; +} + +/* + * replace ntok tokens starting at dtr->tp with the contents of str. + * tp ends up pointing just beyond the replacement. + * Canonical whitespace is assured on each side. + */ +void + insertrow(Tokenrow * dtr, int ntok, Tokenrow * str) +{ + int nrtok = rowlen(str); + + dtr->tp += ntok; + adjustrow(dtr, nrtok - ntok); + dtr->tp -= ntok; + movetokenrow(dtr, str); + dtr->tp += nrtok; +} + +/* + * make sure there is WS before trp->tp, if tokens might merge in the output + */ +void + makespace(Tokenrow * trp, Token * ntp) +{ + uchar *tt; + Token *tp = trp->tp; + + if (tp >= trp->lp) + return; + + if (ntp->wslen) + { + tt = newstring(tp->t, tp->len, ntp->wslen); + strncpy((char *)tt, (char *)ntp->t - ntp->wslen, ntp->wslen); + tp->t = tt + ntp->wslen; + tp->wslen = ntp->wslen; + tp->flag |= XPWS; + } +} + +/* + * Copy an entire tokenrow into another, at tp. + * It is assumed that there is enough space. + * Not strictly conforming. + */ +void + movetokenrow(Tokenrow * dtr, Tokenrow * str) +{ + int nby; + + /* nby = sizeof(Token) * (str->lp - str->bp); */ + nby = (char *) str->lp - (char *) str->bp; + memmove(dtr->tp, str->bp, nby); +} + +/* + * Move the tokens in a row, starting at tr->tp, rightward by nt tokens; + * nt may be negative (left move). + * The row may need to be grown. + * Non-strictly conforming because of the (char *), but easily fixed + */ +void + adjustrow(Tokenrow * trp, int nt) +{ + int nby, size; + + if (nt == 0) + return; + size = (trp->lp - trp->bp) + nt; + while (size > trp->max) + growtokenrow(trp); + /* nby = sizeof(Token) * (trp->lp - trp->tp); */ + nby = (char *) trp->lp - (char *) trp->tp; + if (nby) + memmove(trp->tp + nt, trp->tp, nby); + trp->lp += nt; +} + +/* + * Copy a row of tokens into the destination holder, allocating + * the space for the contents. Return the destination. + */ +Tokenrow * + copytokenrow(Tokenrow * dtr, Tokenrow * str) +{ + int len = rowlen(str); + + maketokenrow(len, dtr); + movetokenrow(dtr, str); + dtr->lp += len; + return dtr; +} + +/* + * Produce a copy of a row of tokens. Start at trp->tp. + * The value strings are copied as well. The first token + * has WS available. + */ +Tokenrow * + normtokenrow(Tokenrow * trp) +{ + Token *tp; + Tokenrow *ntrp = new(Tokenrow); + int len; + + len = trp->lp - trp->tp; + if (len <= 0) + len = 1; + maketokenrow(len, ntrp); + for (tp = trp->tp; tp < trp->lp; tp++) + { + *ntrp->lp = *tp; + if (tp->len) + { + ntrp->lp->t = newstring(tp->t, tp->len, 1); + *ntrp->lp->t++ = ' '; + if (tp->wslen) + ntrp->lp->wslen = 1; + } + ntrp->lp++; + } + if (ntrp->lp > ntrp->bp) + ntrp->bp->wslen = 0; + return ntrp; +} + +/* + * Debugging + */ +void + peektokens(Tokenrow * trp, char *str) +{ + Token *tp; + + tp = trp->tp; + flushout(); + if (str) + fprintf(stderr, "%s ", str); + if (tp < trp->bp || tp > trp->lp) + fprintf(stderr, "(tp offset %ld) ", (long int) (tp - trp->bp)); + for (tp = trp->bp; tp < trp->lp && tp < trp->bp + 32; tp++) + { + if (tp->type != NL) + { + int c = tp->t[tp->len]; + + tp->t[tp->len] = 0; + fprintf(stderr, "%s", tp->t); + tp->t[tp->len] = (uchar) c; + } + fprintf(stderr, tp == trp->tp ? "{%x*} " : "{%x} ", tp->type); + } + fprintf(stderr, "\n"); + fflush(stderr); +} + +void + puttokens(Tokenrow * trp) +{ + Token *tp; + int len; + uchar *p; + + if (Vflag) + peektokens(trp, ""); + tp = trp->bp; + for (; tp < trp->lp; tp++) + { + if (tp->type != NL) + { + len = tp->len + tp->wslen; + p = tp->t - tp->wslen; + + /* add parameter check to delete operator? */ + if( Dflag ) + { + if( (tp->type == NAME) && (strncmp( (char*)p, "delete", len ) == 0) ) + { + Token* ntp = tp; + ntp++; + + if( ntp->type == NAME ) + { + uchar* np = ntp->t - ntp->wslen; + int nlen = ntp->len + ntp->wslen; + + memcpy(wbp, "if(", 3 ); + wbp += 4; + memcpy(wbp, np, nlen ); + wbp += nlen; + memcpy(wbp, ")", 1 ); + wbp++; + + memcpy(wbp, p, len); + } + } + } + + /* EBCDIC to ANSI conversion requested? */ + if( Aflag ) + { + /* keyword __ToLatin1__ found? -> do conversion! */ + if( EBCDIC_StartTokenDetected ) + { + /* previous token was 'extern'? -> don't convert current token! */ + if( EBCDIC_ExternTokenDetected ) + { + EBCDIC_ExternTokenDetected = 0; + memcpy(wbp, p, len); + } + else + { + /* current token is keyword 'extern'? -> don't convert following token! */ + if( (tp->wslen == 0) && (strncmp( (char*)p, "extern", len ) == 0) ) + { + EBCDIC_ExternTokenDetected = 1; + memcpy(wbp, p, len); + } + else + { + /* token is string or char? -> process EBCDIC to ANSI conversion */ + if ((tp->type == STRING) || (tp->type == CCON)) + len = memcpy_EBCDIC(wbp, p, len); + else + memcpy(wbp, p, len); + } + } + } + else + /* keyword __ToLatin1__ found? -> don't copy keyword and start conversion */ + if( (tp->type == NAME) && (strncmp( (char*)p, "__ToLatin1__", len) == 0) ) + { + EBCDIC_StartTokenDetected = 1; + len = 0; + } + else + memcpy(wbp, p, len); + } + else + memcpy(wbp, p, len); + + wbp += len; + } + else + *wbp++ = '\n'; + + if (wbp >= &wbuf[OBS]) + { + if ( write(1, wbuf, OBS) != -1 ) { + if (wbp > &wbuf[OBS]) + memcpy(wbuf, wbuf + OBS, wbp - &wbuf[OBS]); + wbp -= OBS; + } + else exit(1); + } + } + trp->tp = tp; + if (cursource->fd == 0) + flushout(); +} + +void + flushout(void) +{ + if (wbp > wbuf) + { + if ( write(1, wbuf, wbp - wbuf) != -1) + wbp = wbuf; + else + exit(1); + } +} + +/* + * turn a row into just a newline + */ +void + setempty(Tokenrow * trp) +{ + trp->tp = trp->bp; + trp->lp = trp->bp + 1; + *trp->bp = nltoken; +} + +/* + * generate a number + */ +char * + outnum(char *p, int n) +{ + if (n >= 10) + p = outnum(p, n / 10); + *p++ = (char) (n % 10 + '0'); + return p; +} + +/* + * allocate and initialize a new string from s, of length l, at offset o + * Null terminated. + */ +uchar * + newstring(uchar * s, int l, int o) +{ + uchar *ns = (uchar *) domalloc(l + o + 1); + + ns[l + o] = '\0'; + return (uchar *) strncpy((char *) ns + o, (char *) s, l) - o; +} diff --git a/soltools/cpp/_unix.c b/soltools/cpp/_unix.c new file mode 100644 index 000000000000..5352f6f1f5f9 --- /dev/null +++ b/soltools/cpp/_unix.c @@ -0,0 +1,234 @@ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <fcntl.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#else +#include <unistd.h> +#endif + +#include "cpp.h" + +#if defined MACOSX || !defined HAVE_GETOPT +extern int stgetopt(int, char *const *, const char *); +extern char *optarg; +extern int optind; +#else +#include <getopt.h> +#endif + +extern char rcsid[]; + +int Pflag = 0; /* print no line information */ +int Iflag = 0; /* print includes */ +int Mflag = 0; /* print macor expansion */ +int Aflag = 0; /* translate character sets */ +int Xflag = 0; /* print pragma for include/import */ +int Vflag = 0; /* verbose flag */ +int Cflag = 0; /* do not remove any comments */ +int Dflag = 0; /* add parameter check to delete op */ +int Cplusplus = 0; + +extern void setup_kwtab(void); + +void + setup(int argc, char **argv) +{ + int c, fd, i, n; + char *fp, *dp; + Tokenrow tr; + + setup_kwtab(); +#if defined MACOSX || !defined HAVE_GETOPT + while ((c = stgetopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1) +#else + while ((c = getopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1) +#endif + switch (c) + { + case 'N': + for (i = 0; i < NINCLUDE; i++) + if (includelist[i].always == 1) + includelist[i].deleted = 1; + break; + + case 'I': + for (i = NINCLUDE - 2; i >= 0; i--) + { + if (includelist[i].file == NULL) + { + includelist[i].always = 1; + includelist[i].file = optarg; + break; + } + } + if (i < 0) + error(FATAL, "Too many -I directives"); + break; + + case 'D': + case 'U': + case 'A': + setsource("<cmdarg>", -1, -1, optarg, 0); + maketokenrow(3, &tr); + gettokens(&tr, 1); + doadefine(&tr, c); + unsetsource(); + break; + + case 'P': /* Lineinfo */ + Pflag++; + break; + + case 'V': + for (n = 0; (c = optarg[n]) != '\0'; n++) + switch (c) + { + case 'i': + Iflag++; + break; + + case 'm': + Mflag = 1; + break; + + case 'x': + Mflag = 2; + break; + + case 't': + Vflag++; + break; + + case 'v': + fprintf(stderr, "%s %s\n", argv[0], rcsid); + break; + + default: + error(WARNING, "Unknown verbose option %c", c); + } + break; + + case 'X': + for (n = 0; (c = optarg[n]) != '\0'; n++) + switch (c) + { + case 'a': + Aflag++; + break; + + case 'i': + Xflag++; + break; + + case 'c': + Cflag++; + break; + + case 'd': + Dflag++; + break; + + case 'w': + dp = &optarg[n + 1]; + n += strlen(dp); + while (isspace(*dp)) dp++; + + for (i = NINCLUDE - 1; i >= 0; i--) + { + if (wraplist[i].file == NULL) + { + wraplist[i].file = dp; + break; + } + } + if (i < 0) + error(WARNING, "Too many -Xw directives"); + break; + + default: + error(WARNING, "Unknown extension option %c", c); + } + break; + + case '+': + Cplusplus++; + break; + + case 'u': /* -undef fuer GCC (dummy) */ + case 'l': /* -lang-c++ fuer GCC (dummy) */ + break; + + default: + break; + } + dp = "."; + fp = "<stdin>"; + fd = 0; + if (optind < argc) + { + if ((fp = strrchr(argv[optind], '/')) != NULL) + { + int len = fp - argv[optind]; + + dp = (char *) newstring((uchar *) argv[optind], len + 1, 0); + dp[len] = '\0'; + } + fp = (char *) newstring((uchar *) argv[optind], strlen(argv[optind]), 0); + if ((fd = open(fp, O_RDONLY)) <= 0) + error(FATAL, "Can't open input file %s", fp); + } + + if (optind + 1 < argc) + { + int fdo = creat(argv[optind + 1], 0666); + + if (fdo < 0) + error(FATAL, "Can't open output file %s", argv[optind + 1]); + + dup2(fdo, 1); + } + includelist[NINCLUDE - 1].always = 0; + includelist[NINCLUDE - 1].file = dp; + setsource(fp, -1, fd, NULL, 0); +} + + +/* memmove is defined here because some vendors don't provide it at + all and others do a terrible job (like calling malloc) */ + +#if !defined(__IBMC__) && !defined(_WIN32) && !defined(__GLIBC__) + +void * + memmove(void *dp, const void *sp, size_t n) +{ + unsigned char *cdp, *csp; + + if (n <= 0) + return 0; + cdp = dp; + csp = (unsigned char *) sp; + if (cdp < csp) + { + do + { + *cdp++ = *csp++; + } while (--n); + } + else + { + cdp += n; + csp += n; + do + { + *--cdp = *--csp; + } while (--n); + } + return 0; +} + +#endif + diff --git a/soltools/cpp/cpp.h b/soltools/cpp/cpp.h new file mode 100644 index 000000000000..34e18579c35a --- /dev/null +++ b/soltools/cpp/cpp.h @@ -0,0 +1,239 @@ +/* $Id: cpp.h,v 1.4 2006-06-20 05:07:28 hr Exp $ */ + +#define INS 32768 /* input buffer */ +#define OBS 8092 /* outbut buffer */ +#define NARG 32 /* Max number arguments to a macro */ +#define NINCLUDE 48 /* Max number of include directories (-I) */ +#define NIF 64 /* depth of nesting of #if */ +#define NINC 32 /* depth of nesting of #include */ + +#ifndef EOF +#define EOF (-1) +#endif + +#ifndef NULL +#define NULL 0 +#endif + +typedef unsigned char uchar; + +enum toktype +{ + END, UNCLASS, NAME, NUMBER, STRING, CCON, NL, WS, DSHARP, + EQ, NEQ, LEQ, GEQ, LSH, RSH, LAND, LOR, PPLUS, MMINUS, + ARROW, SBRA, SKET, LP, RP, DOT, AND, STAR, PLUS, MINUS, + TILDE, NOT, SLASH, PCT, LT, GT, CIRC, OR, QUEST, + COLON, ASGN, COMMA, SHARP, SEMIC, CBRA, CKET, + ASPLUS, ASMINUS, ASSTAR, ASSLASH, ASPCT, ASCIRC, ASLSH, + ASRSH, ASOR, ASAND, ELLIPS, + DSHARP1, NAME1, NAME2, DEFINED, UMINUS, ARCHITECTURE, IDENT, + COMMENT +}; + +enum kwtype +{ + KIF, KIFDEF, KIFNDEF, KELIF, KELSE, KENDIF, KINCLUDE, KINCLUDENEXT, + KIMPORT, KDEFINE, KUNDEF, KLINE, KERROR, KPRAGMA, KIDENT, KDEFINED, + KMACHINE, KLINENO, KFILE, KDATE, KTIME, KSTDC, KEVAL +}; + +#define ISDEFINED 0x01 /* has #defined value */ +#define ISKW 0x02 /* is PP keyword */ +#define ISUNCHANGE 0x04 /* can't be #defined in PP */ +#define ISMAC 0x08 /* builtin macro, e.g. __LINE__ */ +#define ISARCHITECTURE 0x10 /* architecture */ +#define ISACTIVE 0x80 /* is macro currently expanded */ + +#define EOB 0xFE /* sentinel for end of input buffer */ +#define EOFC 0xFD /* sentinel for end of input file */ +#define XPWS 1 /* token flag: white space to assure token sep. */ +#define XTWS 2 + +typedef struct token +{ + unsigned char type; + unsigned char flag; + unsigned int wslen; + unsigned int len; + uchar *t; + unsigned int identifier; /* used from macro processor to identify where a macro becomes valid again. */ +} Token; + +typedef struct tokenrow +{ + Token *tp; /* current one to scan */ + Token *bp; /* base (allocated value) */ + Token *lp; /* last+1 token used */ + int max; /* number allocated */ +} Tokenrow; + +typedef struct source +{ + char *filename; /* name of file of the source */ + int line; /* current line number */ + int lineinc; /* adjustment for \\n lines */ + uchar *inb; /* input buffer */ + uchar *inp; /* input pointer */ + uchar *inl; /* end of input */ + int fd; /* input source */ + int ifdepth; /* conditional nesting in include */ + int pathdepth; + int wrap; + struct source *next; /* stack for #include */ +} Source; + +typedef struct nlist +{ + struct nlist *next; + uchar *name; + int len; + Tokenrow *vp; /* value as macro */ + Tokenrow *ap; /* list of argument names, if any */ + char val; /* value as preprocessor name */ + char flag; /* is defined, is pp name */ + uchar *loc; /* location of definition */ +} Nlist; + +typedef struct includelist +{ + char deleted; + char always; + char *file; +} Includelist; + +typedef struct wraplist +{ + char *file; +} Wraplist; + +#define new(t) (t *)domalloc(sizeof(t)) +#define quicklook(a,b) (namebit[(a)&077] & (1<<((b)&037))) +#define quickset(a,b) namebit[(a)&077] |= (1<<((b)&037)) +extern unsigned long namebit[077 + 1]; + +enum errtype +{ + INFO, WARNING, ERROR, FATAL +}; + + +typedef struct macroValidator +{ + Nlist * pMacro; + unsigned int nTokenWhereMacroBecomesValid; + struct macroValidator * + pNext; +} MacroValidator; +typedef struct mvl +{ + MacroValidator * pFirst; + unsigned int nextFreeIdentifier; +} MacroValidatorList; + +void mvl_init( + MacroValidatorList * + out_pValidators); +void mvl_destruct( + MacroValidatorList * + out_pValidators); +/* Adds MacroValidator to the list. +*/ +void mvl_add( + MacroValidatorList * + inout_pValidators, + Nlist * in_pMacro, + Token * in_pTokenWhereMacroBecomesValid); +/* Updates all token pointers within the list, when the tokens have + moved, by + pTokenWhereMacroBecomesValid += in_nNrofTokens; + . + +void mvl_move( + MacroValidatorList * + inout_pValidators, + int in_nSpace); // in pointer units. +*/ +/* Checks if one of the validators within the list points to + the token in_pTokenToCheck. If so, the macro is set valid and + the validator is removed. +*/ +void mvl_check( + MacroValidatorList * + inout_pValidators, + Token * inout_pTokenToCheck); + +void tokenrow_zeroTokenIdentifiers(Tokenrow* trp); + +void expandlex(void); +void fixlex(void); +void setup(int, char **); +int gettokens(Tokenrow *, int); +int comparetokens(Tokenrow *, Tokenrow *); +Source *setsource(char *, int, int, char *, int); +void unsetsource(void); +void puttokens(Tokenrow *); +void process(Tokenrow *); +void *domalloc(int); +void dofree(void *); +void error(enum errtype, char *,...); +void flushout(void); +int fillbuf(Source *); +int trigraph(Source *); +int foldline(Source *); +Nlist *lookup(Token *, int); +void control(Tokenrow *); +void dodefine(Tokenrow *); +void doadefine(Tokenrow *, int); +void doinclude(Tokenrow *, int, int); +void doif(Tokenrow *, enum kwtype); +void expand(Tokenrow *, Nlist *, MacroValidatorList *); +void builtin(Tokenrow *, int); +int gatherargs(Tokenrow *, Tokenrow **, int *); +void substargs(Nlist *, Tokenrow *, Tokenrow **); +void expandrow(Tokenrow *, char *); +void maketokenrow(int, Tokenrow *); +Tokenrow *copytokenrow(Tokenrow *, Tokenrow *); +Token *growtokenrow(Tokenrow *); +Tokenrow *normtokenrow(Tokenrow *); +void adjustrow(Tokenrow *, int); +void movetokenrow(Tokenrow *, Tokenrow *); +void insertrow(Tokenrow *, int, Tokenrow *); +void peektokens(Tokenrow *, char *); +void doconcat(Tokenrow *); +Tokenrow *stringify(Tokenrow *); +int lookuparg(Nlist *, Token *); +long eval(Tokenrow *, int); +void genline(void); +void genimport(char *, int, char *, int); +void genwrap(int); +void setempty(Tokenrow *); +void makespace(Tokenrow *, Token *); +char *outnum(char *, int); +int digit(int); +uchar *newstring(uchar *, int, int); + +#define rowlen(tokrow) ((tokrow)->lp - (tokrow)->bp) + +extern char *outptr; +extern Token nltoken; +extern Source *cursource; +extern char *curtime; +extern int incdepth; +extern int ifdepth; +extern int ifsatisfied[NIF]; +extern int Mflag; +extern int Iflag; +extern int Pflag; +extern int Aflag; +extern int Lflag; +extern int Xflag; +extern int Vflag; +extern int Cflag; +extern int Dflag; +extern int Cplusplus; +extern int skipping; +extern Nlist *kwdefined; +extern Includelist includelist[NINCLUDE]; +extern Wraplist wraplist[NINCLUDE]; +extern char wd[]; + diff --git a/soltools/cpp/makefile.mk b/soltools/cpp/makefile.mk new file mode 100644 index 000000000000..533cf9a91ab7 --- /dev/null +++ b/soltools/cpp/makefile.mk @@ -0,0 +1,76 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=cpp +TARGETTYPE=CUI +NO_DEFAULT_STL=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +UWINAPILIB=$(0) +LIBSALCPPRT=$(0) + +# --- Files -------------------------------------------------------- + +OBJFILES= \ + $(OBJ)$/_cpp.obj \ + $(OBJ)$/_eval.obj \ + $(OBJ)$/_include.obj \ + $(OBJ)$/_lex.obj \ + $(OBJ)$/_macro.obj \ + $(OBJ)$/_mcrvalid.obj \ + $(OBJ)$/_nlist.obj \ + $(OBJ)$/_tokens.obj \ + $(OBJ)$/_unix.obj + +# nonstandard cpp options needed for Mac (-isysroot), +# needs the custom stgetopt defined here :/ +.IF "$(OS)" == "MACOSX" || "$(HAVE_GETOPT)" != "YES" +OBJFILES += $(OBJ)$/_getopt.obj +.ENDIF +.IF "$(HAVE_GETOPT)" == "YES" +CDEFS += -DHAVE_GETOPT +.ENDIF + +APP1TARGET = $(TARGET) +.IF "$(GUI)" != "OS2" +APP1STACK = 1000000 +.ENDIF +APP1LIBS = $(LB)$/$(TARGET).lib +APP1DEPN = $(LB)$/$(TARGET).lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/soltools/giparser/gen_info.cxx b/soltools/giparser/gen_info.cxx new file mode 100644 index 000000000000..838e46287b0c --- /dev/null +++ b/soltools/giparser/gen_info.cxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include <gen_info.hxx> +#include <gi_list.hxx> + + +GenericInfo::GenericInfo( const Simstr & i_sKey, + const Simstr & i_sValue, + const Simstr & i_sComment ) + : sKey(i_sKey), + sValue(i_sValue), + sComment(i_sComment), + dpSubList(0) +{ +} + +GenericInfo::GenericInfo( const GenericInfo & i_rInfo ) + : sKey(i_rInfo.sKey), + sValue(i_rInfo.sValue), + sComment(i_rInfo.sComment), + dpSubList(0) +{ + if ( i_rInfo.HasSubList() ) + { + dpSubList = new List_GenericInfo(i_rInfo.SubList()); + } +} + +GenericInfo::~GenericInfo() +{ + if ( dpSubList != 0 ) + delete dpSubList; +} + +GenericInfo & +GenericInfo::operator=( const GenericInfo & i_rInfo ) +{ + sKey = i_rInfo.sKey; + sValue = i_rInfo.sValue; + sComment = i_rInfo.sComment; + + if ( dpSubList != 0 ) + delete dpSubList; + if ( i_rInfo.HasSubList() ) + { + dpSubList = new List_GenericInfo(i_rInfo.SubList()); + } + else + dpSubList = 0; + + return *this; +} + +List_GenericInfo & +GenericInfo::CreateMyList() const +{ + return * ( const_cast<GenericInfo&>(*this).dpSubList = new List_GenericInfo); + +} + diff --git a/soltools/giparser/gi_list.cxx b/soltools/giparser/gi_list.cxx new file mode 100644 index 000000000000..5726a2bf0740 --- /dev/null +++ b/soltools/giparser/gi_list.cxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + + +#include <gi_list.hxx> + + +#include <gen_info.hxx> + + + +const char C_cKeySeparator = '/'; + + +List_GenericInfo::List_GenericInfo() +{ +} + +List_GenericInfo::List_GenericInfo( const List_GenericInfo & i_rList ) + : aChildren(i_rList.aChildren) +{ +} + +List_GenericInfo::~List_GenericInfo() +{ +} + +List_GenericInfo & +List_GenericInfo::operator=( const List_GenericInfo & i_rList ) +{ + aChildren = i_rList.aChildren; + return *this; +} + +const GenericInfo * +List_GenericInfo::operator[]( KeyPath i_sKeyPath ) const +{ + return const_cast< List_GenericInfo& >(*this)[i_sKeyPath]; +} + +GenericInfo * +List_GenericInfo::operator[]( KeyPath i_sKeyPath ) +{ + bool bExists = false; + const char * sNextPathSegment = 0; + sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath); + + if ( bExists ) + { + if ( sNextPathSegment == 0 ) + return (*it); + else + return (*it)->SubList()[sNextPathSegment]; + } + else + { + return 0; + } +} + +bool +List_GenericInfo::InsertInfo( GenericInfo * let_dpInfo, + bool i_bOverwrite ) +{ + if ( let_dpInfo == 0 ) + return false; + + bool bExists = false; + const char * sNextPathSegment = 0; + sub_iterator it = lower_bound(bExists, sNextPathSegment, let_dpInfo->Key() ); + + if ( ! bExists ) + { + aChildren.insert( it, let_dpInfo ); + } + else if ( i_bOverwrite ) + { + delete (*it); + (*it) = let_dpInfo; + } + else + { + delete let_dpInfo; + return false; + } + + return true; +} + +bool +List_GenericInfo::InsertInfoByPath( GenericInfo * let_dpInfo, + KeyPath i_sKeyPath, + bool i_bCreatePath, + bool i_bOverwrite ) +{ + if ( let_dpInfo == 0 ) + return false; + + if ( i_sKeyPath == 0 ? true : *i_sKeyPath == 0 ) + return InsertInfo(let_dpInfo, i_bOverwrite); + + bool bExists = false; + const char * sNextPathSegment = 0; + sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath); + + if ( bExists ) + { + return (*it)->SubList().InsertInfoByPath( + let_dpInfo, + sNextPathSegment, + i_bCreatePath, + i_bOverwrite ); + } + else if ( i_bCreatePath ) + { + Simstr aKey( i_sKeyPath, + 0, + sNextPathSegment - + ( *sNextPathSegment == 0 ? 0 : 1) + - i_sKeyPath ); + + GenericInfo * pNew = new GenericInfo(aKey); + InsertInfo(pNew,false); + + return pNew->SubList().InsertInfoByPath( + let_dpInfo, + sNextPathSegment, + i_bCreatePath, + i_bOverwrite ); + } + else + { + delete let_dpInfo; + return false; + } +} + +GenericInfo * +List_GenericInfo::ReleaseInfo( KeyPath i_sKeyPath ) +{ + bool bExists = false; + const char * sNextPathSegment = 0; + sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath ); + + if ( bExists ) + { + if ( *sNextPathSegment == 0 ) + return (*it); + else + return (*it)->SubList().ReleaseInfo(sNextPathSegment); + } + else + { + return 0; + } +} + +void +List_GenericInfo::DeleteInfo( KeyPath i_sKeyPath ) +{ + bool bExists = false; + const char * sNextPathSegment = 0; + sub_iterator it = lower_bound(bExists, sNextPathSegment, i_sKeyPath ); + + if ( bExists ) + { + if ( *sNextPathSegment == 0 ) + { + aChildren.remove(it); + } + else + { + (*it)->SubList().DeleteInfo(sNextPathSegment); + } + } +} + +List_GenericInfo::sub_iterator +List_GenericInfo::lower_bound( bool & o_bExists, + const char * & o_sNextPathSegment, + KeyPath i_sKeyPath ) +{ + o_sNextPathSegment = strchr(i_sKeyPath, '/'); + Simstr sKey( i_sKeyPath, (o_sNextPathSegment == 0 ? strlen(i_sKeyPath) : o_sNextPathSegment++ - i_sKeyPath) ); + GenericInfo aSearch(sKey); + + unsigned low = 0; + unsigned high = aChildren.size(); + + for ( unsigned cur = high / 2; high > low; cur = (low + high) / 2 ) + { + if ( *aChildren[cur] < aSearch ) + { + low = cur+1; + } + else + { + high = cur; + } + } // end for + + o_bExists = low < aChildren.size() + ? !(aSearch < *aChildren[low] ) + : false; + return &aChildren[low]; +} + diff --git a/soltools/giparser/gi_parse.cxx b/soltools/giparser/gi_parse.cxx new file mode 100644 index 000000000000..ad960e48a1e2 --- /dev/null +++ b/soltools/giparser/gi_parse.cxx @@ -0,0 +1,407 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include <gi_parse.hxx> + +#include <stdio.h> +#include <string.h> +#include <fstream> +#include <gilacces.hxx> + + +using namespace std; + + +const char * C_sLineEnd = "\r\n"; + + + +inline void +WriteStr( ostream & o_rOut, const Simstr & i_rStr ) +{ + o_rOut.write( i_rStr.str(), i_rStr.l() ); +} + +inline void +WriteStr( ostream & o_rOut, const char * i_rStr ) +{ + o_rOut.write( i_rStr, strlen(i_rStr) ); +} + +inline void +GenericInfo_Parser::SetError( E_Error i_eError ) +{ + eErrorCode = i_eError; + nErrorLine = nCurLine; +} + + +GenericInfo_Parser::GenericInfo_Parser() + : sCurParsePosition(""), + nCurLine(0), + nLevel(0), + bGoon(false), + // sCurComment, + eErrorCode(ok), + nErrorLine(0), + pResult(0), + pResource(0) +{ +} + +GenericInfo_Parser::~GenericInfo_Parser() +{ +} + +bool +GenericInfo_Parser::LoadList( GenericInfoList_Builder & o_rResult, + const Simstr & i_sSourceFileName ) +{ + ifstream aFile( i_sSourceFileName.str() ); + if ( aFile.fail() ) + { + SetError(cannot_open); + return false; + } + + aFile.seekg(0, ios::end); + UINT32 nTextSize = aFile.tellg(); + if ( nTextSize == 0 || nTextSize == UINT32(-1) ) + return true; + dpBuffer = new char[nTextSize+2]; + + aFile.seekg(0); + aFile.read( dpBuffer, nTextSize ); + aFile.close(); + + sFilePtr = dpBuffer; + char * sLastChar = dpBuffer + nTextSize - 1; + + while ( sFilePtr != sLastChar && *sFilePtr <= 32 ) + ++sCurParsePosition; + if ( sFilePtr == sLastChar ) + { + if ( *sFilePtr <= 32 ) + return true; + } + else while ( *sLastChar <= 32 ) + { + --sLastChar; + } + + *(sLastChar+1) = '\n'; + *(sLastChar+2) = '\0'; + + ResetState(o_rResult); + + for ( ReadLine(); bGoon; ReadLine() ) + { + bool bOk = InterpretLine(); + if ( !bOk) + { + SetError(syntax_error); + break; + } + } + + if ( nLevel > 0 && eErrorCode == ok) + { + SetError(unexpected_eof); + } + else if ( nLevel < 0 ) + { + SetError(unexpected_list_end); + } + + delete [] dpBuffer; + dpBuffer = 0; + sFilePtr = 0; + + return eErrorCode == ok; +} + +bool +GenericInfo_Parser::SaveList( const Simstr & i_rOutputFile, + GenericInfoList_Browser & io_rListBrowser ) +{ + ofstream aFile( i_rOutputFile.str() ); + if ( aFile.fail() ) + { + SetError(cannot_open); + return false; + } + + ResetState(io_rListBrowser); + + WriteList(aFile); + + aFile.close(); + return eErrorCode == ok; +} + +void +GenericInfo_Parser::ResetState( GenericInfoList_Builder & io_rResult ) +{ + sCurParsePosition = ""; + nCurLine = 0; + nLevel = 0; + bGoon = true; + sCurComment = ""; + eErrorCode = ok; + nErrorLine = 0; + pResult = &io_rResult; + pResource = 0; +} + +void +GenericInfo_Parser::ResetState( GenericInfoList_Browser & io_rSrc ) +{ + sCurParsePosition = ""; + nCurLine = 0; + nLevel = 0; + bGoon = false; + sCurComment = ""; + eErrorCode = ok; + nErrorLine = 0; + pResult = 0; + pResource = &io_rSrc; +} + + +void +GenericInfo_Parser::ReadLine() +{ + if ( *sFilePtr == '\0' ) // See initialising of dpBuffer and sLastChar in LoadList(). + { + bGoon = false; + return; + } + + sCurParsePosition = sFilePtr; + while ( *sFilePtr != '\n' ) + ++sFilePtr; + nCurLine++; + + // Remove leading and trailing whitespace from line: + while ( sCurParsePosition != sFilePtr && *sCurParsePosition <= 32 ) + ++sCurParsePosition; + + char * sEndOfLine = sFilePtr; + while ( sEndOfLine != sCurParsePosition && *sEndOfLine <= 32 ) + --sEndOfLine; + if ( sCurParsePosition != sEndOfLine || *sCurParsePosition > 32 ) + ++sEndOfLine; + *sEndOfLine = '\0'; + + ++sFilePtr; // Go beyond line end to first character of next line. +} + +bool +GenericInfo_Parser::InterpretLine() +{ + switch ( ClassifyLine() ) + { + case lt_key: ReadKey(); + break; + case lt_open_list: PushLevel_Read(); + break; + case lt_close_list: PopLevel_Read(); + break; + case lt_comment: AddCurLine2CurComment(); + break; + case lt_empty: AddCurLine2CurComment(); + break; + default: + return false; + } + return true; +} + +GenericInfo_Parser::E_LineType +GenericInfo_Parser::ClassifyLine() +{ + switch ( *sCurParsePosition ) + { + case '{': return lt_open_list; + case '}': return lt_close_list; + case '#': return lt_comment; + case '\0': return lt_empty; + } + + return lt_key; +} + +void +GenericInfo_Parser::ReadKey() +{ + const char * pSearch = sCurParsePosition; + + for ( ; *pSearch > 32; ++pSearch ) ; + UINT32 nKeyLength = pSearch - sCurParsePosition; + + for ( ; *pSearch <= 32 && *pSearch > '\0'; ++pSearch ) ; + + pResult->AddKey( sCurParsePosition, nKeyLength, + pSearch, strlen(pSearch), + sCurComment.str(), sCurComment.l() + ); + sCurComment = ""; +} + +void +GenericInfo_Parser::PushLevel_Read() +{ + nLevel++; + pResult->OpenList(); +} + +void +GenericInfo_Parser::PopLevel_Read() +{ + nLevel--; + pResult->CloseList(); +} + +void +GenericInfo_Parser::AddCurLine2CurComment() +{ + sCurComment += sCurParsePosition; + sCurComment += C_sLineEnd; +} + +void +GenericInfo_Parser::WriteList( ostream & o_rFile ) +{ + static char sBuffer[32000]; + + for ( bGoon = pResource->Start_CurList(); + bGoon; + bGoon = pResource->NextOf_CurList() ) + { + pResource->Get_CurComment(&sBuffer[0]); + WriteComment(o_rFile,sBuffer); + + pResource->Get_CurKey(&sBuffer[0]); + WriteKey(o_rFile,sBuffer); + + pResource->Get_CurValue(&sBuffer[0]); + WriteValue(o_rFile,sBuffer); + + if ( pResource->HasSubList_CurKey() ) + { + PushLevel_Write(); + +/* + WriteIndentation(); + o_rFile.write("{",1); + o_rFile.write(C_sLineEnd, C_nLineEndLength); +*/ + WriteList(o_rFile); + +/* + WriteIndentation(); + o_rFile.write("}",1); + o_rFile.write(C_sLineEnd, C_nLineEndLength); +*/ + PopLevel_Write(); + } + } // end for +} + +void +GenericInfo_Parser::PushLevel_Write() +{ + nLevel++; + pResource->Push_CurList(); +} + +void +GenericInfo_Parser::PopLevel_Write() +{ + nLevel--; + pResource->Pop_CurList(); +} + +void +GenericInfo_Parser::WriteComment( ostream & o_rFile, + const char * i_sStr ) +{ + WriteStr( o_rFile, i_sStr ); + if ( i_sStr[ strlen(i_sStr)-1 ] != '\n' ) + WriteStr( o_rFile, C_sLineEnd ); +} + +void +GenericInfo_Parser::WriteKey( ostream & o_rFile, + const char * i_sStr ) +{ + WriteIndentation(o_rFile); + WriteStr( o_rFile, i_sStr ); +} + +void +GenericInfo_Parser::WriteValue( ostream & o_rFile, + const char * i_sStr ) +{ + if ( i_sStr != 0 ? strlen(i_sStr) > 0 : false ) + { + WriteStr(o_rFile," "); + WriteStr(o_rFile,i_sStr); + } + + WriteStr(o_rFile,C_sLineEnd); +} + +void +GenericInfo_Parser::WriteIndentation( ostream & o_rFile ) +{ + const int nIndentBound = 60; + + static const char sIndentation[nIndentBound+1] = + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; + + if ( nLevel == 0 ) + return; + + if ( nLevel <= nIndentBound ) + o_rFile.write( sIndentation, nLevel ); + else + { + INT16 iLevel = nLevel; + for ( ; iLevel > nIndentBound; iLevel-=nIndentBound ) + o_rFile.write( sIndentation, nIndentBound ); + o_rFile.write( sIndentation, iLevel ); + } +} + + + diff --git a/soltools/giparser/makefile.mk b/soltools/giparser/makefile.mk new file mode 100644 index 000000000000..bab26d2e7e1b --- /dev/null +++ b/soltools/giparser/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=soltools_giparser +TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE + +.IF "$(GUI)" == "OS2" +STL_OS2_BUILDING=1 +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +OBJFILES=\ + $(OBJ)$/gen_info.obj \ + $(OBJ)$/gi_list.obj \ + $(OBJ)$/gi_parse.obj \ + $(OBJ)$/st_gilrw.obj + +SLOFILES=\ + $(SLO)$/gen_info.obj \ + $(SLO)$/gi_list.obj \ + $(SLO)$/gi_parse.obj \ + $(SLO)$/st_gilrw.obj + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/soltools/giparser/st_gilrw.cxx b/soltools/giparser/st_gilrw.cxx new file mode 100644 index 000000000000..d57d8811cb31 --- /dev/null +++ b/soltools/giparser/st_gilrw.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + + +#include <st_gilrw.hxx> + +#include <gen_info.hxx> +#include <gi_list.hxx> +#include <gi_parse.hxx> +#include <simstr.hxx> +#include <st_list.hxx> + + +using namespace std; + + +ST_InfoListReader::ST_InfoListReader() +{ + dpParser = new GenericInfo_Parser; +} + +ST_InfoListReader::~ST_InfoListReader() +{ + delete dpParser; +} + + +bool +ST_InfoListReader::LoadList( List_GenericInfo & o_rList, + const Simstr & i_sFileName ) +{ + aListStack.push_back(&o_rList); + return dpParser->LoadList(*this, i_sFileName); +} + +ST_InfoListReader::E_Error +ST_InfoListReader::GetLastError( UINT32 * o_pErrorLine ) const +{ + return dpParser->GetLastError(o_pErrorLine); +} + +void +ST_InfoListReader::AddKey( const char * i_sKey, + UINT32 i_nKeyLength, + const char * i_sValue, + UINT32 i_nValueLength, + const char * i_sComment, + UINT32 i_nCommentLength ) +{ + Simstr sKey(i_sKey, i_nKeyLength); + Simstr sValue(i_sValue, i_nValueLength); + Simstr sComment(i_sComment, i_nCommentLength); + + pCurKey = new GenericInfo(sKey, sValue, sComment); + aListStack.back()->InsertInfo( pCurKey ); +} + +void +ST_InfoListReader::OpenList() +{ + if ( pCurKey == 0 ) + { + cerr << "error: '{' without key found." << endl; + exit(1); + } + + aListStack.push_back( & pCurKey->SubList() ); +} + +void +ST_InfoListReader::CloseList() +{ + if ( aListStack.size() == 0 ) + { + cerr << "error: '}' without corresponding '}' found." << endl; + exit(1); + } + + aListStack.pop_back(); +} + + +#if 0 +ST_InfoListWriter::ST_InfoListWriter() +{ + +} + +ST_InfoListWriter::~ST_InfoListWriter() + +bool +ST_InfoListWriter::SaveList( const Simstr & i_sFileName, + List_GenericInfo & io_rList ) +{ + +} + +E_Error +ST_InfoListWriter::GetLastError() const +{ + return dpParser->GetLastError(o_pErrorLine); +} + +bool +ST_InfoListWriter::Start_CurList() +{ + +} + +bool +ST_InfoListWriter::NextOf_CurList() +{ + +} + +void +ST_InfoListWriter::Get_CurKey( char * o_rKey ) const +{ + +} + +void +ST_InfoListWriter::Get_CurValue( char * o_rValue ) const +{ + +} + +void +ST_InfoListWriter::Get_CurComment( char * o_rComment ) const +{ + +} + +bool +ST_InfoListWriter::HasSubList_CurKey() const +{ + +} + +void +ST_InfoListWriter::Push_CurList() +{ + +} + +void +ST_InfoListWriter::Pop_CurList() +{ + +} +#endif + + diff --git a/soltools/inc/gen_info.hxx b/soltools/inc/gen_info.hxx new file mode 100644 index 000000000000..fae89435bed7 --- /dev/null +++ b/soltools/inc/gen_info.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef GEN_INFO_HXX +#define GEN_INFO_HXX + + +#include "simstr.hxx" +#include <string.h> + + + +class List_GenericInfo; + + +/** Holds generic informations in a simple hierarchical format. +*/ +class GenericInfo +{ + public: + // LIFECFYCLE + GenericInfo( + const Simstr & i_sKey, + const Simstr & i_sValue = Simstr::null_(), + const Simstr & i_sComment = Simstr::null_() ); + GenericInfo( + const GenericInfo & i_rInfo ); + ~GenericInfo(); + + // OPERATORS + GenericInfo & operator=( + const GenericInfo & i_rInfo ); + bool operator<( + const GenericInfo & i_rInfo ) const +#ifdef UNX + { return strcasecmp(sKey.str(),i_rInfo.sKey.str()) < 0; } +#else + { return stricmp(sKey.str(),i_rInfo.sKey.str()) < 0; } +#endif + // INFO + const Simstr & Key() const { return sKey; } + const Simstr & Value() const { return sValue; } + const Simstr & Comment() const { return sComment; } + bool HasSubList() const { return dpSubList != 0; } + + const List_GenericInfo & + SubList() const { return HasSubList() ? *dpSubList : CreateMyList(); } + // ACCESS + List_GenericInfo & + SubList() { return HasSubList() ? *dpSubList : CreateMyList(); } + + private: + /// @precond dpSubList == 0 . + List_GenericInfo & CreateMyList() const; + + // DATA + Simstr sKey; + Simstr sValue; + Simstr sComment; + List_GenericInfo * dpSubList; /// Owned by this object. +}; + + +#endif + diff --git a/soltools/inc/gi_list.hxx b/soltools/inc/gi_list.hxx new file mode 100644 index 000000000000..ad7f8d5e93f8 --- /dev/null +++ b/soltools/inc/gi_list.hxx @@ -0,0 +1,215 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_GI_LIST_HXX +#define SOLTOOLS_GI_LIST_HXX + + +#include "st_list.hxx" + + +class GenericInfo; + +/** Holds set of generic informations in a sorted list. + + At different places, methods of this class have a parameter, + whose name includes "path". Those are paths like this: + + src370/drives/o: + + which are used to access GenericInfo keys in deep search through + the lists and their sublists. +*/ +class List_GenericInfo +{ + public: + // TYPES + class const_iterator + { + public: + const GenericInfo & operator*() const; + const_iterator & operator++(); + bool operator==( const const_iterator & ) const; + bool operator!=( const const_iterator & ) const; + + const_iterator(); + const_iterator( const DynamicList< GenericInfo >::const_iterator & ); + private: DynamicList< GenericInfo >::const_iterator it; + }; + class iterator + { public: + GenericInfo & operator*() const; + iterator & operator++(); + bool operator==( const iterator & ) const; + bool operator!=( const iterator & ) const; + + iterator(); + iterator( const DynamicList< GenericInfo >::iterator & ); + private: DynamicList< GenericInfo >::iterator it; + }; + + typedef const char * KeyPath; + + // LIFECYCLE + List_GenericInfo(); + List_GenericInfo( + const List_GenericInfo & + i_rList ); + ~List_GenericInfo(); + + // OPERATORS + List_GenericInfo & operator=( + const List_GenericInfo & + i_rList ); + const GenericInfo * operator[]( + KeyPath i_sKeyPath ) const; + GenericInfo * operator[]( + KeyPath i_sKeyPath ); + + // OPERATIONS + bool InsertInfo( + GenericInfo * let_dpInfo, /// Will be owned by this object. + bool i_bOverwrite = true ); + bool InsertInfoByPath( + GenericInfo * let_dpInfo, /// Will be owned by this object. + KeyPath i_sKeyPath, + bool i_bCreatePath, + bool i_bOverwrite = true ); + + GenericInfo * ReleaseInfo( /// Removes the GenericInfo from its parent. + KeyPath i_sKeyPath ); + + void DeleteInfo( + KeyPath i_sKeyPath ); + + // INFO + unsigned Size() const; + + const_iterator Begin() const; + const_iterator End() const; + + // ACCESS + iterator Begin(); + iterator End(); + + private: + typedef DynamicList< GenericInfo >::iterator sub_iterator; + + sub_iterator lower_bound( + bool & o_bExists, + const char * & o_sNextPathSegment, + KeyPath i_sKeyPath ); + + DynamicList< GenericInfo > + aChildren; +}; + + +// IMPLEMENTATION + + +inline const GenericInfo & +List_GenericInfo:: +const_iterator::operator*() const + { return *(*it); } + +inline List_GenericInfo::const_iterator & +List_GenericInfo:: +const_iterator::operator++() + { ++it; return *this; } + +inline bool +List_GenericInfo:: +const_iterator::operator==( const const_iterator & i_rIter ) const + { return it == i_rIter.it; } + +inline bool +List_GenericInfo:: +const_iterator::operator!=( const const_iterator & i_rIter ) const + { return it != i_rIter.it; } + +inline List_GenericInfo:: +const_iterator::const_iterator() + : it(0) { } + +inline List_GenericInfo:: +const_iterator::const_iterator( const DynamicList< GenericInfo >::const_iterator & i_rDynListIter ) + : it(i_rDynListIter) { } + + +inline GenericInfo & +List_GenericInfo:: +iterator::operator*() const + { return *(*it); } + +inline List_GenericInfo::iterator & +List_GenericInfo:: +iterator::operator++() + { ++it; return *this; } + +inline bool +List_GenericInfo:: +iterator::operator==( const iterator & i_rIter ) const + { return it == i_rIter.it; } + +inline bool +List_GenericInfo:: +iterator::operator!=( const iterator & i_rIter ) const + { return it != i_rIter.it; } + +inline List_GenericInfo:: +iterator::iterator() + : it(0) { } + +inline List_GenericInfo:: +iterator::iterator( const DynamicList< GenericInfo >::iterator & i_rDynListIter ) + : it(i_rDynListIter) { } + +inline unsigned +List_GenericInfo::Size() const + { return aChildren.size(); } + +inline List_GenericInfo::const_iterator +List_GenericInfo::Begin() const + { return aChildren.begin(); } + +inline List_GenericInfo::const_iterator +List_GenericInfo::End() const + { return aChildren.end(); } + +inline List_GenericInfo::iterator +List_GenericInfo::Begin() + { return aChildren.begin(); } + +inline List_GenericInfo::iterator +List_GenericInfo::End() + { return aChildren.end(); } + + + +#endif + diff --git a/soltools/inc/gi_parse.hxx b/soltools/inc/gi_parse.hxx new file mode 100644 index 000000000000..636e3bffcb9c --- /dev/null +++ b/soltools/inc/gi_parse.hxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SOLTOOLS_GI_PARSE_HXX +#define SOLTOOLS_GI_PARSE_HXX + +#include "simstr.hxx" +#include "gilacces.hxx" +#include <fstream> + +class GenericInfoList_Builder; +class GenericInfoList_Browser; + +/** Reads generic information files into a simple structure in memory. + +Information files used by this parser have the following format: + +key [value] +{ + key [value] + key [value] + { + key [value] + ... + ... + } +} +key [value] +... +... + +*/ + + +class GenericInfo_Parser : public GenericInfoParseTypes +{ + public: + typedef unsigned long UINT32; + typedef short INT16; + + GenericInfo_Parser(); + ~GenericInfo_Parser(); + + /** reads a information file and stores the data in a + List_GenericInfo + */ + bool LoadList( + GenericInfoList_Builder & + o_rResult, + const Simstr & i_sSourceFileName ); + + /** save the InformationList to rSourceFile + returns false on error + */ + bool SaveList( + const Simstr & i_rOutputFile, + GenericInfoList_Browser & + io_rListBrowser ); + + E_Error GetLastError( + UINT32 * o_pErrorLine = 0 ) const; + + private: + enum E_LineType + { + lt_empty = 0, + lt_key, + lt_open_list, + lt_close_list, + lt_comment + }; + + void SetError( + E_Error i_eError ); + void ResetState( + GenericInfoList_Builder & + io_rResult ); + void ResetState( + GenericInfoList_Browser & + io_rSrc ); + + void ReadLine(); + bool InterpretLine(); + E_LineType ClassifyLine(); + + void ReadKey(); + void PushLevel_Read(); /// When list is opened by '{': + void PopLevel_Read(); /// When list is closed by '}': + void AddCurLine2CurComment(); + + void WriteList( + std::ostream & o_rFile ); + + void PushLevel_Write(); /// When SubList is pushed in pResource + void PopLevel_Write(); /// When SubList is popped in pResource + + void WriteComment( + std::ostream & o_rFile, + const char * i_sStr ); + void WriteKey( + std::ostream & o_rFile, + const char * i_sStr ); + void WriteValue( + std::ostream & o_rFile, + const char * i_sStr ); + void WriteIndentation( + std::ostream & o_rFile ); + + // DATA + const char * sCurParsePosition; + + UINT32 nCurLine; + INT16 nLevel; + bool bGoon; + + Simstr sCurComment; + + E_Error eErrorCode; + UINT32 nErrorLine; + + GenericInfoList_Builder * + pResult; + GenericInfoList_Browser * + pResource; + + char * dpBuffer; + char * sFilePtr; +}; + + +inline GenericInfo_Parser::E_Error +GenericInfo_Parser::GetLastError( UINT32 * o_pErrorLine ) const +{ + if ( o_pErrorLine != 0 ) + *o_pErrorLine = nErrorLine; + return eErrorCode; +} + + +#endif + + diff --git a/soltools/inc/gilacces.hxx b/soltools/inc/gilacces.hxx new file mode 100644 index 000000000000..f9dd4c21f4e3 --- /dev/null +++ b/soltools/inc/gilacces.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_GILACCES_HXX +#define SOLTOOLS_GILACCES_HXX + + + +class GenericInfoParseTypes +{ + public: + enum E_Error + { + ok = 0, + cannot_open, + unexpected_eof, + syntax_error, + unexpected_list_end + }; +}; + + + +/** This class is an abstract interface for a service, which + builds a memory structure out of a generic information + structure, read from a file or other stream. + + There may be different implementations, which build different kinds + of memory structures. +*/ +class GenericInfoList_Builder +{ + public: + typedef unsigned long UINT32; + + virtual ~GenericInfoList_Builder() {} + + virtual void AddKey( + const char * i_sKey, + UINT32 i_nKeyLength, + const char * i_sValue, + UINT32 i_nValueLength, + const char * i_sComment, + UINT32 i_nCommentLength ) = 0; + + virtual void OpenList() = 0; + virtual void CloseList() = 0; +}; + + +/** This class is an abstract interface for a service, which + returns the values of a generic information tree out of + a memory structure. + + There may be different implementations, which browse different + kinds of memory structures. +*/ +class GenericInfoList_Browser +{ + public: + virtual ~GenericInfoList_Browser() {} + + virtual bool Start_CurList() = 0; + virtual bool NextOf_CurList() = 0; + + virtual void Get_CurKey( + char * o_rKey ) const = 0; + virtual void Get_CurValue( + char * o_rValue ) const = 0; + virtual void Get_CurComment( + char * o_rComment ) const = 0; + virtual bool HasSubList_CurKey() const = 0; + + virtual void Push_CurList() = 0; + virtual void Pop_CurList() = 0; +}; + + +#endif + diff --git a/soltools/inc/pch/precompiled_soltools.cxx b/soltools/inc/pch/precompiled_soltools.cxx new file mode 100644 index 000000000000..186dcaba7488 --- /dev/null +++ b/soltools/inc/pch/precompiled_soltools.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_soltools.hxx" + diff --git a/soltools/inc/pch/precompiled_soltools.hxx b/soltools/inc/pch/precompiled_soltools.hxx new file mode 100644 index 000000000000..ef1d1b1f0a1b --- /dev/null +++ b/soltools/inc/pch/precompiled_soltools.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:01.811113 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/soltools/inc/simstr.hxx b/soltools/inc/simstr.hxx new file mode 100644 index 000000000000..883db0d96bdf --- /dev/null +++ b/soltools/inc/simstr.hxx @@ -0,0 +1,223 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_SIMSTR_HXX +#define SOLTOOLS_SIMSTR_HXX + + +class Simstr /// Simple string class. +{ +// INTERFACE + public: + // LIFECYCLE + Simstr( + const char * str = 0); + Simstr( /** Creates Simstr out of a copy of the first + 'nrOfBytes' bytes of 'anyBytes'. + Adds a '\0' at the end. */ + const char * anybytes, + int nrOfBytes); + Simstr( /** Creates Simstr out of a copy of the described bytes within 'anyBytes'. + Adds a '\0' at the end. */ + const char * anybytes, + int firstBytesPos, + int nrOfBytes ); + Simstr( /// Creates Simstr of 'anzahl' times 'c'. + char c, + int anzahl); + Simstr( + const Simstr & S); + ~Simstr(); + + + // OPERATORS + operator const char*() const; + + Simstr & operator=( + const Simstr & S ); + + Simstr operator+( + const Simstr & S ) const; + Simstr & operator+=( + const Simstr & S ); + Simstr & operator+=( + const char * s ); + + bool operator==( + const Simstr & S ) const; + bool operator!=( + const Simstr & S ) const; + bool operator<( + const Simstr & S ) const; + bool operator>( + const Simstr & S ) const; + bool operator<=( + const Simstr & S ) const; + bool operator>=( + const Simstr & S ) const; + // INFO + static const Simstr & + null_(); + + const char * str() const; + int l() const; // Length of string without '\0' at end. + char * s(); // ATTENTION !!! // Only to be used, when a function needs a 'char*' but + // nevertheless THAT WILL BE NOT CHANGED! + // Typecasts to 'const char*' are performed automatically. + char get( + int n) const; + char get_front() const; + char get_back() const; + Simstr get( + int startPos, + int anzahl ) const; + Simstr get_front( + int anzahl ) const; + Simstr get_back( + int anzahl ) const; + + int pos_first( + char c ) const; + int pos_first_after( + char c, + int startSearchPos ) const; + int pos_last( + char c ) const; + int pos_first( + const Simstr & S ) const; + int pos_last( + const Simstr & S ) const; + int count( + char c ) const; + bool is_empty() const; // Only true if object == "". + bool is_no_text() const; // String may contain spaces or tabs. + + Simstr get_first_token( + char c ) const; + Simstr get_last_token( + char c ) const; + + // ACCESS + char & ch( /** Reference to sz[n]. Allows change of this char. + !!! No safety, if n is out of the allowed range! */ + int n ); + + // OPERATIONS + void insert( + int pos, + char c ); + void push_front( + char c ); + void push_back( + char c ); + void insert( + int pos, + const Simstr & S ); + void push_front( + const Simstr & S ); + void push_back( + const Simstr & S ); + + void remove( + int pos, + int anzahl = 1 ); + void remove_trailing_blanks(); + void pop_front( + int anzahl = 1 ); + void pop_back( + int anzahl = 1 ); + void rem_back_from( + int removeStartPos ); + void remove_all( + char c ); + void remove_all( // Starts search left. + const Simstr & S ); + void strip( + char c ); // Removes all characters == c from front and back. + // c == ' ' removes also TABs !!! + void empty(); // Changes object to the value "". + + void replace( + int pos, + char c ); + void replace( + int startPos, + int anzahl, + const Simstr & S ); + void replace_all( + char oldCh, + char newCh ); + void replace_all( + const Simstr & oldS, + const Simstr & newS ); + void to_lower(); + + Simstr take_first_token( /// Token is removed from the Simstr. + char c ); + Simstr take_last_token( /// Token is removed from the Simstr. + char c ); + private: + // DATA + char * sz; + int len; +}; + +// Simstr - char* / char - concatenations +Simstr operator+(const char * str, const Simstr & S); +Simstr operator+(const Simstr & S, const char * str); +Simstr operator+(char c, const Simstr & S); +Simstr operator+(const Simstr & S, char c); + +// Simstr - char* - comparison operators +bool operator==(const Simstr & S, const char * str); +bool operator!=(const Simstr & S, const char * str); +bool operator<(const Simstr & S, const char * str); +bool operator>(const Simstr & S, const char * str); +bool operator<=(const Simstr & S, const char * str); +bool operator>=(const Simstr & S, const char * str); +bool operator==(const char * str, const Simstr & S); +bool operator!=(const char * str, const Simstr & S); +bool operator<(const char * str, const Simstr & S); +bool operator>(const char * str, const Simstr & S); +bool operator<=(const char * str, const Simstr & S); +bool operator>=(const char * str, const Simstr & S); + + +inline const char * +Simstr::str() const { return sz; } +inline char * +Simstr::s() { return sz; } +inline int +Simstr::l() const { return len; } +inline +Simstr::operator const char*() const { return sz; } +inline bool +Simstr::is_empty() const { return len == 0; } + + +#endif + diff --git a/soltools/inc/st_gilrw.hxx b/soltools/inc/st_gilrw.hxx new file mode 100644 index 000000000000..b70c52e1e75f --- /dev/null +++ b/soltools/inc/st_gilrw.hxx @@ -0,0 +1,125 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_ST_GILRW_HXX +#define SOLTOOLS_ST_GILRW_HXX + + +#include "gilacces.hxx" +#include "st_list.hxx" + +class Simstr; +class List_GenericInfo; +class GenericInfo; +class GenericInfo_Parser; + +class ST_InfoListReader : public GenericInfoParseTypes, + private GenericInfoList_Builder +{ + public: + // LIFECYCLE + ST_InfoListReader(); + ~ST_InfoListReader(); + // OPERATIONS + bool LoadList( + List_GenericInfo & o_rList, + const Simstr & i_sFileName ); + // INFO + E_Error GetLastError( + UINT32 * o_pErrorLine = 0 ) const; + private: + // Interface GenericInfoList_Builder + virtual void AddKey( + const char * i_sKey, + UINT32 i_nKeyLength, + const char * i_sValue, + UINT32 i_nValueLength, + const char * i_sComment, + UINT32 i_nCommentLength ); + + virtual void OpenList(); + virtual void CloseList(); + + // Forbid copies: + ST_InfoListReader( const ST_InfoListReader & ); + ST_InfoListReader & operator=( const ST_InfoListReader & ); + + // DATA + GenericInfo_Parser * + dpParser; + + ST_List< List_GenericInfo * > + aListStack; + GenericInfo * pCurKey; +}; + +class ST_InfoListWriter : public GenericInfoParseTypes, + private GenericInfoList_Browser +{ + public: + // LIFECYCLE + ST_InfoListWriter(); + ~ST_InfoListWriter(); + // OPERATIONS + bool SaveList( + const Simstr & i_sFileName, + List_GenericInfo & io_rList ); + + // INFO + E_Error GetLastError() const; + + private: + // Interface GenericInfoList_Browser + virtual bool Start_CurList(); + virtual bool NextOf_CurList(); + + virtual void Get_CurKey( + char * o_rKey ) const; + virtual void Get_CurValue( + char * o_rValue ) const; + virtual void Get_CurComment( + char * o_rComment ) const; + virtual bool HasSubList_CurKey() const; + + virtual void Push_CurList(); + virtual void Pop_CurList(); + + // Forbid copies: + ST_InfoListWriter( const ST_InfoListWriter & ); + ST_InfoListWriter & operator=( const ST_InfoListWriter & ); + + // DATA + GenericInfo_Parser * + dpParser; + + ST_List< List_GenericInfo * > + aListStack; + GenericInfo * pCurKey; +}; + +#endif + diff --git a/soltools/inc/st_list.hxx b/soltools/inc/st_list.hxx new file mode 100644 index 000000000000..adc791f7fdf2 --- /dev/null +++ b/soltools/inc/st_list.hxx @@ -0,0 +1,330 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_ST_LIST_HXX +#define SOLTOOLS_ST_LIST_HXX + +#include <string.h> +#include <iostream> +#include <stdlib.h> + +template <class XX> +class ST_List /// Soltools-List. +{ + public : + typedef XX * iterator; + typedef const XX * const_iterator; + + // LIFECYCLE + ST_List(); + ST_List( + const ST_List<XX> & i_rList ); + virtual ~ST_List() { } + + // OPERATORS + ST_List<XX> & operator=( + const ST_List<XX> & i_rList ); + + const XX & operator[]( + unsigned n) const + { return elem(n); } + XX & operator[]( + unsigned n) + { return elem(n); } + // OPERATIONS + void reserve( + unsigned i_nSize ) + { alloc(i_nSize,true); } + void insert( + iterator i_aPos, + const XX & elem_ ) + { Insert(i_aPos-begin(), elem_); } + virtual void Insert( + unsigned pos, + const XX & elem ); + void push_back( + const XX & elem_) + { Insert(size(),elem_); } + void remove( + iterator i_aPos ) + { Remove(i_aPos-begin()); } + virtual void Remove( + unsigned pos ); + void pop_back() { Remove(size()-1); } + void erase_all() { while (size()) Remove(size()-1); } + + // INQUIRY + const_iterator begin() const { return &inhalt[0]; } + const_iterator end() const { return &inhalt[len]; } + + const XX & front() const { return elem(0); } + const XX & back() const { return elem(len-1); } + + unsigned size() const { return len; } + unsigned space() const { return allocated; } + bool is_valid_index( + unsigned n) const + { return n < len; } + // ACCESS + iterator begin() { return &inhalt[0]; } + iterator end() { return &inhalt[len]; } + + XX & front() { return elem(0); } + XX & back() { return elem(len-1); } + + protected: + void checkSize( + unsigned newLength); + void alloc( + unsigned newSpace, + bool re = false ); + + const XX & elem( + unsigned n ) const + { return inhalt[n]; } + XX & elem( + unsigned n ) + { return inhalt[n]; } + // DATA + XX * inhalt; + unsigned len; + unsigned allocated; +}; + + + +template <class XY> +class DynamicList : public ST_List< XY* > +{ + public: + DynamicList(); + DynamicList( + const DynamicList<XY> & + i_rList ); + virtual ~DynamicList(); /// Deletes all member pointers + + DynamicList<XY> & operator=( + const DynamicList<XY> & + i_rList ); + + virtual void Insert( + unsigned pos, + XY * const & elem ); + virtual void Remove( + unsigned pos ); +}; + + + +template <class XX> +ST_List<XX>::ST_List() + : inhalt(0), + len(0), + allocated(0) +{ + alloc(1); +} + +template <class XX> +ST_List<XX>::ST_List( const ST_List<XX> & i_rList ) + : inhalt(0), + len(0), + allocated(0) +{ + alloc(i_rList.size()); + + for ( const_iterator it = i_rList.begin(); + it != i_rList.end(); + ++it ) + { + push_back(*it); + } +} + +template <class XX> +ST_List<XX> & +ST_List<XX>::operator=( const ST_List<XX> & i_rList ) +{ + for ( const_iterator it = i_rList.begin(); + it != i_rList.end(); + ++it ) + { + push_back(*it); + } + return *this; +} + +template <class XX> +void +ST_List<XX>::Insert(unsigned pos, const XX & elem_) +{ + if ( pos > len ) + return; + + checkSize(len+2); + for ( unsigned p = len; p > pos; --p) + { + inhalt[p] = inhalt[p-1]; + } + inhalt[pos] = elem_; + len++; +} + + +template <class XX> +void +ST_List<XX>::Remove(unsigned pos) +{ + if ( pos >= len ) + return; + len--; + for ( unsigned p = pos; p < len; ++p) + { + inhalt[p] = inhalt[p+1]; + } +} + + +// Protected: +template <class XX> +void +ST_List<XX>::checkSize(unsigned newLength) +{ + // neuen Platzbedarf pruefen: + unsigned newSpace = space(); + if (newLength >= newSpace) + { + if (!newSpace) + newSpace = 1; + const unsigned nBorder = 2000000000; + while(newLength >= newSpace) + { + if (newSpace < nBorder) + newSpace <<= 1; + else + { + std::cerr << "List becomes too big" << std::endl; + exit(1); + } + } + } + + // Veraenderung ?: + if (newSpace != space()) + alloc(newSpace,true); +} + +template <class XX> +void +ST_List<XX>::alloc( unsigned newSpace, + bool re ) +{ + XX * pNew = new XX[newSpace]; + + if (inhalt != 0) + { + if (re) + { + for (unsigned i = 0; i < len; ++i) + { + pNew[i] = inhalt[i]; + } // end for + } + delete [] inhalt; + } + + inhalt = pNew; + allocated = newSpace; +} + + +template <class XY> +DynamicList<XY>::DynamicList() +{ +} + +template <class XY> +DynamicList<XY>::DynamicList( const DynamicList<XY> & i_rList ) + : ST_List< XY* >(i_rList) +{ + for ( typename DynamicList<XY>::iterator it = this->begin(); + it != DynamicList<XY>::end(); + ++it ) + { + // Copying the contents the pointers point at: + (*it) = new XY( *(*it) ); + } +} + +template <class XY> +DynamicList<XY>::~DynamicList() +{ + this->erase_all(); +} + +template <class XY> +DynamicList<XY> & +DynamicList<XY>::operator=( const DynamicList<XY> & i_rList ) +{ + for ( typename DynamicList<XY>::const_iterator it = i_rList.begin(); + it != i_rList.end(); + ++it ) + { + push_back( new XY(*(*it)) ); + } + return *this; +} + + +template <class XY> +void +DynamicList<XY>::Insert(unsigned pos, XY * const & elem_) +{ + if ( pos > this->len ) + return; + + checkSize(DynamicList<XY>::len+2); + memmove( DynamicList<XY>::inhalt+pos+1, DynamicList<XY>::inhalt+pos, (DynamicList<XY>::len-pos) * sizeof(XY*) ); + this->inhalt[pos] = elem_; + this->len++; +} + +template <class XY> +void +DynamicList<XY>::Remove( unsigned pos ) +{ + if (!this->is_valid_index(pos) ) + return; + this->len--; + delete DynamicList<XY>::inhalt[pos]; + memmove(DynamicList<XY>::inhalt+pos, DynamicList<XY>::inhalt+pos+1, (DynamicList<XY>::len-pos) * sizeof(XY*) ); +} + + + +#endif + diff --git a/soltools/inc/st_types.hxx b/soltools/inc/st_types.hxx new file mode 100644 index 000000000000..29eb7396440c --- /dev/null +++ b/soltools/inc/st_types.hxx @@ -0,0 +1,40 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SOLTOOLS_ST_TYPES_HXX +#define SOLTOOLS_ST_TYPES_HXX + +typedef unsigned long UINT32; +typedef long INT32; +typedef unsigned short UINT16; +typedef short INT16; + + + + +#endif + diff --git a/soltools/javadep/javadep.c b/soltools/javadep/javadep.c new file mode 100644 index 000000000000..d0517d832f45 --- /dev/null +++ b/soltools/javadep/javadep.c @@ -0,0 +1,911 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/* All Java Virtual Machine Specs are from + * "The Java Virtual Machine Specification", T. Lindholm, F. Yellin + * (JVMS) + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <limits.h> + +#if defined(UNX) || defined(OS2) +#include <unistd.h> +#include <netinet/in.h> /* ntohl(), ntohs() */ +#elif defined(WNT) +#include <io.h> +#define access _access +#define vsnprintf _vsnprintf +#define CDECL _cdecl +#define F_OK 00 +#define PATH_MAX _MAX_PATH +#define ntohl(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#define ntohs(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) +#endif + +#if defined(OS2) +#define CDECL +#endif + +/* max. length of line in response file */ +#define RES_FILE_BUF 65536 + +struct file { + char *pname; + FILE *pfs; +}; + +struct growable { + int ncur; + int nmax; + char **parray; +}; + +typedef struct file file_t; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + +struct utf8 { + uint16 nlen; + void *pdata; +}; + +typedef struct utf8 utf8_t; + +/* The contents of the Constant_pool is described in JVMS p. 93 + */ +enum { + CONSTANT_Class = 7, + CONSTANT_Fieldref = 9, + CONSTANT_Methodref = 10, + CONSTANT_InterfaceMethodref = 11, + CONSTANT_String = 8, + CONSTANT_Integer = 3, + CONSTANT_Float = 4, + CONSTANT_Long = 5, + CONSTANT_Double = 6, + CONSTANT_NameAndType = 12, + CONSTANT_Utf8 = 1 +}; + +enum { NGROW_INIT = 10, NGROW = 2 }; + +static char *pprogname = "javadep"; +static char csep = ';'; +#if defined (UNX) || defined(OS2) +#define CDECL +static char cpathsep = '/'; +#elif defined (WNT) || defined(OS2) +static char cpathsep = '\\'; +#endif +static FILE *pfsout = NULL; +static char *pout_file = NULL; + + +/* prototypes */ +uint8 read_uint8(const file_t *pfile); +uint16 read_uint16(const file_t *pfile); +uint32 read_uint32(const file_t *pfile); +void skip_bytes(const file_t *pfile, const size_t nnum); +char *escape_slash(const char *pstr); +int is_inner(const char *pstr); +void print_dependencies(const struct growable *pdep, + const char* pclass_file); +void process_class_file(const char *pfilenamem, + const struct growable *pfilt); +char *utf8tolatin1(const utf8_t a_utf8); +void *xmalloc(size_t size); +void *xcalloc(size_t nmemb, size_t size); +void *xrealloc(void *ptr, size_t size); +void grow_if_needed (struct growable *pgrow); +int append_to_growable(struct growable *, char *); +struct growable *allocate_growable(void); +void free_growable(struct growable *pgrowvoid); +void create_filters(struct growable *pfilt, const struct growable *pinc); +void usage(void); +void err_quit(const char *, ...); +void silent_quit(void); + +#ifdef WNT +/* poor man's getopt() */ +int simple_getopt(char *pargv[], const char *poptstring); +char *optarg = NULL; +int optind = 1; +int optopt = 0; +int opterr = 0; +#endif + +uint8 +read_uint8(const file_t *pfile) +{ + /* read a byte from classfile */ + int nread; + uint8 ndata; + nread = fread(&ndata, sizeof(uint8), 1, pfile->pfs); + if ( !nread ) { + fclose(pfile->pfs); + err_quit("%s: truncated class file", pfile->pname); + } + return ndata; +} + +uint16 +read_uint16(const file_t *pfile) +{ + /* read a short from classfile and convert it to host format */ + int nread; + uint16 ndata; + nread = fread(&ndata, sizeof(uint16), 1, pfile->pfs); + if ( !nread ) { + fclose(pfile->pfs); + err_quit("%s: truncated class file", pfile->pname); + } + ndata = ntohs(ndata); + return ndata; +} + +uint32 +read_uint32(const file_t *pfile) +{ + /* read an int from classfile and convert it to host format */ + int nread; + uint32 ndata; + nread = fread(&ndata, sizeof(uint32), 1, pfile->pfs); + if ( !nread ) { + fclose(pfile->pfs); + err_quit("%s: truncated class file", pfile->pname); + } + ndata = ntohl(ndata); + return ndata; +} + +utf8_t +read_utf8(const file_t *pfile) +{ + /* Read a java utf-8-string with uint16 length prependend + * from class file. Returns utf8 struct + * with fresh allocated datablock, + * caller is responsible for freeing. + * Data is still in network byteorder + */ + + utf8_t a_utf8; + int nread; + + a_utf8.pdata = NULL; + + a_utf8.nlen = read_uint16(pfile); + if (a_utf8.nlen > 0) { + a_utf8.pdata = xmalloc(a_utf8.nlen*sizeof(char)); + nread = fread(a_utf8.pdata, a_utf8.nlen*sizeof(char), 1, pfile->pfs); + if ( !nread ) { + fclose(pfile->pfs); + err_quit("%s: truncated class file", pfile->pname); + } + } + + return a_utf8; +} + +char *utf8tolatin1(const utf8_t a_utf8) +{ + /* function returns fresh allocated zero terminated string, + * caller is responsible for freeing + */ + + /* JVMS p. 101: the null byte is encoded using a two byte format, + * Java Virtual Machine Utf8 strings differ in this respect from + * standard UTF-8 strings + */ + + /* Multibyte data is in network byte order */ + + char *p; + char *pp; + char *pstr; + + pstr = pp = xmalloc((a_utf8.nlen+1) * sizeof(char)); + + for ( p = (char*)a_utf8.pdata; + p < (char*)a_utf8.pdata+a_utf8.nlen; + p++ ) { + if ( *p & 0x80 ) { + err_quit("sorry, real UTF8 decoding not yet implemented\n"); + } else { + *pp++ = *p; + } + } + *pp = '\0'; + + return pstr; +} + + +void +skip_bytes(const file_t *pfile, const size_t nnumber) +{ + /* skip a nnumber of bytes in classfile */ + if ( fseek(pfile->pfs, nnumber, SEEK_CUR) == -1 ) + err_quit("%s: %s", pfile->pname, strerror(errno)); +} + +void +add_to_dependencies(struct growable *pdep, + const struct growable *pfilt, + char *pdepstr, + const char *pclass_file) +{ + /* create dependencies */ + int i; + int nlen_filt, nlen_str, nlen_pdepstr; + char *pstr, *ptrunc; + char path[PATH_MAX+1]; + char cnp_class_file[PATH_MAX+1]; + char cnp_str[PATH_MAX+1]; + + nlen_pdepstr = strlen(pdepstr); + pstr = xmalloc((nlen_pdepstr+6+1)*sizeof(char)); + memcpy(pstr, pdepstr, nlen_pdepstr+1); + strncat(pstr, ".class", 6); + + if ( pfilt->ncur == 0 ) { /* no filters */ + if ( access(pstr, F_OK) == 0 ) { + append_to_growable(pdep, strdup(pstr)); + } + } else { + nlen_str = strlen(pstr); + for ( i = 0; i < pfilt->ncur; i++ ) { + nlen_filt = strlen(pfilt->parray[i]); + if ( nlen_filt + 1 + nlen_str > PATH_MAX ) + err_quit("path to long"); + memcpy(path, pfilt->parray[i], nlen_filt); + path[nlen_filt] = '/'; + memcpy( path+nlen_filt+1, pstr, nlen_str+1); + + if ( access(path, F_OK) != 0 ) { + free(pstr); + pstr = NULL; + return; /* path doesn't represent a real file, don't bother */ + } + + /* get the canonical path */ +#if defined (UNX) || defined(OS2) + if ( !(realpath(pclass_file, cnp_class_file) + && realpath(path, cnp_str) ) ) { + err_quit("can't get the canonical path"); + } +#else + if ( !(_fullpath(cnp_class_file, pclass_file, sizeof(cnp_class_file)) + && _fullpath(cnp_str, path, sizeof(cnp_str)) ) ) { + err_quit("can't get the canonical path"); + } +#endif + + /* truncate so that only the package prefix remains */ + ptrunc = strrchr(cnp_str, cpathsep); + *ptrunc = '\0'; + ptrunc = strrchr(cnp_class_file, cpathsep); + *ptrunc = '\0'; + + if ( !strcmp(cnp_str, cnp_class_file) ) { + free(pstr); + pstr = NULL; + return; /* identical, don't bother with this one */ + } + + append_to_growable(pdep, strdup(path)); + } + } + free(pstr); + return; +} + +char * +escape_slash(const char *pstr) +{ + /* returns a fresh allocated string with all cpathsep escaped exchanged + * with "$/" + * + * caller is responsible for freeing + */ + + const char *pp = pstr; + char *p, *pnp; + char *pnew_str; + int nlen_pnp, nlen_pp; + int i = 0; + + while ( (p=strchr(pp, cpathsep)) != NULL ) { + ++i; + pp = ++p; + } + + nlen_pnp = strlen(pstr) + i; + pnp = pnew_str = xmalloc((nlen_pnp+1) * sizeof(char)); + + pp = pstr; + + if ( i > 0 ) { + while ( (p=strchr(pp, cpathsep)) != NULL ) { + memcpy(pnp, pp, p-pp); + pnp += p-pp; + *pnp++ = '$'; + *pnp++ = '/'; + pp = ++p; + } + } + nlen_pp = strlen(pp); + memcpy(pnp, pp, nlen_pp+1); + + return pnew_str; +} + + +void +print_dependencies(const struct growable *pdep, const char* pclass_file) +{ + char *pstr; + int i; + + pstr = escape_slash(pclass_file); + fprintf(pfsout, "%s:", pstr); + free(pstr); + + for( i=0; i<pdep->ncur; ++i) { + fprintf(pfsout, " \\\n"); + pstr=escape_slash(pdep->parray[i]); + fprintf(pfsout, "\t%s", pstr); + free(pstr); + } + + fprintf(pfsout,"\n\n"); + return; +} + +int +is_inner(const char *pstr) +{ + /* return true if character '$' is found in classname */ + + /* + * note that a '$' in a classname is not an exact indicator + * for an inner class. Java identifier may legally contain + * this chararcter, and so may classnames. In the context + * of javadep this doesn't matter since the makefile system + * can't cope with classfiles with '$'s in the filename + * anyway. + * + */ + + if ( strchr(pstr, '$') != NULL ) + return 1; + + return 0; +} + +void +process_class_file(const char *pfilename, const struct growable *pfilt) +{ + /* read class file and extract object information + * java class files are in bigendian data format + * (JVMS, p. 83) + */ + int i; + uint32 nmagic; + uint16 nminor, nmajor; + uint16 ncnt; + uint16 nclass_cnt; + utf8_t* pc_pool; + uint16* pc_class; + file_t file; + + struct growable *pdepen; + + file.pname = (char*)pfilename; + + file.pfs = fopen(file.pname,"rb"); + if ( !file.pfs ) + silent_quit(); + + nmagic = read_uint32(&file); + + if ( nmagic != 0xCAFEBABE ) { + fclose(file.pfs); + err_quit("%s: invalid magic", file.pname); + } + + nminor = read_uint16(&file); + nmajor = read_uint16(&file); + + /* get number of entries in constant pool */ + ncnt = read_uint16(&file); + +#ifdef DEBUG + printf("Magic: %p\n", (void*)nmagic); + printf("Major %d, Minor %d\n", nmajor, nminor); + printf("Const_pool_count %d\n", ncnt); +#endif + + /* There can be ncount entries in the constant_pool table + * so at most ncount-1 of them can be of type CONSTANT_Class + * (at leat one CONSTANT_Utf8 entry must exist). + * Usually way less CONSTANT_Class entries exists, of course + */ + + pc_pool = xcalloc(ncnt,sizeof(utf8_t)); + pc_class = xmalloc((ncnt-1)*sizeof(uint16)); + + /* pc_pool[0] is reserved to the java virtual machine and does + * not exist in the class file + */ + + nclass_cnt = 0; + + for (i = 1; i < ncnt; i++) { + uint8 ntag; + uint16 nindex; + utf8_t a_utf8; + + ntag = read_uint8(&file); + + /* we are only interested in CONSTANT_Class entries and + * Utf8 string entries, because they might belong to + * CONSTANT_Class entries + */ + switch(ntag) { + case CONSTANT_Class: + nindex = read_uint16(&file); + pc_class[nclass_cnt++] = nindex; + break; + case CONSTANT_Fieldref: + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + skip_bytes(&file, 4L); + break; + case CONSTANT_String: + skip_bytes(&file, 2L); + break; + case CONSTANT_Integer: + case CONSTANT_Float: + skip_bytes(&file, 4L); + break; + case CONSTANT_Long: + case CONSTANT_Double: + skip_bytes(&file, 8L); + /* Long and Doubles take 2(!) + * entries in constant_pool_table + */ + i++; + break; + case CONSTANT_NameAndType: + skip_bytes(&file, 4L); + break; + case CONSTANT_Utf8: + a_utf8 = read_utf8(&file); + pc_pool[i] = a_utf8; + break; + default: + /* Unknown Constant_pool entry, this means we are + * in trouble + */ + err_quit("corrupted class file\n"); + break; + + } + } + + fclose(file.pfs); + + pdepen = allocate_growable(); + + for (i = 0; i < nclass_cnt; i++) { + char *pstr, *ptmpstr; + pstr = ptmpstr = utf8tolatin1(pc_pool[pc_class[i]]); + /* we are not interested in inner classes */ + if ( is_inner(pstr) ) { + free(pstr); + pstr = NULL; + continue; + } + /* strip off evt. array indicators */ + if ( *ptmpstr == '[' ) { + while ( *ptmpstr == '[' ) + ptmpstr++; + /* we only interested in obj. arrays, which are marked with 'L' */ + if ( *ptmpstr == 'L' ) { + char *p = pstr; + pstr = strdup(++ptmpstr); + /* remove final ';' from object array name */ + pstr[strlen(pstr)-1] = '\0'; + free(p); + } else { + free(pstr); + pstr = NULL; + } + } + + if (pstr) { + add_to_dependencies(pdepen, pfilt, pstr, file.pname); + free(pstr); + } + } + + print_dependencies(pdepen, file.pname); + free_growable(pdepen); + pdepen = NULL; + + for (i = 0; i < ncnt; i++) + free(pc_pool[i].pdata); + + free(pc_class); + free(pc_pool); +} + +void * +xmalloc(size_t size) +{ + void *ptr; + + ptr = malloc(size); + + if ( !ptr ) + err_quit("out of memory"); + + return ptr; +} + + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *ptr; + + ptr = calloc(nmemb, size); + + if ( !ptr ) + err_quit("out of memory"); + + return ptr; +} + +void * +xrealloc(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + + if ( !ptr ) + err_quit("out of memory"); + + return ptr; +} + +void +err_quit(const char* fmt, ...) +{ + /* No dependency file must be generated for any error condition, + * just print message and exit. + */ + va_list args; + char buffer[PATH_MAX]; + + va_start(args, fmt); + + if ( pprogname ) + fprintf(stderr, "%s: ", pprogname); + vsnprintf(buffer, sizeof(buffer), fmt, args); + fputs(buffer, stderr); + fputc('\n', stderr); + + va_end(args); + + /* clean up */ + if ( pfsout && pfsout != stdout ) { + fclose(pfsout); + unlink(pout_file); + } + exit(1); +} + +void +silent_quit() +{ + /* In some cases we should just do a silent exit */ + + /* clean up */ + if ( pfsout && pfsout != stdout ) { + fclose(pfsout); + unlink(pout_file); + } + exit(0); +} + +int append_to_growable(struct growable *pgrow, char *pstr) +{ + /* append an element pstr to pgrow, + * return new number of elements + */ + grow_if_needed(pgrow); + pgrow->parray[pgrow->ncur++] = pstr; + return pgrow->ncur; +} + +void +grow_if_needed(struct growable *pgrow) +{ + /* grow growable arrays */ + + if ( pgrow->ncur >= pgrow->nmax ) { + pgrow->parray = xrealloc(pgrow->parray, + (NGROW*pgrow->nmax)*sizeof(char*)); + pgrow->nmax *= NGROW; + } + return; +} + +struct growable *allocate_growable(void) +{ + /* allocate an growable array, + * initialize with NGROW_INIT elements + */ + + struct growable *pgrow; + + pgrow = xmalloc(sizeof(struct growable)); + pgrow->parray = xmalloc(NGROW_INIT*sizeof(char *)); + pgrow->nmax = NGROW_INIT; + pgrow->ncur = 0; + return pgrow; +} + +void +free_growable(struct growable *pgrow) +{ + int i; + for( i = 0; i < pgrow->ncur; i++ ) + free(pgrow->parray[i]); + free(pgrow->parray); + free(pgrow); +} + +void +create_filters(struct growable *pfilt, const struct growable *pinc) +{ + char *p, *pp, *pstr; + int i, nlen, nlen_pstr; + /* break up includes into filter list */ + for ( i = 0; i < pinc->ncur; i++ ) { + pp = pinc->parray[i]; + + while ( (p = strchr(pp, csep)) != NULL) { + nlen = p - pp; + pstr = xmalloc((nlen+1)*sizeof(char*)); + memcpy(pstr, pp, nlen); + pstr[nlen] = '\0'; + append_to_growable(pfilt, pstr); + pp = p + 1; + } + nlen_pstr = strlen(pp); + pstr = xmalloc((nlen_pstr+1)*sizeof(char*)); + memcpy(pstr, pp, nlen_pstr+1); + append_to_growable(pfilt, pstr); + } + +} + +void +usage() +{ + fprintf(stderr, + "usage: %s [-i|-I includepath ... -s|-S seperator " + "-o|-O outpath -v|-V -h|-H] <file> ....\n", + pprogname); +} + +#ifdef WNT +/* my very simple minded implementation of getopt() + * it's to sad that getopt() is not available everywhere + * note: this is not a full POSIX conforming getopt() + */ +int simple_getopt(char *pargv[], const char *poptstring) +{ + char *parg = pargv[optind]; + + /* skip all response file arguments */ + if ( parg ) { + while ( *parg == '@' ) + parg = pargv[++optind]; + + if ( parg[0] == '-' && parg[1] != '\0' ) { + char *popt; + int c = parg[1]; + if ( (popt = strchr(poptstring, c)) == NULL ) { + optopt = c; + if ( opterr ) + fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); + return '?'; + } + if ( *(++popt) == ':') { + if ( parg[2] != '\0' ) { + optarg = ++parg; + } else { + optarg = pargv[++optind]; + } + } else { + optarg = NULL; + } + ++optind; + return c; + } + } + return -1; +} +#endif + +int CDECL +main(int argc, char *argv[]) +{ + int bv_flag = 0; + struct growable *presp, *pincs, *pfilters; + int c, i, nall_argc; + char **pall_argv; + + presp = allocate_growable(); + + /* FIXME: cleanup the option parsing */ + /* search for response file, read it */ + for ( i = 1; i < argc; i++ ) { + char *parg = argv[i]; + char buffer[RES_FILE_BUF]; + + if ( *parg == '@' ) { + FILE *pfile = fopen(++parg, "r"); + if ( !pfile ) + err_quit("%s: %s", parg, strerror(errno)); + while ( !feof(pfile) ) { + char *p, *token; + + if ( fgets(buffer, RES_FILE_BUF, pfile) ) {; + p = buffer; + while ( (token = strtok(p, " \t\n")) != NULL ) { + p = NULL; + append_to_growable(presp, strdup(token)); + } + } + } + fclose(pfile); + } + } + + /* copy all arguments incl. response file in one array + * for parsing with getopt + */ + nall_argc = argc + presp->ncur; + pall_argv = xmalloc((nall_argc+1)*sizeof(char *)); + memcpy(pall_argv, argv, argc*sizeof(char *)); + memcpy(pall_argv+argc, presp->parray, presp->ncur*sizeof(char *)); + *(pall_argv+argc+presp->ncur) = '\0'; /* terminate */ + + opterr = 0; + pincs = allocate_growable(); + +#ifdef WNT + while( (c = simple_getopt(pall_argv, ":i:I:s:S:o:OhHvV")) != -1 ) { +#else + while( (c = getopt(nall_argc, pall_argv, ":i:I:s:S:o:OhHvV")) != -1 ) { +#endif + switch(c) { + case 'i': + case 'I': + append_to_growable(pincs, strdup(optarg)); + break; + case 's': + case 'S': + csep = optarg[0]; + break; + case 'o': + case 'O': + pout_file = optarg; + break; + case 'h': + case 'H': + usage(); + return 0; + break; + case 'v': + case 'V': + bv_flag = 1; + break; + case '?': + if (isprint (optopt)) + fprintf (stderr, + "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + usage(); + return 1; + break; + case ':': + fprintf(stderr, "Missing parameter.\n"); + usage(); + return 1; + break; + default: + usage(); + return 1; + break; + } + } + + pfilters = allocate_growable(); + create_filters(pfilters, pincs); + free_growable(pincs); + pincs = NULL; + + if ( pout_file ) { + pfsout = fopen(pout_file, "w"); + if ( !pfsout ) + err_quit("%s: %s", pout_file, strerror(errno)); + } else { + pfsout = stdout; + } + + /* the remaining arguments are either class file + * names or response files, ignore response file + * since they have already been included + */ + for ( i = optind; i < nall_argc; i++ ) { + char *parg = pall_argv[i]; + if ( *parg != '@' ) { + process_class_file(parg, pfilters); + if ( pfsout != stdout ) { + if ( bv_flag ) + printf("Processed %s ...\n", parg); + } + } + } + + free_growable(pfilters); + pfilters = NULL; + free(pall_argv); + pall_argv = NULL; + free_growable(presp); + presp = NULL; + + fclose(pfsout); + exit(0); +} + diff --git a/soltools/javadep/makefile.mk b/soltools/javadep/makefile.mk new file mode 100644 index 000000000000..1b3b54de6c06 --- /dev/null +++ b/soltools/javadep/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=javadep +TARGETTYPE=CUI +NO_DEFAULT_STL=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +UWINAPILIB=$(0) +LIBSALCPPRT=$(0) + +# --- Files -------------------------------------------------------- + +APP1TARGET = javadep +APP1OBJS = $(OBJ)$/javadep.obj +DEPOBJFILES = $(APP1OBJS) +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/ldump/hashtbl.cxx b/soltools/ldump/hashtbl.cxx new file mode 100644 index 000000000000..27d48926f0df --- /dev/null +++ b/soltools/ldump/hashtbl.cxx @@ -0,0 +1,458 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include "hashtbl.hxx" +#include <string.h> + +// ------------------------------------------------------------- +// class HashItem +// +class HashItem +{ + enum ETag { TAG_EMPTY, TAG_USED, TAG_DELETED }; + + void* m_pObject; + ETag m_Tag; + char* m_Key; + +public: + HashItem() { m_Tag = TAG_EMPTY; m_Key = NULL; m_pObject = NULL; } + ~HashItem() { delete [] m_Key; } + + bool IsDeleted() const + { return m_Tag == TAG_DELETED; } + + bool IsEmpty() const + { return m_Tag == TAG_DELETED || m_Tag == TAG_EMPTY; } + + bool IsFree() const + { return m_Tag == TAG_EMPTY; } + + bool IsUsed() const + { return m_Tag == TAG_USED; } + + void Delete() + { m_Tag = TAG_DELETED; delete [] m_Key; m_Key = new char[ 1 ]; m_Key[ 0 ] = 0; m_pObject = NULL; } + + const char *GetKey() const + { return m_Key; } + + void* GetObject() const + { return m_pObject; } + + void SetObject(const char * Key, void *pObject) + { m_Tag = TAG_USED; delete [] m_Key; m_Key = new char[ strlen( Key ) + 1 ]; strcpy( m_Key, Key ); m_pObject = pObject; } +}; + +#define MIN(a,b) (a)<(b)?(a):(b) +#define MAX(a,b) (a)>(b)?(a):(b) + +// ------------------------------------------------------------- +// class HashTable +// + +/*static*/ double HashTable::m_defMaxLoadFactor = 0.5; +/*static*/ double HashTable::m_defDefGrowFactor = 2.0; + +HashTable::HashTable(unsigned long lSize, bool bOwner, double dMaxLoadFactor, double dGrowFactor) +{ + m_lSize = lSize; + m_bOwner = bOwner; + m_lElem = 0; + m_dMaxLoadFactor = MAX(0.5,MIN(1.0,dMaxLoadFactor)); // 0.5 ... 1.0 + m_dGrowFactor = MAX(2.0,MIN(5.0,dGrowFactor)); // 1.3 ... 5.0 + m_pData = new HashItem [lSize]; +} + +HashTable::~HashTable() +{ + // Wenn die HashTable der Owner der Objecte ist, + // müssen die Destruktoren separat gerufen werden. + // Dies geschieht über die virtuelle Methode OnDeleteObject() + // + // Problem: Virtuelle Funktionen sind im Destructor nicht virtuell!! + // Der Code muß deshalb ins Macro + + /* + if (m_bOwner) + { + for (ULONG i=0; i<GetSize(); i++) + { + void *pObject = GetObjectAt(i); + + if (pObject != NULL) + OnDeleteObject(pObject()); + } + } + */ + + // Speicher für HashItems freigeben + delete [] m_pData; +} + +void* HashTable::GetObjectAt(unsigned long lPos) const +// Gibt Objekt zurück, wenn es eines gibt, sonst NULL; +{ + HashItem *pItem = &m_pData[lPos]; + + return pItem->IsUsed() ? pItem->GetObject() : NULL; +} + +void HashTable::OnDeleteObject(void*) +{ +} + +unsigned long HashTable::Hash(const char *Key) const +{ + // Hashfunktion von P.J. Weinberger + // aus dem "Drachenbuch" von Aho/Sethi/Ullman + unsigned long i,n; + unsigned long h = 0; + unsigned long g = 0; + + for (i=0,n=strlen( Key ); i<n; i++) + { + h = (h<<4) + (unsigned long)(unsigned short)Key[i]; + g = h & 0xf0000000; + + if (g != 0) + { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return h % m_lSize; +} + +unsigned long HashTable::DHash(const char* Key, unsigned long lOldHash) const +{ + unsigned long lHash = lOldHash; + unsigned long i,n; + + for (i=0,n=strlen( Key ); i<n; i++) + { + lHash *= 256L; + lHash += (unsigned long)(unsigned short)Key[i]; + lHash %= m_lSize; + } + return lHash; +} + +unsigned long HashTable::Probe(unsigned long lPos) const +// gibt den Folgewert von lPos zurück +{ + lPos++; if (lPos==m_lSize) lPos=0; + return lPos; +} + +bool HashTable::IsFull() const +{ + return m_lElem>=m_lSize; +} + +bool HashTable::Insert(const char * Key, void* pObject) +// pre: Key ist nicht im Dictionary enthalten, sonst return FALSE +// Dictionary ist nicht voll, sonst return FALSE +// post: pObject ist unter Key im Dictionary; m_nElem wurde erhöht +{ + SmartGrow(); + + if (IsFull()) + { + return false; + } + + if (FindPos(Key) != NULL ) + return false; + + unsigned long lPos = Hash(Key); + HashItem *pItem = &m_pData[lPos]; + + // first hashing + // + if (pItem->IsEmpty()) + { + pItem->SetObject(Key, pObject); + m_lElem++; + + return true; + } + + // double hashing + // + lPos = DHash(Key,lPos); + pItem = &m_pData[lPos]; + + if (pItem->IsEmpty()) + { + pItem->SetObject(Key, pObject); + m_lElem++; + + return true; + } + + // linear probing + // + do + { + lPos = Probe(lPos); + pItem = &m_pData[lPos]; + } + while(!pItem->IsEmpty()); + + pItem->SetObject(Key, pObject); + m_lElem++; + return true; +} + +HashItem* HashTable::FindPos(const char * Key) const +// sucht den Key; gibt Refrenz auf den Eintrag (gefunden) +// oder NULL (nicht gefunden) zurück +// +// pre: - +// post: - +{ + // first hashing + // + unsigned long lPos = Hash(Key); + HashItem *pItem = &m_pData[lPos]; + + if (pItem->IsUsed() + && !(strcmp( pItem->GetKey(), Key ))) + { + return pItem; + } + + // double hashing + // + if (pItem->IsDeleted() || pItem->IsUsed()) + { + lPos = DHash(Key,lPos); + pItem = &m_pData[lPos]; + + if (pItem->IsUsed() + && (!strcmp( pItem->GetKey(), Key))) + { + return pItem; + } + + // linear probing + // + if (pItem->IsDeleted() || pItem->IsUsed()) + { + unsigned long n = 0; + bool bFound = false; + bool bEnd = false; + + do + { + n++; + lPos = Probe(lPos); + pItem = &m_pData[lPos]; + + bFound = pItem->IsUsed() + && !( strcmp( pItem->GetKey(), Key )); + + bEnd = !(n<m_lSize || pItem->IsFree()); + } + while(!bFound && !bEnd); + + return bFound ? pItem : NULL; + } + } + + // nicht gefunden + // + return NULL; +} + +void* HashTable::Find(const char *Key) const +// Gibt Verweis des Objektes zurück, das unter Key abgespeichert ist, +// oder NULL wenn nicht vorhanden. +// +// pre: - +// post: - +{ + HashItem *pItem = FindPos(Key); + + if (pItem != NULL + && ( !strcmp( pItem->GetKey(), Key ))) + return pItem->GetObject(); + else + return NULL; +} + +void* HashTable::Delete( const char * Key) +// Löscht Objekt, das unter Key abgespeichert ist und gibt Verweis +// darauf zurück. +// Gibt NULL zurück, wenn Key nicht vorhanden ist. +// +// pre: - +// post: Objekt ist nicht mehr enthalten; m_lElem dekrementiert +// Wenn die HashTable der Owner ist, wurde das Object gelöscht +{ + HashItem *pItem = FindPos(Key); + + if (pItem != NULL + && ( !strcmp( pItem->GetKey(), Key ))) + { + void* pObject = pItem->GetObject(); + + if (m_bOwner) + OnDeleteObject(pObject); + + pItem->Delete(); + m_lElem--; + return pObject; + } + else + { + return NULL; + } +} + +double HashTable::CalcLoadFactor() const +// prozentuale Belegung der Hashtabelle berechnen +{ + return double(m_lElem) / double(m_lSize); +} + +void HashTable::SmartGrow() +// Achtung: da die Objekte umkopiert werden, darf die OnDeleteObject-Methode +// nicht gerufen werden +{ + double dLoadFactor = CalcLoadFactor(); + + if (dLoadFactor <= m_dMaxLoadFactor) + return; // nothing to grow + + unsigned long lOldSize = m_lSize; // alte Daten sichern + HashItem* pOldData = m_pData; + + m_lSize = (unsigned long) (m_dGrowFactor * m_lSize); // neue Größe + m_pData = new HashItem[m_lSize]; // neue Daten holen + + // kein Speicher: + // Zustand "Tabelle voll" wird in Insert abgefangen + // + if (m_pData == NULL) + { + m_lSize = lOldSize; + m_pData = pOldData; + return; + } + + m_lElem = 0; // noch keine neuen Daten + + // Umkopieren der Daten + // + for (unsigned long i=0; i<lOldSize; i++) + { + HashItem *pItem = &pOldData[i]; + + if (pItem->IsUsed()) + Insert(pItem->GetKey(),pItem->GetObject()); + } + + delete [] pOldData; +} + +// Iterator --------------------------------------------------------- +// + +HashTableIterator::HashTableIterator(HashTable const& aTable) +: m_aTable(aTable) +{ + m_lAt = 0; +} + +void* HashTableIterator::GetFirst() +{ + m_lAt = 0; + return FindValidObject(true /* forward */); +} + +void* HashTableIterator::GetLast() +{ + m_lAt = m_aTable.GetSize() -1; + return FindValidObject(false /* backward */); +} + +void* HashTableIterator::GetNext() +{ + if (m_lAt+1 >= m_aTable.GetSize()) + return NULL; + + m_lAt++; + return FindValidObject(true /* forward */); +} + +void* HashTableIterator::GetPrev() +{ + if (m_lAt <= 0) + return NULL; + + m_lAt--; + return FindValidObject(false /* backward */); +} + +void* HashTableIterator::FindValidObject(bool bForward) +// Sucht nach einem vorhandenen Objekt ab der aktuellen +// Position. +// +// pre: ab inkl. m_lAt soll die Suche beginnen +// post: if not found then +// if bForward == TRUE then +// m_lAt == m_aTable.GetSize() -1 +// else +// m_lAt == 0 +// else +// m_lAt ist die gefundene Position +{ + void *pObject = m_aTable.GetObjectAt(m_lAt); + + if (pObject != NULL) + return pObject; + + while (pObject == NULL + && (bForward ? ((m_lAt+1) < m_aTable.GetSize()) + : m_lAt > 0)) + { + if (bForward) + m_lAt++; + else + m_lAt--; + + pObject = m_aTable.GetObjectAt(m_lAt); + } + + return pObject; +} diff --git a/soltools/ldump/hashtbl.hxx b/soltools/ldump/hashtbl.hxx new file mode 100644 index 000000000000..62d1f8e9120e --- /dev/null +++ b/soltools/ldump/hashtbl.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _HASHTBL_HXX +#define _HASHTBL_HXX + +// ADT hash table +// +// Invariante: +// 1. m_lElem < m_lSize +// 2. die Elemente in m_Array wurden double-hashed erzeugt +// +class HashItem; + +class HashTable +{ + unsigned long m_lSize; + unsigned long m_lElem; + HashItem *m_pData; + double m_dMaxLoadFactor; + double m_dGrowFactor; + bool m_bOwner; + + unsigned long Hash(const char *cKey) const; + unsigned long DHash(const char *cKey , unsigned long lHash) const; + unsigned long Probe(unsigned long lPos) const; + + HashItem* FindPos(const char *cKey) const; + void SmartGrow(); + double CalcLoadFactor() const; + +protected: + friend class HashTableIterator; + + virtual void OnDeleteObject(void* pObject); + + void* GetObjectAt(unsigned long lPos) const; + +// Default-Werte +public: + static double m_defMaxLoadFactor; + static double m_defDefGrowFactor; + +public: + HashTable + ( + unsigned long lSize, + bool bOwner, + double dMaxLoadFactor = HashTable::m_defMaxLoadFactor /* 0.8 */, + double dGrowFactor = HashTable::m_defDefGrowFactor /* 2.0 */ + ); + + virtual ~HashTable(); + + bool IsFull() const; + unsigned long GetSize() const { return m_lSize; } + + void* Find (const char *cKey ) const; + bool Insert (const char *cKey , void* pObject); + void* Delete (const char *cKey); +}; + +// ADT hash table iterator +// +// Invariante: 0 <= m_lAt < m_aTable.GetCount() +// +class HashTableIterator +{ + unsigned long m_lAt; + HashTable const& m_aTable; + + void operator =(HashTableIterator &); // not defined + + void* FindValidObject(bool bForward); + +protected: + void* GetFirst(); // Interation _ohne_ Sortierung + void* GetNext(); + void* GetLast(); + void* GetPrev(); + +public: + HashTableIterator(HashTable const&); +}; + +#endif // _HASHTBL_HXX + diff --git a/soltools/ldump/ldump.cxx b/soltools/ldump/ldump.cxx new file mode 100644 index 000000000000..8c6e85b62594 --- /dev/null +++ b/soltools/ldump/ldump.cxx @@ -0,0 +1,758 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include <string.h> +#include <direct.h> +#include <stdio.h> +#include <stdlib.h> + +#include "ldump.hxx" +#include "hashtbl.hxx" + +#define MAXSYM 65536 +#define MAXBASE 98304 +#define MAX_MAN 4096 + +int bFilter = 0; +int bLdump3 = 0; +int bUseDirectives = 0; +int bVerbose = 0; +int bExportByName = 0; + +class ExportSet : public HashTable +{ +public: + ExportSet + ( + unsigned long lSize, + double dMaxLoadFactor = HashTable::m_defMaxLoadFactor, + double dGrowFactor = HashTable::m_defDefGrowFactor + ) + : HashTable(lSize,false,dMaxLoadFactor,dGrowFactor) {} + + virtual ~ExportSet() {} + + LibExport * Find (char * const& Key) const + { return (LibExport *) HashTable::Find((char *) Key); } + + bool Insert (char * const& Key, LibExport * Object) + { return HashTable::Insert((char *) Key, (void*) Object); } + + LibExport * Delete (char * const&Key) + { return (LibExport *) HashTable::Delete ((char *) Key); } +}; + +LibDump::LibDump( char *cFileName, int bExportByName ) + : cBName( NULL ), + cAPrefix( NULL ), + cLibName( NULL ), + cFilterName( NULL ), + cModName( NULL ) +{ + fprintf( stderr, "LIB-NT File Dumper v4.00 (C) 2000 Sun Microsystems, Inc.\n\n" ); + fprintf( stderr, "%s ", cFileName ); + + bExportName = bExportByName; + + unsigned long nSlots = 0xfffff; + pBaseTab = new ExportSet( nSlots ); + pIndexTab = new ExportSet( nSlots ); + pFilterLines = new char * [MAXFILT]; + CheckLibrary(cFileName); + bBase = 0; + bAll = false; + nDefStart = 0; + nBaseLines = 0; + nFilterLines = 0; + bDef = true; + cAPrefix = new char[ 1 ]; + cAPrefix[ 0 ] = 0; + if (!bExportName) + CheckDataBase(); +} + +bool LibDump::Dump() +{ + FILE *pList; + char aBuf[MAX_MAN]; + int nLen; + char aName[MAX_MAN]; + + pList = fopen( cLibName, "rb"); + if (!pList) + DumpError(10); + + // forget about offset when working on linker directives + if ( !bUseDirectives ) + { + // calculating offset for name section + unsigned char TmpBuffer[4]; + fread( TmpBuffer, 1, 4, pList); + // anzahl bigendian mal laenge + ueberspringen der naechsten laengenangabe + unsigned long nOffSet = (unsigned long) ( TmpBuffer[2] * 256 + TmpBuffer[3] ) * 4 + 4; + fseek( pList, (long) nOffSet, 0); + } + + char aTmpBuf[4096]; + // reading file containing symbols + while( !feof( pList ) ) + { + int i = 0; + if ( !bUseDirectives ) + { + // symbol komplett einlesen + for (;;) + { + int c = fgetc( pList ); + if ( c == '\0' ) + { + break; + } + if ( ((c >= 33) && (c <= 126)) && ( c!=40 && c!=41) ) + aBuf[i] = static_cast< char >(c); + else + { + aBuf[0] = '\0'; + break; + } + i++; + } + // Namen found + aBuf[i] = '\0'; + } + else + { + fgets( aTmpBuf, 4096, pList ); + char * pEnd = 0; + char *pFound = 0; + aBuf[0] = '\0'; + pFound = strchr( aTmpBuf, 'E' ); + while ( pFound ) + { + if ( strncmp( "EXPORT:", pFound, 7) == 0 ) + { + pFound += 7; + pEnd = strchr( pFound, ','); + if ( pEnd ) + *pEnd = '\0'; + strncpy( aBuf, pFound, strlen( pFound)); + aBuf[ strlen( pFound) ] = '\0'; +// fprintf( stderr, "\n--- %s\n", aBuf); + break; + } + else + { + pFound++; + pFound = strchr( pFound, 'E' ); + } + } + } + + if ((aBuf[0] =='?') || !strncmp(aBuf, "__CT",4)) + { + nLen = (int) strlen(aBuf); + memset( aName, 0, sizeof( aName ) ); + int nName = 0; + for( i = 0; i < nLen; i++ ) + { + if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') ) + { + aName[nName] = aBuf[i]; + nName++; + } + } + // und raus damit + PrintSym( aName, bExportByName ); + } + else if ( bAll == true ) + { + int nPreLen = (int) strlen( cAPrefix ); + + nLen = (int) strlen(aBuf); + memset( aName, 0, sizeof( aName ) ); + int nName = 0; + + for( i = 0; i < nLen; i++ ) + { + if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') ) + { + aName[nName] = aBuf[i]; + nName++; + } + } + //fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen ); + // den ersten _ raus + nLen = (int) strlen(aName); + if (aName[0] == '_') + strcpy( aBuf , &aName[1] ); + strncpy ( aTmpBuf, aBuf, (size_t) nPreLen ); + aTmpBuf[nPreLen] = '\0'; + if ( !strcmp( aTmpBuf, cAPrefix )) + { + if ( bLdump3 ) { + int nChar = '@'; + char *pNeu = strchr( aBuf, nChar ); + int nPos = pNeu - aBuf + 1; + if ( nPos > 0 ) + { + char aOldBuf[MAX_MAN]; + strcpy( aOldBuf, aBuf ); + char pChar[MAX_MAN]; + strncpy( pChar, aBuf, (size_t) (nPos -1) ); + pChar[nPos-1] = '\0'; + strcpy( aBuf, pChar ); + strcat( aBuf, "=" ); + strcat( aBuf, aOldBuf ); + strcpy( pChar, "" ); + } + } + // und raus damit + PrintSym( aBuf, true ); + } + } + } + fclose(pList); + return true; +} + +bool LibDump::ReadFilter( char * cFilterName ) +{ + FILE* pfFilter = 0; + char aBuf[MAX_MAN]; + char* pStr; + int nLen; + + pfFilter = fopen( cFilterName, "r" ); + + if ( !pfFilter ) + { + ::bFilter = 0; + DumpError( 500 ); + } + + while( fgets( aBuf, MAX_MAN, pfFilter ) != 0 ) + { + nLen = (int) strlen(aBuf); + pStr = new char[(unsigned int) nLen]; + if ( !pStr ) + DumpError( 98 ); + memcpy( pStr, aBuf, (unsigned int) nLen ); + if ( *(pStr+nLen-1) == '\n' ) + *(pStr+nLen-1) = '\0'; + pFilterLines[nFilterLines] = pStr; + nFilterLines++; + if ( nFilterLines >= MAXFILT ) + DumpError( 510 ); + } + + fclose( pfFilter ); + return true; +} + +bool LibDump::PrintSym(char *pName, bool bName ) +{ + LibExport *pData; + + + // Filter auswerten + if ( Filter( pName ) ) + { + if ( strlen( pName ) > 3 ) + { + if ( bDef ) + { + if (!bBase) + if (bExportName) { + fprintf( stdout, "\t%s\n", pName ); + } else { + fprintf( stdout, "\t%s\t\t@%lu\n", pName, nDefStart ); + } + else + { + pData = pBaseTab->Find( pName ); + if ( pData ) + { + pData->bExport = true; + if ( bName ) + pData->bByName = true; + else + pData->bByName = false; + if ( bVerbose ) + fprintf(stderr,"."); + } + else + { + // neuen Export eintragen + pData = new LibExport; + pData->cExportName = new char[ strlen( pName ) + 1 ]; + strcpy( pData->cExportName, pName ); + pData->nOrdinal = nBaseLines++; + pData->bExport = true; + if ( bName ) + pData->bByName = true; + else + pData->bByName = false; + pBaseTab->Insert( pData->cExportName, pData ); + char *cBuffer = new char[ 30 ]; + sprintf( cBuffer, "%lu", pData->nOrdinal ); + pIndexTab->Insert( cBuffer, pData ); + delete [] cBuffer; + if ( bVerbose ) + fprintf(stderr,"n"); + } + } + } + else + printf( "%s\n", pName ); + nDefStart++; + } + } + return true; +} + +bool LibDump::IsFromAnonymousNamespace (char *pExportName) { + char* pattern1 = "@?A0x"; + + if (strstr(pExportName, pattern1)) { + return true; + }; + return false; +}; + +bool LibDump::Filter(char *pExportName) +{ + unsigned long i; + char pTest[256]; + + // filter out symbols from anonymous namespaces + if (IsFromAnonymousNamespace (pExportName)) + return false; + + // Kein Filter gesetzt + if ( ::bFilter == 0 ) + return true; + + for ( i=0; i<nFilterLines; i++ ) + { + //Zum vergleichen muá das Plus abgeschnitteb werden + if(pFilterLines[i][0] != '+') + { + if ( strstr( pExportName, pFilterLines[i])) + return false; + } + else + { + strcpy(pTest,&pFilterLines[i][1]); + if ( strstr( pExportName, pTest)) + return true; + } + } + return true; +} + +bool LibDump::SetFilter(char * cFilterName) +{ + ReadFilter( cFilterName ); + return true; +} + +bool LibDump::CheckLibrary(char * cName) +{ + delete [] cLibName; + cLibName = new char[ strlen( cName ) + 1 ]; + strcpy( cLibName, cName ); + return true; +} + +bool LibDump::ReadDataBase() +{ + FILE* pfBase = 0; + char aBuf[MAX_MAN]; + char* pStr; + char cBuffer[ 30 ]; + int nLen; + LibExport *pData; + + pfBase = fopen( cBName, "r" ); + + if ( !pfBase ) + { + bBase = 0; + DumpError( 600 ); + } + + bool bRet = true; + while( fgets( aBuf, MAX_MAN, pfBase ) != 0 ) + { + nLen = (int) strlen(aBuf); + pStr = new char[(unsigned int) nLen]; + if ( !pStr ) + DumpError( 98 ); + memcpy( pStr, aBuf, (size_t) nLen ); + if ( *(pStr+nLen-1) == '\n' ) + *(pStr+nLen-1) = '\0'; + pData = new LibExport; + pData->cExportName = pStr; + pData->nOrdinal = nBaseLines; + pData->bExport=false; + + if (pBaseTab->Insert(pData->cExportName, pData ) == NULL) + bRet = false; + ltoa( (long) pData->nOrdinal, cBuffer, 10 ); + if (pIndexTab->Insert( cBuffer, pData ) == NULL) + bRet = false; + nBaseLines++; + if ( nBaseLines >= MAXBASE ) + DumpError( 610 ); + } + fclose( pfBase ); + return bRet; +} + +class ExportSetIter : public HashTableIterator +{ +public: + ExportSetIter(HashTable const& aTable) + : HashTableIterator(aTable) {} + + LibExport * GetFirst() + { return (LibExport *)HashTableIterator::GetFirst(); } + LibExport * GetNext() + { return (LibExport *)HashTableIterator::GetNext(); } + LibExport * GetLast() + { return (LibExport *)HashTableIterator::GetLast(); } + LibExport * GetPrev() + { return (LibExport *)HashTableIterator::GetPrev(); } + +private: + void operator =(ExportSetIter &); // not defined +}; + +bool LibDump::PrintDataBase() +{ + if (bExportName) + return true; + FILE *pFp; + pFp = fopen (cBName,"w+"); + if (!pFp) + fprintf( stderr, "Error opening DataBase File\n" ); + + LibExport *pData; + for ( unsigned long i=0; i < nBaseLines+10; i++ ) + { + char * cBuffer = new char[ 30 ]; + sprintf( cBuffer, "%lu", i ); + pData = pIndexTab->Find( cBuffer ); + delete [] cBuffer; + if ( pData ) + fprintf(pFp,"%s\n",pData->cExportName); + } + fclose(pFp); + return true; +} + +bool LibDump::PrintDefFile() +{ +#ifdef FAST + ExportSetIter aIterator( *pBaseTab ); + for ( LibExport *pData = aIterator.GetFirst(); pData != NULL; + pData = aIterator.GetNext() ) + { + if ( pData->bExport ) + { + if ( pData->bByName ) + { + fprintf(stdout,"\t%s\n", + pData->sExportName.GetBuffer()); + } + else + { + fprintf(stdout,"\t%s\t\t@%d NONAME\n", + pData->sExportName.GetBuffer(), pData->nOrdinal+nBegin); + } + } + } +#else + // sortiert nach Ordinals; + LibExport *pData; + for ( unsigned long i=0; i<nBaseLines+1; i++) + { + char * cBuffer = new char[ 30 ]; + sprintf( cBuffer, "%lu", i ); + pData = pIndexTab->Find( cBuffer ); + delete [] cBuffer; + if ( pData ) + if ( pData->bExport ) + { + if ( pData->bByName ) + { + if ( strlen( pData->cExportName )) + fprintf(stdout,"\t%s\n", + pData->cExportName); + } + else + { + if ( strlen( pData->cExportName )) + fprintf(stdout,"\t%s\t\t@%d NONAME\n", + pData->cExportName, pData->nOrdinal+nBegin); + } + } + } +#endif + return true; +} + +bool LibDump::CheckDataBase() +{ + // existiert eine Datenbasis ? + if (!bBase) + { + cBName = new char[ 2048 ]; + char *pTmp = "defs\\"; + + FILE *fp; +#ifdef OS2 + _mkdir ("defs", 0777); +#else + _mkdir ("defs"); +#endif + strcpy(cBName,pTmp); +#ifdef OS2 + strcat(cBName,"gcc"); +#else + strcat(cBName,getenv ("COMP_ENV")); +#endif + + fp = fopen (cBName,"r"); + if (fp) + { + bBase = true; + } + else + { + fp = fopen (cBName,"w+"); + bBase = true; + } + fclose (fp); + } + // lese Datenbasis ! + if (bBase) + { + ReadDataBase(); + } + return true; +} + +LibDump::~LibDump() +{ + delete [] cBName; + delete [] cAPrefix; +// delete [] cLibName; + delete [] cFilterName; + delete [] cModName; +} + +void LibDump::SetCExport( char* pName ) +{ + delete [] cAPrefix; + cAPrefix = new char[ strlen( pName ) + 1 ]; + strcpy( cAPrefix, pName );bAll = true; +} + +//****************************************************************** +//* Error() - Gibt Fehlermeldumg aus +//****************************************************************** + +void LibDump::DumpError( unsigned long n ) +{ + char *p; + + switch (n) + { + case 1: p = "Input error in library file"; break; + case 2: p = "Position error in library file (no THEADR set)"; break; + case 3: p = "Overflow of symbol table"; break; +#ifdef WNT + case 10: p = "EXP file not found"; break; + case 11: p = "No valid EXP file"; break; +#else + case 10: p = "Library file not found"; break; + case 11: p = "No valid library file"; break; +#endif + case 98: p = "Out of memory"; break; + case 99: p = "LDUMP [-LD3] [-D] [-N] [-A] [-E nn] [-F name] Filename[.LIB]\n" + "-LD3 : Supports feature set of ldump3 (default: ldump/ldump2)\n" + "-A : all symbols (default: only C++)\n" + "-E nn : gerenration of export table beginning with number nn\n" + "-F name: Filter file\n" + "-D : file contains \"dumpbin\" directives\n" + "-N : export by name\n" + "-V : be verbose\n"; break; + case 500: p = "Unable to open filter file\n"; break; + case 510: p = "Overflow of filter table\n"; break; + case 600: p = "Unable to open base database file\n"; break; + case 610: p = "Overflow in base database table\n"; break; + default: p = "Unspecified error"; + } + fprintf( stdout, "%s\n", p ); + exit (1); +} + +/********************************************************************* + Test Funktionen +*********************************************************************/ + + +void usage() +{ + LibDump::DumpError(99); +} + +#define STATE_NON 0x0000 +#define STATE_BEGIN 0x0001 +#define STATE_FILTER 0x0002 +#define STATE_CEXPORT 0x0003 + +int +#ifdef WNT +__cdecl +#endif +main( int argc, char **argv ) +{ + char *pLibName = NULL, *pFilterName = NULL, *pCExport= NULL; + unsigned short nBegin=1; + + unsigned short nState = STATE_NON; + + if ( argc == 1 ) { + usage(); + } + + for ( int i = 1; i < argc; i++ ) { + if (( !strcmp( argv[ i ], "-H" )) || + ( !strcmp( argv[ i ], "-h" )) || + ( !strcmp( argv[ i ], "-?" ))) + { + usage(); + } + else if (( !strcmp( argv[ i ], "-LD3" )) || + ( !strcmp( argv[ i ], "-Ld3" )) || + ( !strcmp( argv[ i ], "-ld3" )) || + ( !strcmp( argv[ i ], "-lD3" ))) + { + if ( nState != STATE_NON ) { + usage(); + } + bLdump3 = 1; + } + else if (( !strcmp( argv[ i ], "-E" )) || ( !strcmp( argv[ i ], "-e" ))) { + if ( nState != STATE_NON ) { + usage(); + } + nState = STATE_BEGIN; + } + else if (( !strcmp( argv[ i ], "-F" )) || ( !strcmp( argv[ i ], "-f" ))) { + if ( nState != STATE_NON ) { + usage(); + } + nState = STATE_FILTER; + } + else if (( !strcmp( argv[ i ], "-A" )) || ( !strcmp( argv[ i ], "-a" ))) { + if ( nState != STATE_NON ) { + usage(); + } + nState = STATE_CEXPORT; + pCExport = new char[ 1 ]; + pCExport[ 0 ] = 0; + } + else if (( !strcmp( argv[ i ], "-D" )) || ( !strcmp( argv[ i ], "-d" ))) { + if ( nState != STATE_NON ) { + usage(); + } + bUseDirectives = 1; + } + else if (( !strcmp( argv[ i ], "-N" )) || ( !strcmp( argv[ i ], "-n" ))) { + if ( nState != STATE_NON ) { + usage(); + } + bExportByName = 1; + } + else if (( !strcmp( argv[ i ], "-V" )) || ( !strcmp( argv[ i ], "-v" ))) { + if ( nState != STATE_NON ) { + usage(); + } + bVerbose = 1; + } + else { + switch ( nState ) { + case STATE_BEGIN: + nBegin = static_cast< unsigned short >(atoi( argv[ i ] )); + nState = STATE_NON; + break; + case STATE_FILTER: + pFilterName = new char[ strlen( argv[ i ] ) + 1 ]; + strcpy( pFilterName, argv[ i ] ); + bFilter = 1; + nState = STATE_NON; + break; + case STATE_CEXPORT: + delete [] pCExport; + pCExport = new char[ strlen( argv[ i ] ) + 1 ]; + strcpy( pCExport, argv[ i ] ); + nState = STATE_NON; + break; + default: + pLibName = new char[ strlen( argv[ i ] ) + 1 ]; + strcpy( pLibName, argv[ i ] ); + break; + } + } + } + + if ( !pLibName ) { + usage(); + } + + LibDump *pDump = new LibDump( pLibName, bExportByName ); + pDump->SetBeginExport(nBegin); + if ( bFilter != 0 ) + pDump->SetFilter( pFilterName ); + if ( pCExport ) + pDump->SetCExport( pCExport ); + else { + char *pEmpty = ""; + pDump->SetCExport( pEmpty ); + } + pDump->Dump(); + pDump->PrintDefFile(); + pDump->PrintDataBase(); + delete pDump; + return 0; +} diff --git a/soltools/ldump/ldump.hxx b/soltools/ldump/ldump.hxx new file mode 100644 index 000000000000..c0a1a166b8b2 --- /dev/null +++ b/soltools/ldump/ldump.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "hashtbl.hxx" + +#define MAXFILT 200 + +struct LibExport +{ + char *cExportName; // zu exportierende Fkt. + unsigned long nOrdinal; // Nummer der zu export. Fkt. + bool bByName; // NONAME anhaengen + bool bExport; // exportieren oder nicht ? +}; + +class ExportSet; +class LibDump +{ + ExportSet *pBaseTab; // Zugriff auf gemangelte Namen + ExportSet *pIndexTab; // Zugriff auf die Ordinals + char *cBName; // Name der Datenbasis + char *cAPrefix; // Prefix fuer C-Fkts. + char *cLibName; // Name der zu untersuchenden Lib + char *cFilterName; // Name der Filterdatei + char *cModName; // Modulname + unsigned short nBegin; // Nummer des ersten Exports + unsigned long nBaseLines; // Line in Datenbasis + unsigned long nFilterLines; // Line in FilterTabelle + char **pFilterLines; // Filtertabelle + unsigned long nDefStart; + bool bBase; // Existenz der DatenBasis; + bool bAll; // Alle Fkts exportieren + bool bDef; // DefFile schreiben ( bei -E ) + int bExportName; // 0 - export by ordinal; 1 - export by name + + bool CheckDataBase(); + bool CheckLibrary(char * cName); + bool ReadDataBase(); + bool ReadFilter(char *); + bool PrintSym(char *, bool bName = true ); +public: + LibDump( char *cFileName, int bExportByName ); + ~LibDump(); + bool Dump(); + bool SetFilter(char *cFilterName); + void SetBeginExport(unsigned short nVal){nBegin = nVal;} + void SetCExport( char* pName ); + bool Filter(char *pName); + bool IsFromAnonymousNamespace(char *pName); + bool PrintDefFile(); + bool PrintDataBase(); + static void DumpError(unsigned long nError); +}; + diff --git a/soltools/ldump/makefile.mk b/soltools/ldump/makefile.mk new file mode 100644 index 000000000000..51ff42e60772 --- /dev/null +++ b/soltools/ldump/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=ldump +TARGET=ldump +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +UWINAPILIB=$(0) +LIBSALCPPRT=$(0) + +# --- Files -------------------------------------------------------- + +# ldump only supports windows environment +.IF "$(GUI)"=="WNT" || "$(GUI)"=="OS2" +.IF "$(COM)"!="GCC" +#ldump4 reimplements feature set of ldump2 and ldump3 +APP1TARGET= ldump4 +.IF "$(GUI)"=="WNT" +APP1STACK= 16000 +.ENDIF +APP1OBJS= $(OBJ)$/ldump.obj $(OBJ)$/hashtbl.obj + +.ENDIF #"$(COM)"!="GCC" +.ENDIF #"$(GUI)"=="WNT" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/mkdepend/collectdircontent.cxx b/soltools/mkdepend/collectdircontent.cxx new file mode 100755 index 000000000000..c9308faf0562 --- /dev/null +++ b/soltools/mkdepend/collectdircontent.cxx @@ -0,0 +1,83 @@ +#include "collectdircontent.hxx" + +PathFilePair IncludesCollection::split_path(const string& filePath) { + string sepU = "/"; + string sepW = "\\"; + string::size_type pos = filePath.rfind (sepU); + string::size_type posW = filePath.rfind (sepW); + if ((posW != string::npos) && ((posW > pos) || (pos == string::npos))) pos = posW; + if (pos != string::npos) { + string dirName = filePath.substr(0, pos); + return PathFilePair(dirName, filePath.substr(pos + 1, filePath.length())); + } else + return PathFilePair(".", filePath); +}; + +void IncludesCollection::add_to_collection(const string& dirPath) { + DirContent dirContent; +#if defined( WNT ) + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + hFind = FindFirstFile((dirPath + "\\*").c_str(), &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) { + // Invalid File Handle - no need to try it anymore + allIncludes.insert(EntriesPair(dirPath, DirContent())); + return; + }; + do { + string winFileName(FindFileData.cFileName); + transform(winFileName.begin(), winFileName.end(), winFileName.begin(), ::tolower); + dirContent.insert(winFileName); + } while (FindNextFile(hFind, &FindFileData)); +#else + DIR *pdir; + dirent *pent; + pdir = opendir(dirPath.c_str()); //"." refers to the current dir + if (!pdir) { + // Invalid File Handle - no need to try it anymore + allIncludes.insert(EntriesPair(dirPath, DirContent())); + return; + } + while ((pent = readdir(pdir))) { + dirContent.insert(pent->d_name); + }; +#endif // defined( WNT ) + allIncludes.insert(EntriesPair(dirPath, dirContent)); +}; + +bool IncludesCollection::exists(string filePath) { +#if defined( WNT ) + transform(filePath.begin(), filePath.end(), filePath.begin(), ::tolower); +#endif // defined( WNT ) + PathFilePair dirFile = split_path(filePath); + string dirPath = dirFile.first; + string fileName = dirFile.second; + DirMap::iterator mapIter = allIncludes.find(dirPath); + if (mapIter == allIncludes.end()) { + add_to_collection(dirPath); + mapIter = allIncludes.find(dirPath); + }; + DirContent dirContent = (*mapIter).second; + DirContent::iterator dirIter = dirContent.find(fileName); + if (dirIter == dirContent.end()) { + return false; + } else { + return true; + }; + //return false; +}; + +extern "C" { + + IncludesCollection * create_IncludesCollection() { + return new IncludesCollection; + } + + void delete_IncludesCollection(IncludesCollection *m) { + delete m; + } + + int call_IncludesCollection_exists(IncludesCollection* m, const char * filePath) { + return m->exists(filePath); + } +} diff --git a/soltools/mkdepend/collectdircontent.hxx b/soltools/mkdepend/collectdircontent.hxx new file mode 100644 index 000000000000..1896df0c8bc7 --- /dev/null +++ b/soltools/mkdepend/collectdircontent.hxx @@ -0,0 +1,58 @@ +#ifndef COLLECTDIRCONTENT_H +#define COLLECTDIRCONTENT_H + +#if defined __cplusplus + +#include <set> +#include <map> +#include <string> + +#if defined( WNT ) +#include <windows.h> +#include <algorithm> +#else +#include <dirent.h> +#endif // defined( WNT ) + +#include <iostream> + +using namespace std; + +typedef set<string> DirContent; +typedef map<string, DirContent> DirMap; +typedef DirMap::value_type EntriesPair; +typedef pair<string, string> PathFilePair; + + +struct IncludesCollection { + private: + DirMap allIncludes; +// bool search(string filePath); +// bool add_dir(string dirPath); + PathFilePair split_path(const string& filePath); + void add_to_collection(const string& dirPath); + + public: + bool exists(string filePath); +}; + +#else + +struct IncludesCollection; + +#endif + +#if defined __cplusplus +extern "C" { +#endif + +struct IncludesCollection * create_IncludesCollection(void); +void delete_IncludesCollection(struct IncludesCollection *); + +int call_IncludesCollection_exists(struct IncludesCollection* m, const char* filePath); + +#if defined __cplusplus +} +#endif + +#endif // COLLECTDIRCONTENT_H diff --git a/soltools/mkdepend/cppsetup.c b/soltools/mkdepend/cppsetup.c new file mode 100644 index 000000000000..173798105a3c --- /dev/null +++ b/soltools/mkdepend/cppsetup.c @@ -0,0 +1,234 @@ +/* $XConsortium: cppsetup.c,v 1.13 94/04/17 20:10:32 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" + +#ifdef CPP +/* + * This file is strictly for the sake of cpy.y and yylex.c (if + * you indeed have the source for cpp). + */ +#define IB 1 +#define SB 2 +#define NB 4 +#define CB 8 +#define QB 16 +#define WB 32 +#define SALT '#' +#if pdp11 | vax | ns16000 | mc68000 | ibm032 +#define COFF 128 +#else +#define COFF 0 +#endif +/* + * These variables used by cpy.y and yylex.c + */ +extern char *outp, *inp, *newp, *pend; +extern char *ptrtab; +extern char fastab[]; +extern char slotab[]; + +/* + * cppsetup + */ +struct filepointer *currentfile; +struct inclist *currentinc; + +cppsetup(line, filep, inc) + register char *line; + register struct filepointer *filep; + register struct inclist *inc; +{ + register char *p, savec; + static boolean setupdone = FALSE; + boolean value; + + if (!setupdone) { + cpp_varsetup(); + setupdone = TRUE; + } + + currentfile = filep; + currentinc = inc; + inp = newp = line; + for (p=newp; *p; p++) + ; + + /* + * put a newline back on the end, and set up pend, etc. + */ + *p++ = '\n'; + savec = *p; + *p = '\0'; + pend = p; + + ptrtab = slotab+COFF; + *--inp = SALT; + outp=inp; + value = yyparse(); + *p = savec; + return(value); +} + +pperror(tag, x0,x1,x2,x3,x4) + int tag,x0,x1,x2,x3,x4; +{ + warning("\"%s\", line %d: ", currentinc->i_file, currentfile->f_line); + warning(x0,x1,x2,x3,x4); +} + + +yyerror(s) + register char *s; +{ + fatalerr("Fatal error: %s\n", s); +} +#else /* not CPP */ + +#include "ifparser.h" +struct _parse_data { + struct filepointer *filep; + struct inclist *inc; + const char *line; +}; + +static const char * +_my_if_errors (ip, cp, expecting) + IfParser *ip; + const char *cp; + const char *expecting; +{ +#ifdef DEBUG_MKDEPEND + struct _parse_data *pd = (struct _parse_data *) ip->data; + int lineno = pd->filep->f_line; + char *filename = pd->inc->i_file; + char prefix[300]; + int prefixlen; + int i; + + sprintf (prefix, "\"%s\":%d", filename, lineno); + prefixlen = strlen(prefix); + fprintf (stderr, "%s: %s", prefix, pd->line); + i = cp - pd->line; + if (i > 0 && pd->line[i-1] != '\n') { + putc ('\n', stderr); + } + for (i += prefixlen + 3; i > 0; i--) { + putc (' ', stderr); + } + fprintf (stderr, "^--- expecting %s\n", expecting); +#endif /* DEBUG_MKDEPEND */ + (void)ip; + (void)cp; + (void)expecting; + return NULL; +} + + +#define MAXNAMELEN 256 + +char * +_lookup_variable (var, len) + const char *var; + int len; +{ + char tmpbuf[MAXNAMELEN + 1]; + + if (len > MAXNAMELEN) + return 0; + + strncpy (tmpbuf, var, len); + tmpbuf[len] = '\0'; + return isdefined(tmpbuf); +} + + +static int +_my_eval_defined (ip, var, len) + IfParser *ip; + const char *var; + int len; +{ + (void)ip; + if (_lookup_variable (var, len)) + return 1; + else + return 0; +} + +#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') + +static int +_my_eval_variable (ip, var, len) + IfParser *ip; + const char *var; + int len; +{ + char *s; + + (void)ip; + + s = _lookup_variable (var, len); + if (!s) + return 0; + do { + var = s; + if (!isvarfirstletter(*var)) + break; + s = _lookup_variable (var, strlen(var)); + } while (s); + + return atoi(var); +} + + +int cppsetup(line, filep, inc) + register char *line; + register struct filepointer *filep; + register struct inclist *inc; +{ + IfParser ip; + struct _parse_data pd; + int val = 0; + + pd.filep = filep; + pd.inc = inc; + pd.line = line; + ip.funcs.handle_error = _my_if_errors; + ip.funcs.eval_defined = _my_eval_defined; + ip.funcs.eval_variable = _my_eval_variable; + ip.data = (char *) &pd; + + (void) ParseIfExpression (&ip, line, &val); + if (val) + return IF; + else + return IFFALSE; +} +#endif /* CPP */ + diff --git a/soltools/mkdepend/def.h b/soltools/mkdepend/def.h new file mode 100644 index 000000000000..4133326ddb70 --- /dev/null +++ b/soltools/mkdepend/def.h @@ -0,0 +1,189 @@ +/* $XConsortium: def.h,v 1.25 94/04/17 20:10:33 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#ifndef NO_X11 +#include <X11/Xosdefs.h> +#ifdef WIN32 +#include <X11/Xw32defs.h> +#endif +#ifndef SUNOS4 +#include <X11/Xfuncproto.h> +#endif /* SUNOS4 */ +#endif /* NO_X11 */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <ctype.h> +#ifndef X_NOT_POSIX +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE +#endif +#endif +#include <sys/types.h> +#include <fcntl.h> +#include <sys/stat.h> + +#ifndef S_IFDIR +#define S_IFDIR 0040000 +#endif + +#ifndef S_IFREG +#define S_IFREG 0100000 +#endif + +#define MAXDEFINES 512 +#define MAXFILES ( 1<<16 ) /* Increased from 512. -mcafee */ + /* Increased from 1024. -mh */ + /* Increased from 2048. -b_michaelsen */ +#define MAXDIRS 64 +#define SYMHASHSEED 131 /* 131 1313 13131 ... */ +#define SYMHASHMEMBERS 64 /* must be 2^x to work right */ +#define TRUE 1 +#define FALSE 0 + +/* the following must match the directives table in main.c */ +#define IF 0 +#define IFDEF 1 +#define IFNDEF 2 +#define ELSE 3 +#define ENDIF 4 +#define DEFINE 5 +#define UNDEF 6 +#define INCLUDE 7 +#define LINE 8 +#define PRAGMA 9 +#define ERROR 10 +#define IDENT 11 +#define SCCS 12 +#define ELIF 13 +#define EJECT 14 +#define IFFALSE 15 /* pseudo value --- never matched */ +#define ELIFFALSE 16 /* pseudo value --- never matched */ +#define INCLUDEDOT 17 /* pseudo value --- never matched */ +#define IFGUESSFALSE 18 /* pseudo value --- never matched */ +#define ELIFGUESSFALSE 19 /* pseudo value --- never matched */ + +#ifdef DEBUG +extern int _debugmask; +/* + * debug levels are: + * + * 0 show ifn*(def)*,endif + * 1 trace defined/!defined + * 2 show #include + * 3 show #include SYMBOL + * 4-6 unused + */ +#define debug(level,arg) { if (_debugmask & (1 << level)) warning arg; } +#else +#define debug(level,arg) /**/ +#endif /* DEBUG */ + +// VG: a C++ class for information about directories +#include "collectdircontent.hxx" + +typedef unsigned char boolean; + +struct pair { + char *p_name; + char *p_value; + struct pair *p_next; +}; + +struct symhash { + struct pair *s_pairs[SYMHASHMEMBERS]; +}; + +struct inclist { + char *i_incstring; /* string from #include line */ + char *i_file; /* path name of the include file */ + struct inclist **i_list; /* list of files it itself includes */ + int i_listlen; /* length of i_list */ + boolean i_defchecked; /* whether defines have been checked */ + boolean i_notified; /* whether we have revealed includes */ + boolean i_marked; /* whether it's in the makefile */ + boolean i_searched; /* whether we have read this */ + boolean i_included_sym; /* whether #include SYMBOL was found */ + /* Can't use i_list if TRUE */ +}; + +struct filepointer { + char *f_p; + char *f_base; + char *f_end; + long f_len; + long f_line; +}; + +#ifndef X_NOT_STDC_ENV +#include <stdlib.h> +#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */ +char *malloc(), *realloc(); +#endif /* macII */ +#else +char *malloc(); +char *realloc(); +#endif + +char *copy(); +char *base_name(); +char *get_line(); +char *isdefined(); +struct filepointer *getfile(); +struct inclist *newinclude(); +struct inclist *inc_path(); + +void define( char *def, struct symhash **symbols ); +void hash_define(char *name, char * val, struct symhash **symbols); +struct symhash *hash_copy( struct symhash *symbols ); +void hash_free( struct symhash *symbols ); +void freefile( struct filepointer * fp ); +int find_includes(struct filepointer *filep, struct inclist *file, + struct inclist *file_red, int recursion, boolean failOK, + struct IncludesCollection* incCollection, struct symhash *symbols); +void included_by(register struct inclist *ip, + register struct inclist * newfile); +int cppsetup(register char *line, + register struct filepointer *filep, register struct inclist *inc); +void add_include(struct filepointer *filep, struct inclist *file, + struct inclist *file_red, char *include, boolean dot, boolean failOK, + struct IncludesCollection* incCollection, struct symhash *symbols); +int match(register char *str, register char **list); +void recursive_pr_include(register struct inclist *head, register char *file, + register char *base); +void inc_clean(); + +void fatalerr(char *, ...); +void warning(char *, ...); +void warning1(char *, ...); + +void convert_slashes(char *); +char *append_slash(char *); diff --git a/soltools/mkdepend/ifparser.c b/soltools/mkdepend/ifparser.c new file mode 100644 index 000000000000..3c47de64e2f0 --- /dev/null +++ b/soltools/mkdepend/ifparser.c @@ -0,0 +1,460 @@ +/* + * $XConsortium: ifparser.c,v 1.8 95/06/03 00:01:41 gildea Exp $ + * + * Copyright 1992 Network Computing Devices, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices may not be + * used in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Network Computing Devices makes + * no representations about the suitability of this software for any purpose. + * It is provided ``as is'' without express or implied warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Fulton + * Network Computing Devices, Inc. + * + * Simple if statement processor + * + * This module can be used to evaluate string representations of C language + * if constructs. It accepts the following grammar: + * + * EXPRESSION := VALUE + * | VALUE BINOP EXPRESSION + * + * VALUE := '(' EXPRESSION ')' + * | '!' VALUE + * | '-' VALUE + * | 'defined' '(' variable ')' + * | 'defined' variable + * | # variable '(' variable-list ')' + * | variable + * | number + * + * BINOP := '*' | '/' | '%' + * | '+' | '-' + * | '<<' | '>>' + * | '<' | '>' | '<=' | '>=' + * | '==' | '!=' + * | '&' | '|' + * | '&&' | '||' + * + * The normal C order of precidence is supported. + * + * + * External Entry Points: + * + * ParseIfExpression parse a string for #if + */ + +#include "ifparser.h" +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +/**************************************************************************** + Internal Macros and Utilities for Parser + ****************************************************************************/ + +#define DO(val) if (!(val)) return NULL +#define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff)) +#define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++ +#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') + + +static const char * +parse_variable (g, cp, varp) + IfParser *g; + const char *cp; + const char **varp; +{ + SKIPSPACE (cp); + + if (!isvarfirstletter (*cp)) + return CALLFUNC(g, handle_error) (g, cp, "variable name"); + + *varp = cp; + /* EMPTY */ + for (cp++; isalnum(*cp) || *cp == '_'; cp++) ; + return cp; +} + + +static const char * +parse_number (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + SKIPSPACE (cp); + + if (!isdigit(*cp)) + return CALLFUNC(g, handle_error) (g, cp, "number"); + +#ifdef WIN32 + *valp = strtol(cp, &cp, 0); +#else + *valp = atoi (cp); + /* EMPTY */ + for (cp++; isdigit(*cp); cp++) ; +#endif + return cp; +} + + +static const char * +parse_value (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + const char *var; + + *valp = 0; + + SKIPSPACE (cp); + if (!*cp) + return cp; + + switch (*cp) { + case '(': + DO (cp = ParseIfExpression (g, cp + 1, valp)); + SKIPSPACE (cp); + if (*cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + + return cp + 1; /* skip the right paren */ + + case '!': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = !(*valp); + return cp; + + case '-': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = -(*valp); + return cp; + + case '#': + DO (cp = parse_variable (g, cp + 1, &var)); + SKIPSPACE (cp); + if (*cp != '(') + return CALLFUNC(g, handle_error) (g, cp, "("); + do { + DO (cp = parse_variable (g, cp + 1, &var)); + SKIPSPACE (cp); + } while (*cp && *cp != ')'); + if (*cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + *valp = 1; /* XXX */ + return cp + 1; + + case 'd': + if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) { + int paren = 0; + int len; + + cp += 7; + SKIPSPACE (cp); + if (*cp == '(') { + paren = 1; + cp++; + } + DO (cp = parse_variable (g, cp, &var)); + len = cp - var; + SKIPSPACE (cp); + if (paren && *cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + *valp = (*(g->funcs.eval_defined)) (g, var, len); + return cp + paren; /* skip the right paren */ + } + /* fall out */ + } + + if (isdigit(*cp)) { + DO (cp = parse_number (g, cp, valp)); + } else if (!isvarfirstletter(*cp)) + return CALLFUNC(g, handle_error) (g, cp, "variable or number"); + else { + DO (cp = parse_variable (g, cp, &var)); + *valp = (*(g->funcs.eval_variable)) (g, var, cp - var); + } + + return cp; +} + + + +static const char * +parse_product (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_value (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '*': + DO (cp = parse_product (g, cp + 1, &rightval)); + *valp = (*valp * rightval); + break; + + case '/': + DO (cp = parse_product (g, cp + 1, &rightval)); + + /* Do nothing in the divide-by-zero case. */ + if (rightval) { + *valp = (*valp / rightval); + } + break; + + case '%': + DO (cp = parse_product (g, cp + 1, &rightval)); + *valp = (*valp % rightval); + break; + } + return cp; +} + + +static const char * +parse_sum (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_product (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '+': + DO (cp = parse_sum (g, cp + 1, &rightval)); + *valp = (*valp + rightval); + break; + + case '-': + DO (cp = parse_sum (g, cp + 1, &rightval)); + *valp = (*valp - rightval); + break; + } + return cp; +} + + +static const char * +parse_shift (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_sum (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '<': + if (cp[1] == '<') { + DO (cp = parse_shift (g, cp + 2, &rightval)); + *valp = (*valp << rightval); + } + break; + + case '>': + if (cp[1] == '>') { + DO (cp = parse_shift (g, cp + 2, &rightval)); + *valp = (*valp >> rightval); + } + break; + } + return cp; +} + + +static const char * +parse_inequality (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_shift (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '<': + if (cp[1] == '=') { + DO (cp = parse_inequality (g, cp + 2, &rightval)); + *valp = (*valp <= rightval); + } else { + DO (cp = parse_inequality (g, cp + 1, &rightval)); + *valp = (*valp < rightval); + } + break; + + case '>': + if (cp[1] == '=') { + DO (cp = parse_inequality (g, cp + 2, &rightval)); + *valp = (*valp >= rightval); + } else { + DO (cp = parse_inequality (g, cp + 1, &rightval)); + *valp = (*valp > rightval); + } + break; + } + return cp; +} + + +static const char * +parse_equality (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_inequality (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '=': + if (cp[1] == '=') + cp++; + DO (cp = parse_equality (g, cp + 1, &rightval)); + *valp = (*valp == rightval); + break; + + case '!': + if (cp[1] != '=') + break; + DO (cp = parse_equality (g, cp + 2, &rightval)); + *valp = (*valp != rightval); + break; + } + return cp; +} + + +static const char * +parse_band (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_equality (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '&': + if (cp[1] != '&') { + DO (cp = parse_band (g, cp + 1, &rightval)); + *valp = (*valp & rightval); + } + break; + } + return cp; +} + + +static const char * +parse_bor (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_band (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '|': + if (cp[1] != '|') { + DO (cp = parse_bor (g, cp + 1, &rightval)); + *valp = (*valp | rightval); + } + break; + } + return cp; +} + + +static const char * +parse_land (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_bor (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '&': + if (cp[1] != '&') + return CALLFUNC(g, handle_error) (g, cp, "&&"); + DO (cp = parse_land (g, cp + 2, &rightval)); + *valp = (*valp && rightval); + break; + } + return cp; +} + + +static const char * +parse_lor (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_land (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '|': + if (cp[1] != '|') + return CALLFUNC(g, handle_error) (g, cp, "||"); + DO (cp = parse_lor (g, cp + 2, &rightval)); + *valp = (*valp || rightval); + break; + } + return cp; +} + + +/**************************************************************************** + External Entry Points + ****************************************************************************/ + +const char * +ParseIfExpression (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + return parse_lor (g, cp, valp); +} + + diff --git a/soltools/mkdepend/ifparser.h b/soltools/mkdepend/ifparser.h new file mode 100644 index 000000000000..d832bfbcb6d7 --- /dev/null +++ b/soltools/mkdepend/ifparser.h @@ -0,0 +1,75 @@ +/* + * $XConsortium: ifparser.h,v 1.1 92/08/22 13:05:39 rws Exp $ + * + * Copyright 1992 Network Computing Devices, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices may not be + * used in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Network Computing Devices makes + * no representations about the suitability of this software for any purpose. + * It is provided ``as is'' without express or implied warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Fulton + * Network Computing Devices, Inc. + * + * Simple if statement processor + * + * This module can be used to evaluate string representations of C language + * if constructs. It accepts the following grammar: + * + * EXPRESSION := VALUE + * | VALUE BINOP EXPRESSION + * + * VALUE := '(' EXPRESSION ')' + * | '!' VALUE + * | '-' VALUE + * | 'defined' '(' variable ')' + * | variable + * | number + * + * BINOP := '*' | '/' | '%' + * | '+' | '-' + * | '<<' | '>>' + * | '<' | '>' | '<=' | '>=' + * | '==' | '!=' + * | '&' | '|' + * | '&&' | '||' + * + * The normal C order of precidence is supported. + * + * + * External Entry Points: + * + * ParseIfExpression parse a string for #if + */ + +#include <stdio.h> + +typedef int Bool; +#define False 0 +#define True 1 + +typedef struct _if_parser { + struct { /* functions */ + const char *(*handle_error) (/* struct _if_parser *, const char *, + const char * */); + int (*eval_variable) (/* struct _if_parser *, const char *, int */); + int (*eval_defined) (/* struct _if_parser *, const char *, int */); + } funcs; + char *data; +} IfParser; + +const char *ParseIfExpression (/* IfParser *, const char *, int * */); + diff --git a/soltools/mkdepend/imakemdep.h b/soltools/mkdepend/imakemdep.h new file mode 100644 index 000000000000..67a98929c904 --- /dev/null +++ b/soltools/mkdepend/imakemdep.h @@ -0,0 +1,730 @@ + +/* $XConsortium: imakemdep.h,v 1.83 95/04/07 19:47:46 kaleb Exp $ */ +/* $XFree86: xc/config/imake/imakemdep.h,v 3.12 1995/07/08 10:22:17 dawes Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + + +/* + * This file contains machine-dependent constants for the imake utility. + * When porting imake, read each of the steps below and add in any necessary + * definitions. In general you should *not* edit ccimake.c or imake.c! + */ + +#ifdef CCIMAKE +/* + * Step 1: imake_ccflags + * Define any special flags that will be needed to get imake.c to compile. + * These will be passed to the compile along with the contents of the + * make variable BOOTSTRAPCFLAGS. + */ +#ifdef hpux +#ifdef hp9000s800 +#define imake_ccflags "-DSYSV" +#else +#define imake_ccflags "-Wc,-Nd4000,-Ns3000 -DSYSV" +#endif +#endif + +#if defined(macII) || defined(_AUX_SOURCE) +#define imake_ccflags "-DmacII -DSYSV" +#endif + +#ifdef stellar +#define imake_ccflags "-DSYSV" +#endif + +#if defined(USL) || defined(Oki) || defined(NCR) +#define imake_ccflags "-Xc -DSVR4" +#endif + +#ifdef sony +#if defined(SYSTYPE_SYSV) || defined(_SYSTYPE_SYSV) +#define imake_ccflags "-DSVR4" +#else +#include <sys/param.h> +#if NEWSOS < 41 +#define imake_ccflags "-Dbsd43 -DNOSTDHDRS" +#else +#if NEWSOS < 42 +#define imake_ccflags "-Dbsd43" +#endif +#endif +#endif +#endif + +#ifdef _CRAY +#define imake_ccflags "-DSYSV -DUSG" +#endif + +#if defined(_IBMR2) || defined(aix) +#define imake_ccflags "-Daix -DSYSV" +#endif + +#ifdef Mips +# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) +# define imake_ccflags "-DBSD43" +# else +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef is68k +#define imake_ccflags "-Dluna -Duniosb" +#endif + +#ifdef SYSV386 +# ifdef SVR4 +# define imake_ccflags "-Xc -DSVR4" +# else +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef SVR4 +# ifdef i386 +# define imake_ccflags "-Xc -DSVR4" +# endif +#endif + +#ifdef SYSV +# ifdef i386 +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef __convex__ +#define imake_ccflags "-fn -tm c1" +#endif + +#ifdef apollo +#define imake_ccflags "-DX_NOT_POSIX" +#endif + +#ifdef WIN32 +#define imake_ccflags "-nologo -batch -D__STDC__" +#endif + +#ifdef __uxp__ +#define imake_ccflags "-DSVR4 -DANSICPP" +#endif + +#ifdef __sxg__ +#define imake_ccflags "-DSYSV -DUSG -DNOSTDHDRS" +#endif + +#ifdef sequent +#define imake_ccflags "-DX_NOT_STDC_ENV -DX_NOT_POSIX" +#endif + +#ifdef _SEQUENT_ +#define imake_ccflags "-DSYSV -DUSG" +#endif + +#if defined(SX) || defined(PC_UX) +#define imake_ccflags "-DSYSV" +#endif + +#ifdef nec_ews_svr2 +#define imake_ccflags "-DUSG" +#endif + +#if defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(_nec_up) || defined(_nec_ft) +#define imake_ccflags "-DSVR4" +#endif + +#ifdef MACH +#define imake_ccflags "-DNOSTDHDRS" +#endif + +/* this is for OS/2 under EMX. This won't work with DOS */ +#if defined(__EMX__) +#define imake_ccflags "-DBSD43" +#endif + +#else /* not CCIMAKE */ +#ifndef MAKEDEPEND +/* + * Step 2: dup2 + * If your OS doesn't have a dup2() system call to duplicate one file + * descriptor onto another, define such a mechanism here (if you don't + * already fall under the existing category(ies). + */ +#if defined(SYSV) && !defined(_CRAY) && !defined(Mips) && !defined(_SEQUENT_) +#define dup2(fd1,fd2) ((fd1 == fd2) ? fd1 : (close(fd2), \ + fcntl(fd1, F_DUPFD, fd2))) +#endif + + +/* + * Step 3: FIXUP_CPP_WHITESPACE + * If your cpp collapses tabs macro expansions into a single space and + * replaces escaped newlines with a space, define this symbol. This will + * cause imake to attempt to patch up the generated Makefile by looking + * for lines that have colons in them (this is why the rules file escapes + * all colons). One way to tell if you need this is to see whether or not + * your Makefiles have no tabs in them and lots of @@ strings. + */ +#if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(WIN32) || (defined(AMOEBA) && defined(CROSS_COMPILE)) +#define FIXUP_CPP_WHITESPACE +#endif +#ifdef WIN32 +#define REMOVE_CPP_LEADSPACE +#define INLINE_SYNTAX +#define MAGIC_MAKE_VARS +#endif +#ifdef __minix_vmd +#define FIXUP_CPP_WHITESPACE +#endif + +/* + * Step 4: USE_CC_E, DEFAULT_CC, DEFAULT_CPP + * If you want to use cc -E instead of cpp, define USE_CC_E. + * If use cc -E but want a different compiler, define DEFAULT_CC. + * If the cpp you need is not in /lib/cpp, define DEFAULT_CPP. + */ +#ifdef hpux +#define USE_CC_E +#endif +#ifdef WIN32 +#define USE_CC_E +#define DEFAULT_CC "cl" +#endif +#ifdef apollo +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#if defined(_IBMR2) && !defined(DEFAULT_CPP) +#define DEFAULT_CPP "/usr/lpp/X11/Xamples/util/cpp/cpp" +#endif +#if defined(sun) && defined(SVR4) +#define DEFAULT_CPP "/usr/ccs/lib/cpp" +#endif +#ifdef __bsdi__ +#define DEFAULT_CPP "/usr/bin/cpp" +#endif +#ifdef __uxp__ +#define DEFAULT_CPP "/usr/ccs/lib/cpp" +#endif +#ifdef __sxg__ +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#ifdef _CRAY +#define DEFAULT_CPP "/lib/pcpp" +#endif +#if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#define DEFAULT_CPP "/usr/libexec/cpp" +#endif +#ifdef MACH +#define USE_CC_E +#endif +#ifdef __minix_vmd +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#if defined(__EMX__) +/* expects cpp in PATH */ +#define DEFAULT_CPP "cpp" +#endif + +/* + * Step 5: cpp_argv + * The following table contains the flags that should be passed + * whenever a Makefile is being generated. If your preprocessor + * doesn't predefine any unique symbols, choose one and add it to the + * end of this table. Then, do the following: + * + * a. Use this symbol in Imake.tmpl when setting MacroFile. + * b. Put this symbol in the definition of BootstrapCFlags in your + * <platform>.cf file. + * c. When doing a make World, always add "BOOTSTRAPCFLAGS=-Dsymbol" + * to the end of the command line. + * + * Note that you may define more than one symbol (useful for platforms + * that support multiple operating systems). + */ + +#define ARGUMENTS 50 /* number of arguments in various arrays */ +char *cpp_argv[ARGUMENTS] = { + "cc", /* replaced by the actual program to exec */ + "-I.", /* add current directory to include path */ +#ifdef unix + "-Uunix", /* remove unix symbol so that filename unix.c okay */ +#endif +#if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(MACH) +# ifdef __i386__ + "-D__i386__", +# endif +# ifdef __GNUC__ + "-traditional", +# endif +#endif +#ifdef M4330 + "-DM4330", /* Tektronix */ +#endif +#ifdef M4310 + "-DM4310", /* Tektronix */ +#endif +#if defined(macII) || defined(_AUX_SOURCE) + "-DmacII", /* Apple A/UX */ +#endif +#ifdef USL + "-DUSL", /* USL */ +#endif +#ifdef sony + "-Dsony", /* Sony */ +#if !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) && NEWSOS < 42 + "-Dbsd43", +#endif +#endif +#ifdef _IBMR2 + "-D_IBMR2", /* IBM RS-6000 (we ensured that aix is defined above */ +#ifndef aix +#define aix /* allow BOOTSTRAPCFLAGS="-D_IBMR2" */ +#endif +#endif /* _IBMR2 */ +#ifdef aix + "-Daix", /* AIX instead of AOS */ +#ifndef ibm +#define ibm /* allow BOOTSTRAPCFLAGS="-Daix" */ +#endif +#endif /* aix */ +#ifdef ibm + "-Dibm", /* IBM PS/2 and RT under both AOS and AIX */ +#endif +#ifdef luna + "-Dluna", /* OMRON luna 68K and 88K */ +#ifdef luna1 + "-Dluna1", +#endif +#ifdef luna88k /* need not on UniOS-Mach Vers. 1.13 */ + "-traditional", /* for some older version */ +#endif /* instead of "-DXCOMM=\\#" */ +#ifdef uniosb + "-Duniosb", +#endif +#ifdef uniosu + "-Duniosu", +#endif +#endif /* luna */ +#ifdef _CRAY /* Cray */ + "-Ucray", +#endif +#ifdef Mips + "-DMips", /* Define and use Mips for Mips Co. OS/mach. */ +# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) + "-DBSD43", /* Mips RISCOS supports two environments */ +# else + "-DSYSV", /* System V environment is the default */ +# endif +#endif /* Mips */ +#ifdef MOTOROLA + "-DMOTOROLA", /* Motorola Delta Systems */ +# ifdef SYSV + "-DSYSV", +# endif +# ifdef SVR4 + "-DSVR4", +# endif +#endif /* MOTOROLA */ +#ifdef i386 + "-Di386", +# ifdef SVR4 + "-DSVR4", +# endif +# ifdef SYSV + "-DSYSV", +# ifdef ISC + "-DISC", +# ifdef ISC40 + "-DISC40", /* ISC 4.0 */ +# else +# ifdef ISC202 + "-DISC202", /* ISC 2.0.2 */ +# else +# ifdef ISC30 + "-DISC30", /* ISC 3.0 */ +# else + "-DISC22", /* ISC 2.2.1 */ +# endif +# endif +# endif +# endif +# ifdef SCO + "-DSCO", +# ifdef SCO324 + "-DSCO324", +# endif +# endif +# endif +# ifdef ESIX + "-DESIX", +# endif +# ifdef ATT + "-DATT", +# endif +# ifdef DELL + "-DDELL", +# endif +#endif +#ifdef SYSV386 /* System V/386 folks, obsolete */ + "-Di386", +# ifdef SVR4 + "-DSVR4", +# endif +# ifdef ISC + "-DISC", +# ifdef ISC40 + "-DISC40", /* ISC 4.0 */ +# else +# ifdef ISC202 + "-DISC202", /* ISC 2.0.2 */ +# else +# ifdef ISC30 + "-DISC30", /* ISC 3.0 */ +# else + "-DISC22", /* ISC 2.2.1 */ +# endif +# endif +# endif +# endif +# ifdef SCO + "-DSCO", +# ifdef SCO324 + "-DSCO324", +# endif +# endif +# ifdef ESIX + "-DESIX", +# endif +# ifdef ATT + "-DATT", +# endif +# ifdef DELL + "-DDELL", +# endif +#endif +#ifdef __osf__ + "-D__osf__", +# ifdef __mips__ + "-D__mips__", +# endif +# ifdef __alpha + "-D__alpha", +# endif +# ifdef __i386__ + "-D__i386__", +# endif +# ifdef __GNUC__ + "-traditional", +# endif +#endif +#ifdef Oki + "-DOki", +#endif +#ifdef sun +#ifdef SVR4 + "-DSVR4", +#endif +#endif +#ifdef WIN32 + "-DWIN32", + "-nologo", + "-batch", + "-D__STDC__", +#endif +#ifdef NCR + "-DNCR", /* NCR */ +#endif +#ifdef linux + "-traditional", + "-Dlinux", +#endif +#ifdef __uxp__ + "-D__uxp__", +#endif +#ifdef __sxg__ + "-D__sxg__", +#endif +#ifdef nec_ews_svr2 + "-Dnec_ews_svr2", +#endif +#ifdef AMOEBA + "-DAMOEBA", +# ifdef CROSS_COMPILE + "-DCROSS_COMPILE", +# ifdef CROSS_i80386 + "-Di80386", +# endif +# ifdef CROSS_sparc + "-Dsparc", +# endif +# ifdef CROSS_mc68000 + "-Dmc68000", +# endif +# else +# ifdef i80386 + "-Di80386", +# endif +# ifdef sparc + "-Dsparc", +# endif +# ifdef mc68000 + "-Dmc68000", +# endif +# endif +#endif +#ifdef __minix_vmd + "-Dminix", +#endif + +#if defined(__EMX__) + "-traditional", + "-Demxos2", +#endif + +}; +#else /* else MAKEDEPEND */ +/* + * Step 6: predefs + * If your compiler and/or preprocessor define any specific symbols, add + * them to the the following table. The definition of struct symtab is + * in util/makedepend/def.h. + */ +struct pair predefs[] = { +#ifdef apollo + {"apollo", "1", NULL}, +#endif +#ifdef ibm032 + {"ibm032", "1", NULL}, +#endif +#ifdef ibm + {"ibm", "1", NULL}, +#endif +#ifdef aix + {"aix", "1", NULL}, +#endif +#ifdef sun + {"sun", "1", NULL}, +#endif +#ifdef sun2 + {"sun2", "1", NULL}, +#endif +#ifdef sun3 + {"sun3", "1", NULL}, +#endif +#ifdef sun4 + {"sun4", "1", NULL}, +#endif +#ifdef sparc + {"sparc", "1", NULL}, +#endif +#ifdef __sparc__ + {"__sparc__", "1", NULL}, +#endif +#ifdef hpux + {"hpux", "1", NULL}, +#endif +#ifdef __hpux + {"__hpux", "1", NULL}, +#endif +#ifdef __hp9000s800 + {"__hp9000s800", "1", NULL}, +#endif +#ifdef __hp9000s700 + {"__hp9000s700", "1", NULL}, +#endif +#ifdef vax + {"vax", "1", NULL}, +#endif +#ifdef VMS + {"VMS", "1", NULL}, +#endif +#ifdef cray + {"cray", "1", NULL}, +#endif +#ifdef CRAY + {"CRAY", "1", NULL}, +#endif +#ifdef _CRAY + {"_CRAY", "1", NULL}, +#endif +#ifdef att + {"att", "1", NULL}, +#endif +#ifdef mips + {"mips", "1", NULL}, +#endif +#ifdef __mips__ + {"__mips__", "1", NULL}, +#endif +#ifdef ultrix + {"ultrix", "1", NULL}, +#endif +#ifdef stellar + {"stellar", "1", NULL}, +#endif +#ifdef mc68000 + {"mc68000", "1", NULL}, +#endif +#ifdef mc68020 + {"mc68020", "1", NULL}, +#endif +#ifdef __GNUC__ + {"__GNUC__", "1", NULL}, +#endif +#if __STDC__ + {"__STDC__", "1", NULL}, +#endif +#ifdef __HIGHC__ + {"__HIGHC__", "1", NULL}, +#endif +#ifdef CMU + {"CMU", "1", NULL}, +#endif +#ifdef luna + {"luna", "1", NULL}, +#ifdef luna1 + {"luna1", "1", NULL}, +#endif +#ifdef luna2 + {"luna2", "1", NULL}, +#endif +#ifdef luna88k + {"luna88k", "1", NULL}, +#endif +#ifdef uniosb + {"uniosb", "1", NULL}, +#endif +#ifdef uniosu + {"uniosu", "1", NULL}, +#endif +#endif +#ifdef ieeep754 + {"ieeep754", "1", NULL}, +#endif +#ifdef is68k + {"is68k", "1", NULL}, +#endif +#ifdef m68k + {"m68k", "1", NULL}, +#endif +#ifdef m88k + {"m88k", "1", NULL}, +#endif +#ifdef __m88k__ + {"__m88k__", "1", NULL}, +#endif +#ifdef bsd43 + {"bsd43", "1", NULL}, +#endif +#ifdef hcx + {"hcx", "1", NULL}, +#endif +#ifdef sony + {"sony", "1", NULL}, +#ifdef SYSTYPE_SYSV + {"SYSTYPE_SYSV", "1", NULL}, +#endif +#ifdef _SYSTYPE_SYSV + {"_SYSTYPE_SYSV", "1", NULL}, +#endif +#endif +#ifdef __OSF__ + {"__OSF__", "1", NULL}, +#endif +#ifdef __osf__ + {"__osf__", "1", NULL}, +#endif +#ifdef __alpha + {"__alpha", "1", NULL}, +#endif +#ifdef __DECC + {"__DECC", "1", NULL}, +#endif +#ifdef __decc + {"__decc", "1", NULL}, +#endif +#ifdef __uxp__ + {"__uxp__", "1", NULL}, +#endif +#ifdef __sxg__ + {"__sxg__", "1", NULL}, +#endif +#ifdef _SEQUENT_ + {"_SEQUENT_", "1", NULL}, + {"__STDC__", "1", NULL}, +#endif +#ifdef __bsdi__ + {"__bsdi__", "1", NULL}, +#endif +#ifdef nec_ews_svr2 + {"nec_ews_svr2", "1", NULL}, +#endif +#ifdef nec_ews_svr4 + {"nec_ews_svr4", "1", NULL}, +#endif +#ifdef _nec_ews_svr4 + {"_nec_ews_svr4", "1", NULL}, +#endif +#ifdef _nec_up + {"_nec_up", "1", NULL}, +#endif +#ifdef SX + {"SX", "1", NULL}, +#endif +#ifdef nec + {"nec", "1", NULL}, +#endif +#ifdef _nec_ft + {"_nec_ft", "1", NULL}, +#endif +#ifdef PC_UX + {"PC_UX", "1", NULL}, +#endif +#ifdef sgi + {"sgi", "1", NULL}, +#endif +#ifdef __sgi + {"__sgi", "1", NULL}, +#endif +#ifdef __FreeBSD__ + {"__FreeBSD__", "1", NULL}, +#endif +#ifdef __NetBSD__ + {"__NetBSD__", "1", NULL}, +#endif +#ifdef __OpenBSD__ + {"__OpenBSD__", "1", NULL}, +#endif +#ifdef __EMX__ + {"__EMX__", "1", NULL}, +#endif + /* add any additional symbols before this line */ + {NULL, NULL, NULL} +}; + +#endif /* MAKEDEPEND */ +#endif /* CCIMAKE */ diff --git a/soltools/mkdepend/include.c b/soltools/mkdepend/include.c new file mode 100644 index 000000000000..4446489ba259 --- /dev/null +++ b/soltools/mkdepend/include.c @@ -0,0 +1,329 @@ +/* $XConsortium: include.c,v 1.17 94/12/05 19:33:08 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + + +#include "def.h" +#include <string.h> + +void remove_dotdot( char * ); +int isdot( char * ); +int isdotdot( char * ); +int issymbolic(char * dir, char * component); +int exists_path(struct IncludesCollection*, char*); + + +extern struct inclist inclist[ MAXFILES ], + *inclistp; +extern char *includedirs[ ]; +extern char *notdotdot[ ]; +extern boolean show_where_not; +extern boolean warn_multiple; + +struct inclist *inc_path(file, include, dot, incCollection) + register char *file, + *include; + boolean dot; + struct IncludesCollection* incCollection; +{ + static char path[ BUFSIZ ]; + register char **pp, *p; + register struct inclist *ip; + struct stat st; + boolean found = FALSE; + + /* + * Check all previously found include files for a path that + * has already been expanded. + */ + for (ip = inclist; ip->i_file; ip++) + if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym) + { + found = TRUE; + break; + } + + /* + * If the path was surrounded by "" or is an absolute path, + * then check the exact path provided. + */ +// FIXME: creates duplicates in the dependency files if absolute paths are +// given, which certainly is not the intended behavior. Also it slows down +// makedepend performance considerably. +// if (!found && (dot || *include == '/')) { +// +// if ((exists_path(incCollection, include)) && stat(include, &st) == 0 && !( st.st_mode & S_IFDIR)) { +// ip = newinclude(include, include); +// found = TRUE; +// } +// else if (show_where_not) +// warning1("\tnot in %s\n", include); +// } + + /* + * See if this include file is in the directory of the + * file being compiled. + */ + if (!found) { + for (p=file+strlen(file); p>file; p--) + if (*p == '/') + break; + if (p == file) + strcpy(path, include); + else { + strncpy(path, file, (p-file) + 1); + path[ (p-file) + 1 ] = '\0'; + strcpy(path + (p-file) + 1, include); + } + remove_dotdot(path); + if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !( st.st_mode & S_IFDIR)) { + ip = newinclude(path, include); + found = TRUE; + } + else if (show_where_not) + warning1("\tnot in %s\n", path); + } + + /* + * Check the include directories specified. (standard include dir + * should be at the end.) + */ + if (!found) + for (pp = includedirs; *pp; pp++) { + sprintf(path, "%s/%s", *pp, include); + remove_dotdot(path); + if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !(st.st_mode & S_IFDIR)) { + ip = newinclude(path, include); + found = TRUE; + break; + } + else if (show_where_not) + warning1("\tnot in %s\n", path); + } + + if (!found) + ip = NULL; + return(ip); +} + +int exists_path(incCollection, path) + struct IncludesCollection* incCollection; + char* path; +{ + convert_slashes(path); + return call_IncludesCollection_exists(incCollection, path); +} + +/* + * Occasionally, pathnames are created that look like .../x/../y + * Any of the 'x/..' sequences within the name can be eliminated. + * (but only if 'x' is not a symbolic link!!) + */ +void remove_dotdot(path) + char *path; +{ + register char *end, *from, *to, **cp; + char *components[ MAXFILES ], + newpath[ BUFSIZ ]; + boolean component_copied; + + /* + * slice path up into components. + */ + to = newpath; + if (*path == '/') + *to++ = '/'; + *to = '\0'; + cp = components; + for (from=end=path; *end; end++) + if (*end == '/') { + while (*end == '/') + *end++ = '\0'; + if (*from) + *cp++ = from; + from = end; + } + *cp++ = from; + *cp = NULL; + + /* + * Recursively remove all 'x/..' component pairs. + */ + cp = components; + while(*cp) { + if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1)) + && !issymbolic(newpath, *cp)) + { + char **fp = cp + 2; + char **tp = cp; + + do + *tp++ = *fp; /* move all the pointers down */ + while (*fp++); + if (cp != components) + cp--; /* go back and check for nested ".." */ + } else { + cp++; + } + } + /* + * Concatenate the remaining path elements. + */ + cp = components; + component_copied = FALSE; + while(*cp) { + if (component_copied) + *to++ = '/'; + component_copied = TRUE; + for (from = *cp; *from; ) + *to++ = *from++; + *to = '\0'; + cp++; + } + *to++ = '\0'; + + /* + * copy the reconstituted path back to our pointer. + */ + strcpy(path, newpath); +} + +int isdot(p) + register char *p; +{ + if(p && *p++ == '.' && *p++ == '\0') + return(TRUE); + return(FALSE); +} + +int isdotdot(p) + register char *p; +{ + if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0') + return(TRUE); + return(FALSE); +} + +int issymbolic(dir, component) + register char *dir, *component; +{ +#ifdef S_IFLNK + struct stat st; + char buf[ BUFSIZ ], **pp; + + sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component); + for (pp=notdotdot; *pp; pp++) + if (strcmp(*pp, buf) == 0) + return (TRUE); + if (lstat(buf, &st) == 0 + && (st.st_mode & S_IFMT) == S_IFLNK) { + *pp++ = copy(buf); + if (pp >= ¬dotdot[ MAXDIRS ]) + fatalerr("out of .. dirs, increase MAXDIRS\n"); + return(TRUE); + } +#endif + return(FALSE); +} + +/* + * Add an include file to the list of those included by 'file'. + */ +struct inclist *newinclude(newfile, incstring) + register char *newfile, *incstring; +{ + register struct inclist *ip; + + /* + * First, put this file on the global list of include files. + */ + ip = inclistp++; + if (inclistp == inclist + MAXFILES - 1) + fatalerr("out of space: increase MAXFILES\n"); + ip->i_file = copy(newfile); + ip->i_included_sym = FALSE; + if (incstring == NULL) + ip->i_incstring = ip->i_file; + else + ip->i_incstring = copy(incstring); + + return(ip); +} + +void included_by(ip, newfile) + register struct inclist *ip, *newfile; +{ + register int i; + + if (ip == NULL) + return; + /* + * Put this include file (newfile) on the list of files included + * by 'file'. If 'file' is NULL, then it is not an include + * file itself (i.e. was probably mentioned on the command line). + * If it is already on the list, don't stick it on again. + */ + if (ip->i_list == NULL) + ip->i_list = (struct inclist **) + malloc(sizeof(struct inclist *) * ++ip->i_listlen); + else { + for (i=0; i<ip->i_listlen; i++) + if (ip->i_list[ i ] == newfile) { + i = strlen(newfile->i_file); + if (!ip->i_included_sym && + !(i > 2 && + newfile->i_file[i-1] == 'c' && + newfile->i_file[i-2] == '.')) + { + /* only complain if ip has */ + /* no #include SYMBOL lines */ + /* and is not a .c file */ + if (warn_multiple) + { + warning("%s includes %s more than once!\n", + ip->i_file, newfile->i_file); + warning1("Already have\n"); + for (i=0; i<ip->i_listlen; i++) + warning1("\t%s\n", ip->i_list[i]->i_file); + } + } + return; + } + ip->i_list = (struct inclist **) realloc(ip->i_list, + sizeof(struct inclist *) * ++ip->i_listlen); + } + ip->i_list[ ip->i_listlen-1 ] = newfile; +} + +void inc_clean () +{ + register struct inclist *ip; + + for (ip = inclist; ip < inclistp; ip++) { + ip->i_marked = FALSE; + } +} diff --git a/soltools/mkdepend/main.c b/soltools/mkdepend/main.c new file mode 100644 index 000000000000..cf5c42c14bdf --- /dev/null +++ b/soltools/mkdepend/main.c @@ -0,0 +1,799 @@ +/* $XConsortium: main.c,v 1.84 94/11/30 16:10:44 kaleb Exp $ */ +/* $XFree86: xc/config/makedepend/main.c,v 3.4 1995/07/15 14:53:49 dawes Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#if defined(FREEBSD) || defined(MACOSX) +#include <sys/types.h> +#include <sys/stat.h> +#endif + +#ifdef _MSC_VER /* Define ssize_t */ + +#if !defined(_W64) +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +#define _W64 __w64 +#else +#define _W64 +#endif +#endif + +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif + +#endif + +#include "def.h" +#include <string.h> +#ifdef hpux +#define sigvec sigvector +#endif /* hpux */ + +#ifdef X_POSIX_C_SOURCE +#define _POSIX_C_SOURCE X_POSIX_C_SOURCE +#include <signal.h> +#undef _POSIX_C_SOURCE +#else +#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) +#include <signal.h> +#else +#define _POSIX_SOURCE +#include <signal.h> +#undef _POSIX_SOURCE +#endif +#endif + +#include <stdarg.h> + +#ifdef MINIX +#define USE_CHMOD 1 +#endif + +#ifdef DEBUG +int _debugmask; +#endif + +char *ProgramName; + +#define OBJSUFFIX ".obj" +#define INCLUDEDIR "." + +char *directives[] = { + "if", + "ifdef", + "ifndef", + "else", + "endif", + "define", + "undef", + "include", + "line", + "pragma", + "error", + "ident", + "sccs", + "elif", + "eject", + NULL +}; + +#define MAKEDEPEND +#include "imakemdep.h" /* from config sources */ +#undef MAKEDEPEND + +/******* function declarations ********/ +/******* added by -Wall project *******/ +void redirect(char * line, char * makefile ); + +struct inclist inclist[ MAXFILES ], + *inclistp = inclist; + +struct symhash *maininclist = NULL; + +char *filelist[ MAXFILES ]; +char *includedirs[ MAXDIRS + 1 ]; +char *notdotdot[ MAXDIRS ]; +char *objprefix = ""; +char *objsuffix = OBJSUFFIX; +char *startat = "# DO NOT DELETE"; +int width = 78; +boolean append = FALSE; +boolean printed = FALSE; +boolean verbose = FALSE; +boolean show_where_not = FALSE; +boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */ + +static +#ifdef SIGNALRETURNSINT +int +#else +void +#endif +catch (sig) + int sig; +{ + fflush (stdout); + fatalerr ("got signal %d\n", sig); +} + +#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(OS2) || defined(Lynx_22) +#define USGISH +#endif + +#ifndef USGISH +#ifndef _POSIX_SOURCE +#define sigaction sigvec +#define sa_handler sv_handler +#define sa_mask sv_mask +#define sa_flags sv_flags +#endif +struct sigaction sig_act; +#endif /* USGISH */ + +boolean native_win_slashes = FALSE; + +int main(argc, argv) + int argc; + char **argv; +{ + register char **fp = filelist; + register char **incp = includedirs; + register char *p; + register struct inclist *ip; + char *makefile = NULL; + struct filepointer *filecontent; + struct pair *psymp = predefs; + char *endmarker = NULL; + char *defincdir = NULL; + struct IncludesCollection* incCollection; + + ProgramName = argv[0]; + + while (psymp->p_name) + { + hash_define(psymp->p_name, psymp->p_value, &maininclist); + psymp++; + } + if (argc == 2 && argv[1][0] == '@') { + struct stat ast; + int afd; + char *args; + char **nargv; + int nargc; + char quotechar = '\0'; + + nargc = 1; + if ((afd = open(argv[1]+1, O_RDONLY)) < 0) + fatalerr("cannot open \"%s\"\n", argv[1]+1); + fstat(afd, &ast); + args = (char *)malloc(ast.st_size + 1); + if ((ast.st_size = read(afd, args, (size_t) ast.st_size)) < 0) + fatalerr("failed to read %s\n", argv[1]+1); + args[ast.st_size] = '\0'; + close(afd); + for (p = args; *p; p++) { + if (quotechar) { + if (quotechar == '\\' || + (*p == quotechar && p[-1] != '\\')) + quotechar = '\0'; + continue; + } + switch (*p) { + case '\\': + case '"': + case '\'': + quotechar = *p; + break; + case ' ': + case '\n': + *p = '\0'; + if (p > args && p[-1]) + nargc++; + break; + } + } + if (p[-1]) + nargc++; + nargv = (char **)malloc(nargc * sizeof(char *)); + nargv[0] = argv[0]; + argc = 1; + for (p = args; argc < nargc; p += strlen(p) + 1) + if (*p) nargv[argc++] = p; + argv = nargv; + } + for(argc--, argv++; argc; argc--, argv++) { + /* if looking for endmarker then check before parsing */ + if (endmarker && strcmp (endmarker, *argv) == 0) { + endmarker = NULL; + continue; + } + if (**argv != '-') { + /* treat +thing as an option for C++ */ + if (endmarker && **argv == '+') + continue; + *fp++ = argv[0]; + continue; + } + switch(argv[0][1]) { + case '-': + endmarker = &argv[0][2]; + if (endmarker[0] == '\0') endmarker = "--"; + break; + case 'D': + if (argv[0][2] == '\0') { + argv++; + argc--; + } + for (p=argv[0] + 2; *p ; p++) + if (*p == '=') { + *p = ' '; + break; + } + define(argv[0] + 2, &maininclist); + break; + case 'I': + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = argv[0]+2; + if (**(incp-1) == '\0') { + *(incp-1) = *(++argv); + argc--; + } + break; + case 'Y': + defincdir = argv[0]+2; + break; + /* do not use if endmarker processing */ + case 'a': + if (endmarker) break; + append = TRUE; + break; + case 'w': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + width = atoi(argv[0]); + } else + width = atoi(argv[0]+2); + break; + case 'n': + // Use "-n" switch to generate dependencies with windows-native slash style + native_win_slashes = TRUE; + break; + case 'o': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + objsuffix = argv[0]; + } else + objsuffix = argv[0]+2; + break; + case 'p': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + objprefix = argv[0]; + } else + objprefix = argv[0]+2; + break; + case 'v': + if (endmarker) break; + verbose = TRUE; +#ifdef DEBUG + if (argv[0][2]) + _debugmask = atoi(argv[0]+2); +#endif + break; + case 's': + if (endmarker) break; + startat = argv[0]+2; + if (*startat == '\0') { + startat = *(++argv); + argc--; + } + if (*startat != '#') + fatalerr("-s flag's value should start %s\n", + "with '#'."); + break; + case 'f': + if (endmarker) break; + makefile = argv[0]+2; + if (*makefile == '\0') { + makefile = *(++argv); + argc--; + } + break; + + case 'm': + warn_multiple = TRUE; + break; + + /* Ignore -O, -g so we can just pass ${CFLAGS} to + makedepend + */ + case 'O': + case 'g': + break; + default: + if (endmarker) break; + /* fatalerr("unknown opt = %s\n", argv[0]); */ + warning("ignoring option %s\n", argv[0]); + } + } + + convert_slashes(objprefix); + objprefix = append_slash(objprefix); + + if (!defincdir) { +#ifdef PREINCDIR + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = PREINCDIR; +#endif + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = INCLUDEDIR; +#ifdef POSTINCDIR + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = POSTINCDIR; +#endif + } else if (*defincdir) { + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = defincdir; + } + + redirect(startat, makefile); + + /* + * catch signals. + */ +#ifdef USGISH +/* should really reset SIGINT to SIG_IGN if it was. */ +#ifdef SIGHUP + signal (SIGHUP, catch); +#endif + signal (SIGINT, catch); +#ifdef SIGQUIT + signal (SIGQUIT, catch); +#endif + signal (SIGILL, catch); +#ifdef SIGBUS + signal (SIGBUS, catch); +#endif + signal (SIGSEGV, catch); +#ifdef SIGSYS + signal (SIGSYS, catch); +#endif + signal (SIGFPE, catch); +#else + sig_act.sa_handler = catch; +#ifdef _POSIX_SOURCE + sigemptyset(&sig_act.sa_mask); + sigaddset(&sig_act.sa_mask, SIGINT); + sigaddset(&sig_act.sa_mask, SIGQUIT); +#ifdef SIGBUS + sigaddset(&sig_act.sa_mask, SIGBUS); +#endif + sigaddset(&sig_act.sa_mask, SIGILL); + sigaddset(&sig_act.sa_mask, SIGSEGV); + sigaddset(&sig_act.sa_mask, SIGHUP); + sigaddset(&sig_act.sa_mask, SIGPIPE); +#ifdef SIGSYS + sigaddset(&sig_act.sa_mask, SIGSYS); +#endif +#else + sig_act.sa_mask = ((1<<(SIGINT -1)) + |(1<<(SIGQUIT-1)) +#ifdef SIGBUS + |(1<<(SIGBUS-1)) +#endif + |(1<<(SIGILL-1)) + |(1<<(SIGSEGV-1)) + |(1<<(SIGHUP-1)) + |(1<<(SIGPIPE-1)) +#ifdef SIGSYS + |(1<<(SIGSYS-1)) +#endif + ); +#endif /* _POSIX_SOURCE */ + sig_act.sa_flags = 0; + sigaction(SIGHUP, &sig_act, (struct sigaction *)0); + sigaction(SIGINT, &sig_act, (struct sigaction *)0); + sigaction(SIGQUIT, &sig_act, (struct sigaction *)0); + sigaction(SIGILL, &sig_act, (struct sigaction *)0); +#ifdef SIGBUS + sigaction(SIGBUS, &sig_act, (struct sigaction *)0); +#endif + sigaction(SIGSEGV, &sig_act, (struct sigaction *)0); +#ifdef SIGSYS + sigaction(SIGSYS, &sig_act, (struct sigaction *)0); +#endif +#endif /* USGISH */ + + /* + * now peruse through the list of files. + */ + incCollection = create_IncludesCollection(); + + for(fp=filelist; *fp; fp++) { + struct symhash *includes; + filecontent = getfile(*fp); + ip = newinclude(*fp, (char *)NULL); + + includes = hash_copy( maininclist ); + find_includes(filecontent, ip, ip, 0, FALSE, incCollection, includes); + hash_free( includes ); + + freefile(filecontent); + recursive_pr_include(ip, ip->i_file, base_name(*fp)); + inc_clean(); + } + if (printed) + printf("\n"); + + delete_IncludesCollection(incCollection); + + exit(0); +} + +struct filepointer *getfile(file) + char *file; +{ + register int fd; + struct filepointer *content; + struct stat st; + off_t size_backup; + ssize_t bytes_read; + size_t malloc_size; + + content = (struct filepointer *)malloc(sizeof(struct filepointer)); + if ((fd = open(file, O_RDONLY)) < 0) { + warning("makedepend: Cannot open file \"%s\"\n", file); + content->f_p = content->f_base = content->f_end = (char *)malloc(1); + *content->f_p = '\0'; + return(content); + } + fstat(fd, &st); + + size_backup = st.st_size; + malloc_size = size_backup; + /* Since off_t is larger than size_t, need to test for + * truncation. + */ + if ( (off_t)malloc_size != size_backup ) + { + close( fd ); + warning("makedepend: File \"%s\" size larger than can fit in size_t. Cannot allocate memory for contents.\n", file); + content->f_p = content->f_base = content->f_end = (char *)malloc(1); + *content->f_p = '\0'; + return(content); + } + + content->f_base = (char *)malloc(malloc_size+1); + if (content->f_base == NULL) + fatalerr("makedepend: Cannot allocate memory to process file \"%s\"\n", file); + if ((bytes_read = read(fd, content->f_base, malloc_size)) < 0) + if ( st.st_mode & S_IFREG ) + fatalerr("makedepend: Failed to read file \"%s\"\n", file); + + close(fd); + content->f_len = bytes_read+1; + content->f_p = content->f_base; + content->f_end = content->f_base + bytes_read; + *content->f_end = '\0'; + content->f_line = 0; + return(content); +} + +void freefile(fp) + struct filepointer *fp; +{ + free(fp->f_base); + free(fp); +} + +char *copy(str) + register char *str; +{ + register char *p = (char *)malloc(strlen(str) + 1); + + strcpy(p, str); + return(p); +} + +int match(str, list) + register char *str, **list; +{ + register int i; + + for (i=0; *list; i++, list++) + if (strcmp(str, *list) == 0) + return(i); + return(-1); +} + +/* + * Get the next line. We only return lines beginning with '#' since that + * is all this program is ever interested in. + */ +char *get_line(filep) + register struct filepointer *filep; +{ + register char *p, /* walking pointer */ + *eof, /* end of file pointer */ + *bol; /* beginning of line pointer */ + register int lineno; /* line number */ + + p = filep->f_p; + eof = filep->f_end; + if (p >= eof) + return((char *)NULL); + lineno = filep->f_line; + + for(bol = p--; ++p < eof; ) { + if (*p == '/' && *(p+1) == '*') { /* consume comments */ + *p++ = ' ', *p++ = ' '; + while (*p) { + if (*p == '*' && *(p+1) == '/') { + *p++ = ' ', *p = ' '; + break; + } + else if (*p == '\n') + lineno++; + *p++ = ' '; + } + continue; + } + else if (*p == '/' && *(p+1) == '/') { /* consume comments */ + *p++ = ' ', *p++ = ' '; + while (*p && *p != '\n') + *p++ = ' '; + if ( *p == '\n' ) + p--; + lineno++; + continue; + } + else if (*p == '\\') { + if (*(p+1) == '\n') { + *p = ' '; + *(p+1) = ' '; + lineno++; + } + } + else if (*p == '\n') { + lineno++; + if (*bol == '#') { + register char *cp; + + *p++ = '\0'; + /* punt lines with just # (yacc generated) */ + for (cp = bol+1; + *cp && (*cp == ' ' || *cp == '\t'); cp++); + if (*cp) goto done; + } + bol = p+1; + } + } + if (*bol != '#') + bol = NULL; +done: + filep->f_p = p; + filep->f_line = lineno; + return(bol); +} + +/* + * Strip the file name down to what we want to see in the Makefile. + * It will have objprefix and objsuffix around it. + */ +char *base_name(file) + register char *file; +{ + register char *p; + + file = copy(file); + for(p=file+strlen(file); p>file && *p != '.'; p--) ; + + if (*p == '.') + *p = '\0'; + + while (p > file) { + if ( *p == '/' || *p == '\\') { + file = p + 1; + break; + }; + p--; + }; + return(file); +} + +#if defined(USG) && !defined(CRAY) && !defined(SVR4) +int rename (from, to) + char *from, *to; +{ + (void) unlink (to); + if (link (from, to) == 0) { + unlink (from); + return 0; + } else { + return -1; + } +} +#endif /* USGISH */ + +void redirect(line, makefile) + char *line, + *makefile; +{ + struct stat st; + FILE *fdin, *fdout; + char backup[ BUFSIZ ], + buf[ BUFSIZ ]; + boolean found = FALSE; + int len; + + /* + * if makefile is "-" then let it pour onto stdout. + */ + if (makefile && *makefile == '-' && *(makefile+1) == '\0') + return; + + /* + * use a default makefile is not specified. + */ + if (!makefile) { + if (stat("Makefile", &st) == 0) + makefile = "Makefile"; + else if (stat("makefile", &st) == 0) + makefile = "makefile"; + else + fatalerr("[mM]akefile is not present\n"); + } + else + stat(makefile, &st); + if ((fdin = fopen(makefile, "r")) == NULL) + fatalerr("cannot open \"%s\"\n", makefile); + sprintf(backup, "%s.bak", makefile); + unlink(backup); +#if defined(WIN32) || defined(OS2) + fclose(fdin); +#endif + if (rename(makefile, backup) < 0) + fatalerr("cannot rename %s to %s\n", makefile, backup); +#if defined(WIN32) || defined(OS2) + if ((fdin = fopen(backup, "r")) == NULL) + fatalerr("cannot open \"%s\"\n", backup); +#endif + if ((fdout = freopen(makefile, "w", stdout)) == NULL) + fatalerr("cannot open \"%s\"\n", backup); + len = strlen(line); + while (!found && fgets(buf, BUFSIZ, fdin)) { + if (*buf == '#' && strncmp(line, buf, len) == 0) + found = TRUE; + fputs(buf, fdout); + } + if (!found) { + if (verbose) + warning("Adding new delimiting line \"%s\" and dependencies...\n", + line); + puts(line); /* same as fputs(fdout); but with newline */ + } else if (append) { + while (fgets(buf, BUFSIZ, fdin)) { + fputs(buf, fdout); + } + } + fflush(fdout); +#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD) + chmod(makefile, st.st_mode); +#else + fchmod(fileno(fdout), st.st_mode); +#endif /* USGISH */ + fclose(fdin); +} + +void fatalerr(char *msg, ...) +{ + va_list args; + fprintf(stderr, "%s: error: ", ProgramName); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + exit (1); +} + +void warning(char *msg, ...) +{ +#ifdef DEBUG_MKDEPEND + va_list args; + fprintf(stderr, "%s: warning: ", ProgramName); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +#else + (void)msg; +#endif /* DEBUG_MKDEPEND */ +} + +void warning1(char *msg, ...) +{ +#ifdef DEBUG_MKDEPEND + va_list args; + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +#else + (void)msg; +#endif /* DEBUG_MKDEPEND */ +} + +void convert_slashes(path) + char* path; +{ +#if defined (WNT) || defined(OS2) + /* + * Convert backslashes to slashes + */ + char *ptr; + if (native_win_slashes) { + for (ptr = (char*)path; *ptr; ++ptr) + if (*ptr == '/') + *ptr = '\\'; + } else { + for (ptr = (char*)path; *ptr; ++ptr) + if (*ptr == '\\') + *ptr = '/'; + }; +#else + (void)path; +#endif +} + +char* append_slash(path) + char* path; +{ + char *new_string; + if ((path[strlen(path) - 1] == '/') || (path[strlen(path) - 1] == '\\')) { + new_string = path; + } else { + new_string = (char*)malloc(sizeof(char) * (strlen(path) + 2)); + strcpy(new_string, path); + if (native_win_slashes) + strcat(new_string, "\\"); + else + strcat(new_string, "/"); + }; + return new_string; +} + diff --git a/soltools/mkdepend/makefile.mk b/soltools/mkdepend/makefile.mk new file mode 100644 index 000000000000..630c688faba2 --- /dev/null +++ b/soltools/mkdepend/makefile.mk @@ -0,0 +1,82 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJNAME=soltools +TARGET=make_makedepend +PRJ=.. +TARGETTYPE=CUI +LIBTARGET=NO +# noadjust here to have dependencies over there +noadjust=TRUE +nodep=true +ENABLE_EXCEPTIONS=TRUE + +# "mkdepend" is written in K&R style C. Modern compilers will generate +# lots of warning. There is no point in cleaning this up, so we just +# ignore warnings +EXTERNAL_WARNINGS_NOT_ERRORS=TRUE + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +LIBSALCPPRT= +UWINAPILIB= + +CDEFS+=-DNO_X11 -DXP_PC -DHW_THREADS + +OBJFILES= \ + $(OBJ)$/cppsetup.obj \ + $(OBJ)$/ifparser.obj \ + $(OBJ)$/include.obj \ + $(OBJ)$/main.obj \ + $(OBJ)$/parse.obj \ + $(OBJ)$/pr.obj \ + $(OBJ)$/collectdircontent.obj \ + $(NULL) + +APP1TARGET=makedepend +APP1OBJS=$(OBJFILES) +APP1RPATH=NONE + +.IF "$(COM)"=="MSC" +.IF "$(dbgutil)"=="" +APP1STDLIBS+=msvcprt.lib +.ELSE +APP1STDLIBS+=msvcprtd.lib +CDEFS+=-D_DEBUG +.ENDIF # "$(DBG_UTIL)"=="" +.ENDIF # "$(COM)"=="MSC" + +.IF "$(OS)"=="SOLARIS" +#APP1STDLIBS+=-lstlport +APP1STDLIBS+=-lCstd +.ENDIF + + +.INCLUDE : target.mk + + diff --git a/soltools/mkdepend/mkdepend.man b/soltools/mkdepend/mkdepend.man new file mode 100644 index 000000000000..9c3cdccd988c --- /dev/null +++ b/soltools/mkdepend/mkdepend.man @@ -0,0 +1,368 @@ +.\" $XConsortium: mkdepend.man,v 1.15 94/04/17 20:10:37 gildea Exp $ +.\" Copyright (c) 1993, 1994 X Consortium +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the "Software"), +.\" to deal in the Software without restriction, including without limitation +.\" the rights to use, copy, modify, merge, publish, distribute, sublicense, +.\" and/or sell copies of the Software, and to permit persons to whom the +.\" Software furnished to do so, subject to the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be included in +.\" all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +.\" THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +.\" SOFTWARE. +.\" +.\" Except as contained in this notice, the name of the X Consortium shall not +.\" be used in advertising or otherwise to promote the sale, use or other +.\" dealing in this Software without prior written authorization from the +.\" X Consortium. +.TH MAKEDEPEND 1 "Release 6" "X Version 11" +.UC 4 +.SH NAME +makedepend \- create dependencies in makefiles +.SH SYNOPSIS +.B makedepend +[ +.B \-Dname=def +] [ +.B \-Dname +] [ +.B \-Iincludedir +] [ +.B \-Yincludedir +] [ +.B \-a +] [ +.B \-fmakefile +] [ +.B \-oobjsuffix +] [ +.B \-pobjprefix +] [ +.B \-sstring +] [ +.B \-wwidth +] [ +.B \-v +] [ +.B \-m +] [ +\-\^\- +.B otheroptions +\-\^\- +] +sourcefile .\|.\|. +.br +.SH DESCRIPTION +.B Makedepend +reads each +.I sourcefile +in sequence and parses it like a C-preprocessor, +processing all +.I #include, +.I #define, +.I #undef, +.I #ifdef, +.I #ifndef, +.I #endif, +.I #if +and +.I #else +directives so that it can correctly tell which +.I #include, +directives would be used in a compilation. +Any +.I #include, +directives can reference files having other +.I #include +directives, and parsing will occur in these files as well. +.PP +Every file that a +.I sourcefile +includes, +directly or indirectly, +is what +.B makedepend +calls a "dependency". +These dependencies are then written to a +.I makefile +in such a way that +.B make(1) +will know which object files must be recompiled when a dependency has changed. +.PP +By default, +.B makedepend +places its output in the file named +.I makefile +if it exists, otherwise +.I Makefile. +An alternate makefile may be specified with the +.B \-f +option. +It first searches the makefile for +the line +.sp + # DO NOT DELETE THIS LINE \-\^\- make depend depends on it. +.sp +or one provided with the +.B \-s +option, +as a delimiter for the dependency output. +If it finds it, it will delete everything +following this to the end of the makefile +and put the output after this line. +If it doesn't find it, the program +will append the string to the end of the makefile +and place the output following that. +For each +.I sourcefile +appearing on the command line, +.B makedepend +puts lines in the makefile of the form +.sp + sourcefile.o:\0dfile .\|.\|. +.sp +Where "sourcefile.o" is the name from the command +line with its suffix replaced with ".o", +and "dfile" is a dependency discovered in a +.I #include +directive while parsing +.I sourcefile +or one of the files it included. +.SH EXAMPLE +Normally, +.B makedepend +will be used in a makefile target so that typing "make depend" will +bring the dependencies up to date for the makefile. +For example, +.nf + SRCS\0=\0file1.c\0file2.c\0.\|.\|. + CFLAGS\0=\0\-O\0\-DHACK\0\-I\^.\^.\^/foobar\0\-xyz + depend: + makedepend\0\-\^\-\0$(CFLAGS)\0\-\^\-\0$(SRCS) +.fi +.SH OPTIONS +.B Makedepend +will ignore any option that it does not understand so that you may use +the same arguments that you would for +.B cc(1). +.TP 5 +.B \-Dname=def or \-Dname +Define. +This places a definition for +.I name +in +.B makedepend's +symbol table. +Without +.I =def +the symbol becomes defined as "1". +.TP 5 +.B \-Iincludedir +Include directory. +This option tells +.B makedepend +to prepend +.I includedir +to its list of directories to search when it encounters +a +.I #include +directive. +By default, +.B makedepend +only searches the standard include directories (usually /usr/include +and possibly a compiler-dependent directory). +.TP 5 +.B \-Yincludedir +Replace all of the standard include directories with the single specified +include directory; you can omit the +.I includedir +to simply prevent searching the standard include directories. +.TP 5 +.B \-a +Append the dependencies to the end of the file instead of replacing them. +.TP 5 +.B \-fmakefile +Filename. +This allows you to specify an alternate makefile in which +.B makedepend +can place its output. +.TP 5 +.B \-oobjsuffix +Object file suffix. +Some systems may have object files whose suffix is something other +than ".o". +This option allows you to specify another suffix, such as +".b" with +.I -o.b +or ":obj" +with +.I -o:obj +and so forth. +.TP 5 +.B \-pobjprefix +Object file prefix. +The prefix is prepended to the name of the object file. This is +usually used to designate a different directory for the object file. +The default is the empty string. +.TP 5 +.B \-sstring +Starting string delimiter. +This option permits you to specify +a different string for +.B makedepend +to look for in the makefile. +.TP 5 +.B \-wwidth +Line width. +Normally, +.B makedepend +will ensure that every output line that it writes will be no wider than +78 characters for the sake of readability. +This option enables you to change this width. +.TP 5 +.B \-v +Verbose operation. +This option causes +.B makedepend +to emit the list of files included by each input file on standard output. +.TP 5 +.B \-m +Warn about multiple inclusion. +This option causes +.B makedepend +to produce a warning if any input file includes another file more than +once. In previous versions of +.B makedepend +this was the default behavior; the default has been changed to better +match the behavior of the C compiler, which does not consider multiple +inclusion to be an error. This option is provided for backward +compatibility, and to aid in debugging problems related to multiple +inclusion. +.TP 5 +.B "\-\^\- options \-\^\-" +If +.B makedepend +encounters a double hyphen (\-\^\-) in the argument list, +then any unrecognized argument following it +will be silently ignored; a second double hyphen terminates this +special treatment. +In this way, +.B makedepend +can be made to safely ignore esoteric compiler arguments that might +normally be found in a CFLAGS +.B make +macro (see the +.B EXAMPLE +section above). +All options that +.B makedepend +recognizes and appear between the pair of double hyphens +are processed normally. +.SH ALGORITHM +The approach used in this program enables it to run an order of magnitude +faster than any other "dependency generator" I have ever seen. +Central to this performance are two assumptions: +that all files compiled by a single +makefile will be compiled with roughly the same +.I -I +and +.I -D +options; +and that most files in a single directory will include largely the +same files. +.PP +Given these assumptions, +.B makedepend +expects to be called once for each makefile, with +all source files that are maintained by the +makefile appearing on the command line. +It parses each source and include +file exactly once, maintaining an internal symbol table +for each. +Thus, the first file on the command line will take an amount of time +proportional to the amount of time that a normal C preprocessor takes. +But on subsequent files, if it encounter's an include file +that it has already parsed, it does not parse it again. +.PP +For example, +imagine you are compiling two files, +.I file1.c +and +.I file2.c, +they each include the header file +.I header.h, +and the file +.I header.h +in turn includes the files +.I def1.h +and +.I def2.h. +When you run the command +.sp + makedepend\0file1.c\0file2.c +.sp +.B makedepend +will parse +.I file1.c +and consequently, +.I header.h +and then +.I def1.h +and +.I def2.h. +It then decides that the dependencies for this file are +.sp + file1.o:\0header.h\0def1.h\0def2.h +.sp +But when the program parses +.I file2.c +and discovers that it, too, includes +.I header.h, +it does not parse the file, +but simply adds +.I header.h, +.I def1.h +and +.I def2.h +to the list of dependencies for +.I file2.o. +.SH "SEE ALSO" +cc(1), make(1) +.SH BUGS +.B makedepend +parses, but does not currently evaluate, the SVR4 +#predicate(token-list) preprocessor expression; +such expressions are simply assumed to be true. +This may cause the wrong +.I #include +directives to be evaluated. +.PP +Imagine you are parsing two files, +say +.I file1.c +and +.I file2.c, +each includes the file +.I def.h. +The list of files that +.I def.h +includes might truly be different when +.I def.h +is included by +.I file1.c +than when it is included by +.I file2.c. +But once +.B makedepend +arrives at a list of dependencies for a file, +it is cast in concrete. +.SH AUTHOR +Todd Brunhoff, Tektronix, Inc. and MIT Project Athena diff --git a/soltools/mkdepend/parse.c b/soltools/mkdepend/parse.c new file mode 100644 index 000000000000..31d48bf2bbc5 --- /dev/null +++ b/soltools/mkdepend/parse.c @@ -0,0 +1,614 @@ +/* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" +char *hash_lookup( char *symbol, struct symhash *symbols ); +void hash_undefine( char *symbol, struct symhash *symbols ); +int gobble( register struct filepointer *filep, struct inclist *file, + struct inclist *file_red, struct symhash *symbols ); +int deftype ( register char *line, register struct filepointer *filep, + register struct inclist *file_red, register struct inclist *file, + int parse_it, struct symhash *symbols); +int zero_value(register char *exp, register struct filepointer *filep, + register struct inclist *file_red, register struct symhash *symbols); + +extern char *directives[]; +extern struct symhash *maininclist; + +int find_includes(filep, file, file_red, recursion, failOK, incCollection, symbols) + struct filepointer *filep; + struct inclist *file, *file_red; + int recursion; + boolean failOK; + struct IncludesCollection* incCollection; + struct symhash *symbols; +{ + register char *line; + register int type; + boolean recfailOK; + + while ((line = get_line(filep))) { + switch(type = deftype(line, filep, file_red, file, TRUE, symbols)) { + case IF: + doif: + type = find_includes(filep, file, + file_red, recursion+1, failOK, incCollection, symbols); + while ((type == ELIF) || (type == ELIFFALSE) || + (type == ELIFGUESSFALSE)) + type = gobble(filep, file, file_red, symbols); + if (type == ELSE) + gobble(filep, file, file_red, symbols); + break; + case IFFALSE: + case IFGUESSFALSE: + doiffalse: + if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) + recfailOK = TRUE; + else + recfailOK = failOK; + type = gobble(filep, file, file_red, symbols); + if (type == ELSE) + find_includes(filep, file, + file_red, recursion+1, recfailOK, incCollection, symbols); + else + if (type == ELIF) + goto doif; + else + if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) + goto doiffalse; + break; + case IFDEF: + case IFNDEF: + if ((type == IFDEF && hash_lookup(line, symbols)) + || (type == IFNDEF && !hash_lookup(line, symbols))) { + debug(1,(type == IFNDEF ? + "line %d: %s !def'd in %s via %s%s\n" : "", + filep->f_line, line, + file->i_file, file_red->i_file, ": doit")); + type = find_includes(filep, file, + file_red, recursion+1, failOK, incCollection, symbols); + while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) + type = gobble(filep, file, file_red, symbols); + if (type == ELSE) + gobble(filep, file, file_red, symbols); + } + else { + debug(1,(type == IFDEF ? + "line %d: %s !def'd in %s via %s%s\n" : "", + filep->f_line, line, + file->i_file, file_red->i_file, ": gobble")); + type = gobble(filep, file, file_red, symbols); + if (type == ELSE) + find_includes(filep, file, + file_red, recursion + 1, failOK, incCollection, symbols); + else if (type == ELIF) + goto doif; + else if (type == ELIFFALSE || type == ELIFGUESSFALSE) + goto doiffalse; + } + break; + case ELSE: + case ELIFFALSE: + case ELIFGUESSFALSE: + case ELIF: + if (!recursion) + gobble(filep, file, file_red, symbols); + case ENDIF: + if (recursion) + return(type); + case DEFINE: + define(line, &symbols); + break; + case UNDEF: + if (!*line) { + warning("%s, line %d: incomplete undef == \"%s\"\n", + file_red->i_file, filep->f_line, line); + break; + } + hash_undefine(line, symbols); + break; + case INCLUDE: + add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols); + break; + case INCLUDEDOT: + add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols); + break; + case ERROR: + warning("%s: %d: %s\n", file_red->i_file, + filep->f_line, line); + break; + + case PRAGMA: + case IDENT: + case SCCS: + case EJECT: + break; + case -1: + warning("%s", file_red->i_file); + if (file_red != file) + warning1(" (reading %s)", file->i_file); + warning1(", line %d: unknown directive == \"%s\"\n", + filep->f_line, line); + break; + case -2: + warning("%s", file_red->i_file); + if (file_red != file) + warning1(" (reading %s)", file->i_file); + warning1(", line %d: incomplete include == \"%s\"\n", + filep->f_line, line); + break; + } + } + return(-1); +} + +int gobble(filep, file, file_red, symbols) + register struct filepointer *filep; + struct inclist *file, *file_red; + struct symhash *symbols; +{ + register char *line; + register int type; + + while ((line = get_line(filep))) { + switch(type = deftype(line, filep, file_red, file, FALSE, symbols)) { + case IF: + case IFFALSE: + case IFGUESSFALSE: + case IFDEF: + case IFNDEF: + type = gobble(filep, file, file_red, symbols); + while ((type == ELIF) || (type == ELIFFALSE) || + (type == ELIFGUESSFALSE)) + type = gobble(filep, file, file_red, symbols); + if (type == ELSE) + (void)gobble(filep, file, file_red, symbols); + break; + case ELSE: + case ENDIF: + debug(0,("%s, line %d: #%s\n", + file->i_file, filep->f_line, + directives[type])); + return(type); + case DEFINE: + case UNDEF: + case INCLUDE: + case INCLUDEDOT: + case PRAGMA: + case ERROR: + case IDENT: + case SCCS: + case EJECT: + break; + case ELIF: + case ELIFFALSE: + case ELIFGUESSFALSE: + return(type); + case -1: + warning("%s, line %d: unknown directive == \"%s\"\n", + file_red->i_file, filep->f_line, line); + break; + } + } + return(-1); +} + +/* + * Decide what type of # directive this line is. + */ +int deftype (line, filep, file_red, file, parse_it, symbols) + register char *line; + register struct filepointer *filep; + register struct inclist *file_red, *file; + int parse_it; + struct symhash *symbols; +{ + register char *p; + char *directive, savechar; + register int ret; + + /* + * Parse the directive... + */ + directive=line+1; + while (*directive == ' ' || *directive == '\t') + directive++; + + p = directive; + while (*p >= 'a' && *p <= 'z') + p++; + savechar = *p; + *p = '\0'; + ret = match(directive, directives); + *p = savechar; + + /* If we don't recognize this compiler directive or we happen to just + * be gobbling up text while waiting for an #endif or #elif or #else + * in the case of an #elif we must check the zero_value and return an + * ELIF or an ELIFFALSE. + */ + + if (ret == ELIF && !parse_it) + { + while (*p == ' ' || *p == '\t') + p++; + /* + * parse an expression. + */ + debug(0,("%s, line %d: #elif %s ", + file->i_file, filep->f_line, p)); + ret = zero_value(p, filep, file_red, symbols); + if (ret != IF) + { + debug(0,("false...\n")); + if (ret == IFFALSE) + return(ELIFFALSE); + else + return(ELIFGUESSFALSE); + } + else + { + debug(0,("true...\n")); + return(ELIF); + } + } + + if (ret < 0 || ! parse_it) + return(ret); + + /* + * now decide how to parse the directive, and do it. + */ + while (*p == ' ' || *p == '\t') + p++; + switch (ret) { + case IF: + /* + * parse an expression. + */ + ret = zero_value(p, filep, file_red, symbols); + debug(0,("%s, line %d: %s #if %s\n", + file->i_file, filep->f_line, ret?"false":"true", p)); + break; + case IFDEF: + case IFNDEF: + debug(0,("%s, line %d: #%s %s\n", + file->i_file, filep->f_line, directives[ret], p)); + case UNDEF: + /* + * separate the name of a single symbol. + */ + while (isalnum(*p) || *p == '_') + *line++ = *p++; + *line = '\0'; + break; + case INCLUDE: + debug(2,("%s, line %d: #include %s\n", + file->i_file, filep->f_line, p)); + + /* Support ANSI macro substitution */ + { + char *sym = hash_lookup(p, symbols); + while (sym) + { + p = sym; + debug(3,("%s : #includes SYMBOL %s\n", + file->i_incstring, + sym)); + /* mark file as having included a 'soft include' */ + file->i_included_sym = TRUE; + sym = hash_lookup(p, symbols); + } + } + + /* + * Separate the name of the include file. + */ + while (*p && *p != '"' && *p != '<') + p++; + if (! *p) + return(-2); + if (*p++ == '"') { + ret = INCLUDEDOT; + while (*p && *p != '"') + *line++ = *p++; + } else + while (*p && *p != '>') + *line++ = *p++; + *line = '\0'; + break; + case DEFINE: + /* + * copy the definition back to the beginning of the line. + */ + strcpy (line, p); + break; + case ELSE: + case ENDIF: + case ELIF: + case PRAGMA: + case ERROR: + case IDENT: + case SCCS: + case EJECT: + debug(0,("%s, line %d: #%s\n", + file->i_file, filep->f_line, directives[ret])); + /* + * nothing to do. + */ + break; + } + return(ret); +} + +/* + * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c + * function... It's safe, functions from cppsetup.c don't return here. + */ +struct symhash *global_symbols = NULL; + +char * isdefined( symbol ) + register char *symbol; +{ + return hash_lookup( symbol, global_symbols ); +} + +/* + * Return type based on if the #if expression evaluates to 0 + */ +int zero_value(exp, filep, file_red, symbols) + register char *exp; + register struct filepointer *filep; + register struct inclist *file_red; + register struct symhash *symbols; +{ + global_symbols = symbols; /* HACK! see above */ + if (cppsetup(exp, filep, file_red)) + return(IFFALSE); + else + return(IF); +} + +void define( def, symbols ) + char *def; + struct symhash **symbols; +{ + char *val; + + /* Separate symbol name and its value */ + val = def; + while (isalnum(*val) || *val == '_') + val++; + if (*val) + *val++ = '\0'; + while (*val == ' ' || *val == '\t') + val++; + + if (!*val) + val = "1"; + hash_define( def, val, symbols ); +} + +static int hash( str ) + register char *str; +{ + /* Hash (Kernighan and Ritchie) */ + register unsigned int hashval = 0; + //char *s = str; + + for ( ; *str; str++ ) + { + hashval = ( hashval * SYMHASHSEED ) + ( *str ); + } + + //fprintf( stderr, "hash: %s, %d\n", s, hashval & ( SYMHASHMEMBERS - 1 ) ); + return hashval & ( SYMHASHMEMBERS - 1 ); +} + +struct symhash *hash_copy( symbols ) + struct symhash *symbols; +{ + int i; + struct symhash *newsym; + if ( !symbols ) + return NULL; + + newsym = (struct symhash *) malloc( sizeof( struct symhash ) ); + + for ( i = 0; i < SYMHASHMEMBERS; ++i ) + { + if ( !symbols->s_pairs[ i ] ) + newsym->s_pairs[ i ] = NULL; + else + { + struct pair *it = symbols->s_pairs[ i ]; + struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) ); + nw->p_name = it->p_name; + nw->p_value = it->p_value; + nw->p_next = NULL; + + while ( it->p_next ) + { + nw->p_next = (struct pair*) malloc( sizeof( struct pair ) ); + it = it->p_next; + nw = nw->p_next; + nw->p_name = it->p_name; + nw->p_value = it->p_value; + nw->p_next = NULL; + } + } + } + return newsym; +} + +void hash_free( symbols ) + struct symhash *symbols; +{ + int i; + + if ( !symbols ) + return; + + for ( i = 0; i < SYMHASHMEMBERS; ++i ) + { + struct pair *it = symbols->s_pairs[ i ]; + struct pair *next; + while ( it ) + { + next = it->p_next; + free( it ); + it = next; + } + } + free( symbols->s_pairs ); +} + +void hash_define( name, val, symbols ) + char *name, *val; + struct symhash **symbols; +{ + int hashval; + struct pair *it; + + if ( !symbols ) + return; + + /* Make space if it's needed */ + if ( *symbols == NULL ) + { + int i; + + *symbols = (struct symhash *) malloc( sizeof( struct symhash ) ); + if ( *symbols == NULL ) + fatalerr( "malloc()/realloc() failure in insert_defn()\n" ); + + for ( i = 0; i < SYMHASHMEMBERS; ++i ) + (*symbols)->s_pairs[i] = NULL; + } + + hashval = hash( name ); + it = (*symbols)->s_pairs[ hashval ]; + + /* Replace/insert the symbol */ + if ( it == NULL ) + { + it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) ); + it->p_name = copy( name ); + it->p_value = copy( val ); + it->p_next = NULL; + } + else if ( strcmp( it->p_name, name ) == 0 ) + { + it->p_value = copy( val ); + } + else + { + while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) ) + { + it = it->p_next; + } + if ( it->p_next ) + it->p_next->p_name = copy( name ); + else + { + it->p_next = (struct pair*) malloc( sizeof( struct pair ) ); + it->p_next->p_name = copy( name ); + it->p_next->p_value = copy( val ); + it->p_next->p_next = NULL; + } + } +} + +char *hash_lookup( symbol, symbols ) + char *symbol; + struct symhash *symbols; +{ + struct pair *it; + + if ( !symbols ) + return NULL; + + it = symbols->s_pairs[ hash( symbol ) ]; + + while ( it && ( strcmp( it->p_name, symbol ) != 0 ) ) + { + it = it->p_next; + } + if ( it ) + return it->p_value; + + return NULL; +} + +void hash_undefine( symbol, symbols ) + char *symbol; + struct symhash *symbols; +{ + int hashval; + struct pair *it; + + if ( !symbols ) + return; + + hashval = hash( symbol ); + it = symbols->s_pairs[ hashval ]; + + /* Replace/insert the symbol */ + if ( it == NULL ) + return; + else if ( strcmp( it->p_name, symbol ) == 0 ) + { + if ( it->p_next ) + { + struct pair *tmp; + it->p_name = it->p_next->p_name; + it->p_value = it->p_next->p_value; + tmp = it->p_next->p_next; + free( it->p_next ); + it->p_next = tmp; + } + else + { + free( it ); + symbols->s_pairs[ hashval ] = NULL; + } + } + else + { + while ( it->p_next && ( strcmp( it->p_next->p_name, symbol ) != 0 ) ) + { + it = it->p_next; + } + if ( it->p_next ) + { + struct pair *tmp = it->p_next; + it->p_next = it->p_next->p_next; + free( tmp ); + } + } +} diff --git a/soltools/mkdepend/pr.c b/soltools/mkdepend/pr.c new file mode 100644 index 000000000000..1319972f99c5 --- /dev/null +++ b/soltools/mkdepend/pr.c @@ -0,0 +1,137 @@ +/* $XConsortium: pr.c,v 1.17 94/04/17 20:10:38 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" +#include <string.h> +void pr( struct inclist *ip, char *file,char *base); + +extern struct inclist inclist[ MAXFILES ], + *inclistp; +extern char *objprefix; +extern char *objsuffix; +extern int width; +extern boolean printed; +extern boolean verbose; +extern boolean show_where_not; + +void add_include(filep, file, file_red, include, dot, failOK, incCollection, symbols) + struct filepointer *filep; + struct inclist *file, *file_red; + char *include; + boolean dot; + boolean failOK; + struct IncludesCollection* incCollection; + struct symhash *symbols; +{ + register struct inclist *newfile; + register struct filepointer *content; + + /* + * First decide what the pathname of this include file really is. + */ + newfile = inc_path(file->i_file, include, dot, incCollection); + if (newfile == NULL) { + if (failOK) + return; + if (file != file_red) + warning("%s (reading %s, line %d): ", + file_red->i_file, file->i_file, filep->f_line); + else + warning("%s, line %d: ", file->i_file, filep->f_line); + warning1("cannot find include file \"%s\"\n", include); + show_where_not = TRUE; + newfile = inc_path(file->i_file, include, dot, incCollection); + show_where_not = FALSE; + } + + if (newfile) { + + /* Only add new dependency files if they don't have "/usr/include" in them. */ + if (!(newfile && newfile->i_file && strstr(newfile->i_file, "/usr/"))) { + included_by(file, newfile); + } + + if (!newfile->i_searched) { + newfile->i_searched = TRUE; + content = getfile(newfile->i_file); + find_includes(content, newfile, file_red, 0, failOK, incCollection, symbols); + freefile(content); + } + } +} + +void recursive_pr_include(head, file, base) + register struct inclist *head; + register char *file, *base; +{ + register int i; + + if (head->i_marked) + return; + head->i_marked = TRUE; + if (head->i_file != file) + pr(head, file, base); + for (i=0; i<head->i_listlen; i++) + recursive_pr_include(head->i_list[ i ], file, base); +} + +void pr(ip, file, base) + register struct inclist *ip; + char *file, *base; +{ + static char *lastfile; + static int current_len; + register int len, i; + char buf[ BUFSIZ ]; + + printed = TRUE; + len = strlen(ip->i_file)+1; + if (current_len + len > width || file != lastfile) { + lastfile = file; + sprintf(buf, "\n%s%s%s: %s", objprefix, base, objsuffix, + ip->i_file); + len = current_len = strlen(buf); + } + else { + buf[0] = ' '; + strcpy(buf+1, ip->i_file); + current_len += len; + } + fwrite(buf, len, 1, stdout); + + /* + * If verbose is set, then print out what this file includes. + */ + if (! verbose || ip->i_list == NULL || ip->i_notified) + return; + ip->i_notified = TRUE; + lastfile = NULL; + printf("\n# %s includes:", ip->i_file); + for (i=0; i<ip->i_listlen; i++) + printf("\n#\t%s", ip->i_list[ i ]->i_incstring); +} diff --git a/soltools/prj/build.lst b/soltools/prj/build.lst new file mode 100644 index 000000000000..578723b0e09d --- /dev/null +++ b/soltools/prj/build.lst @@ -0,0 +1,13 @@ +so soltools : solenv SUN:so_prereq NULL +so soltools usr1 - all so_usr1 NULL +so soltools\inc get - all so_inc NULL +so soltools\ldump nmake - all so_ldump so_mkdep NULL +so soltools\winunistd nmake - n so_wunistd NULL +so soltools\mkdepend nmake - all so_mkdep so_wunistd.n NULL +so soltools\checkdll nmake - u so_chkdl so_adjvis.u so_mkdep NULL +so soltools\cpp nmake - all so_cpp__ so_mkdep so_adjvis.u NULL +so soltools\javadep nmake - all so_jvdep so_mkdep so_adjvis.u NULL +so soltools\support nmake - all so_supp so_mkdep so_adjvis.u NULL +so soltools\giparser nmake - all so_gip so_supp so_adjvis.u NULL +so soltools\adjustvisibility nmake - u so_adjvis so_mkdep NULL +so soltools\testhxx nmake - all so_testhxx so_mkdep NULL diff --git a/soltools/prj/d.lst b/soltools/prj/d.lst new file mode 100644 index 000000000000..970805f5d60c --- /dev/null +++ b/soltools/prj/d.lst @@ -0,0 +1,11 @@ +..\%__SRC%\bin\ldump4.exe %_DEST%\bin%_EXT%\ldump4.exe +..\%__SRC%\bin\makedepend.exe %_DEST%\bin%_EXT%\makedepend.exe +..\%__SRC%\bin\makedepend %_DEST%\bin%_EXT%\makedepend +..\%__SRC%\bin\adjustvisibility %_DEST%\bin%_EXT%\adjustvisibility +..\%__SRC%\bin\javadep.exe %_DEST%\bin%_EXT%\javadep.exe +..\%__SRC%\bin\javadep %_DEST%\bin%_EXT%\javadep +..\%__SRC%\bin\checkdll %_DEST%\bin%_EXT%\checkdll +..\%__SRC%\bin\cpp.exe %_DEST%\bin%_EXT%\cpplcc.exe +..\%__SRC%\bin\cpp %_DEST%\bin%_EXT%\cpp.lcc +..\%__SRC%\inc\unistd.h %_DEST%\inc%_EXT%\unistd.h +..\%__SRC%\bin\testhxx* %_DEST%\bin%_EXT%\testhxx* diff --git a/soltools/support/makefile.mk b/soltools/support/makefile.mk new file mode 100644 index 000000000000..d3f1095f6eb2 --- /dev/null +++ b/soltools/support/makefile.mk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=soltools_support +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + + + +# --- Files -------------------------------------------------------- + +OBJFILES= \ + $(OBJ)$/simstr.obj + +SLOFILES= \ + $(SLO)$/simstr.obj + + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/soltools/support/simstr.cxx b/soltools/support/simstr.cxx new file mode 100644 index 000000000000..d2ecf3480677 --- /dev/null +++ b/soltools/support/simstr.cxx @@ -0,0 +1,833 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + + +#include <simstr.hxx> + +#include <string.h> // strlen(), memcpy(), memset() +#include <ctype.h> // tolower() +#include <limits.h> // INT_MAX + +const char NULCH = '\0'; +const int NO_POS = -1; + + +Simstr::Simstr(const char * s_) +{ + if (s_ == 0) + { + len = 0; + sz = new char[1]; + *sz = 0; + } + else + { + len = strlen(s_); + sz = new char[len+1]; + memcpy(sz,s_,len+1); + } +} + +Simstr::Simstr(const char * anybytes, int nrOfBytes) +{ + if (anybytes == 0) + { + len = 0; + sz = new char[1]; + *sz = 0; + return; + } + + int slen = static_cast<int>( strlen(anybytes) ); + + len = slen < nrOfBytes + ? slen + : nrOfBytes; + sz = new char[len+1]; + memcpy( sz, anybytes, len ); + *( sz + len ) = 0; +} + +Simstr::Simstr(char c, int anzahl) +{ + if (anzahl < 1) + { + len = 0; + sz = new char[1]; + *sz = 0; + } + else + { + len = anzahl; + sz = new char[len+1]; + memset(sz,c,anzahl); + sz[len] = 0; + } +} + +Simstr::Simstr( const char * anybytes, + int firstBytesPos, + int nrOfBytes) +{ + unsigned slen = strlen(anybytes); + if (anybytes == 0 || slen <= unsigned(firstBytesPos)) + { + len = 0; + sz = new char[1]; + *sz = 0; + } + else + { + int maxLen = slen - unsigned(firstBytesPos); + len = maxLen < nrOfBytes + ? maxLen + : nrOfBytes; + sz = new char[len+1]; + memcpy(sz,anybytes+firstBytesPos,len); + *(sz+len) = 0; + } +} + + +Simstr::Simstr(const Simstr & S) +{ + len = S.len; + sz = new char[len+1]; + memcpy(sz,S.sz,len+1); +} + +Simstr & Simstr::operator=(const Simstr & S) +{ + if (sz == S.sz) + return *this; + + delete [] sz; + + len = S.len; + sz = new char[len+1]; + memcpy(sz,S.sz,len+1); + + return *this; +} + +Simstr::~Simstr() +{ + delete [] sz; +} + +char & +Simstr::ch(int n) +{ + static char nullCh = NULCH; + nullCh = NULCH; + if (n >= long(len) || n < 0) + return nullCh; + else + return sz[unsigned(n)]; +} + +const Simstr & +Simstr::null_() +{ + static Simstr aNull_; + return aNull_; +} + + +Simstr +Simstr::operator+(const Simstr & S) const +{ + Simstr ret = sz; + ret.push_back(S); + return ret; +} + +Simstr & +Simstr::operator+=(const Simstr & S) +{ + push_back(S); + return *this; +} + +Simstr & +Simstr::operator+=(const char * s_) +{ + Simstr a(s_); + push_back(a); + return *this; +} + + +// REL + +bool +Simstr::operator==(const Simstr & S) const +{ return !strcmp(sz,S.sz) ? true : false; } + +bool +Simstr::operator!=(const Simstr & S) const +{ return strcmp(sz,S.sz) ? true : false; } + +bool +Simstr::operator<(const Simstr & S) const +{ return (strcmp(sz,S.sz) < 0) ? true : false; } + +bool +Simstr::operator>(const Simstr & S) const +{ return (strcmp(sz,S.sz) > 0) ? true : false; } + +bool +Simstr::operator<=(const Simstr & S) const +{ return (strcmp(sz,S.sz) <= 0) ? true : false; } + +bool +Simstr::operator>=(const Simstr & S) const +{ return (strcmp(sz,S.sz) >= 0) ? true : false; } + + + + +// ************** LIST - Funktionen ***************** + + +// Einzelzugriff + +char +Simstr::get(int n) const { return (n >= len || n < 0) ? 0 : sz[n]; } + +char +Simstr::get_front() const { return sz[0]; } + +char +Simstr::get_back() const { return len ? sz[len-1] : 0; } + +Simstr +Simstr::get(int startPos, int anzahl) const +{ + if (startPos >= len || startPos < 0 || anzahl < 1) + return ""; + + int anz = len - startPos < anzahl ? len - startPos : anzahl; + + Simstr ret(' ',anz); + memcpy(ret.sz, sz+startPos, anz); + return ret; +} + +Simstr +Simstr::get_front(int anzahl) const +{ + int anz = len < anzahl ? len : anzahl; + if (anz < 1) + return ""; + + Simstr ret(' ',anz); + memcpy(ret.sz, sz, anz); + return ret; +} + +Simstr +Simstr::get_back(int anzahl) const +{ + int anz = len < anzahl ? len : anzahl; + if (anz < 1) + return ""; + int start = len-anz; + + Simstr ret(' ',anz); + memcpy(ret.sz, sz+start, anz); + return ret; +} + +Simstr +Simstr::get_first_token(char c) const +{ + int posc = pos_first(c); + if (posc != NO_POS) + return get_front(posc); + else + return sz; +} + +Simstr +Simstr::get_last_token(char c) const +{ + int posc = pos_last(c); + if (posc != NO_POS) + return get_back(len-posc-1); + else + return sz; +} + + + +// Insert + +void +Simstr::insert(int pos, char c) +{ + if (pos < 0 || pos > len) + return; + + char * result = new char[len+2]; + + memcpy(result,sz,pos); + result[pos] = c; + memcpy(result+pos+1,sz+pos,len-pos+1); + + delete [] sz; + sz = result; + len++; +} + +void +Simstr::push_front(char c) +{ + char * result = new char[len+2]; + + result[0] = c; + memcpy(result+1,sz,len+1); + + delete [] sz; + sz = result; + len++; +} + +void +Simstr::push_back(char c) +{ + char * result = new char[len+2]; + + memcpy(result,sz,len); + result[len] = c; + result[len+1] = 0; + + delete [] sz; + sz = result; + len++; +} + +void +Simstr::insert(int pos, const Simstr & S) +{ + if (pos < 0 || pos > len) + return; + + char * result = new char[len+1+S.len]; + + memcpy(result,sz,pos); + memcpy(result+pos,S.sz,S.len); + memcpy(result+pos+S.len,sz+pos,len-pos+1); + + delete [] sz; + sz = result; + len += S.len; +} + +void +Simstr::push_front(const Simstr & S) +{ + char * result = new char[len+1+S.len]; + + memcpy(result,S.sz,S.len); + memcpy(result+S.len,sz,len+1); + + delete [] sz; + sz = result; + len += S.len; +} + +void +Simstr::push_back(const Simstr & S) +{ + char * result = new char[len+1+S.len]; + + memcpy(result,sz,len); + memcpy(result+len,S.sz,S.len+1); + + delete [] sz; + sz = result; + len += S.len; +} + + +// Remove + +void +Simstr::remove(int pos, int anzahl) +{ + if (pos >= len || pos < 0 || anzahl < 1) + return; + + int anz = len - pos < anzahl ? len - pos : anzahl; + + char * result = new char[len-anz+1]; + + memcpy(result,sz,pos); + memcpy(result+pos,sz+pos+anz,len-pos-anz+1); + + delete [] sz; + sz = result; + len -= anz; +} + +void +Simstr::remove_trailing_blanks() +{ + int newlen = len-1; + for ( ; newlen > 1 && sz[newlen] <= 32; --newlen ) {} + + if (newlen < len-1) + remove ( newlen+1, len-newlen); +} + +void +Simstr::pop_front(int anzahl) +{ + if (anzahl < 1) + return; + int anz = len < anzahl ? len : anzahl; + + char * result = new char[len-anz+1]; + + memcpy(result,sz+anz,len-anz+1); + + delete [] sz; + sz = result; + len -= anz; +} + +void +Simstr::pop_back(int anzahl) +{ + if (anzahl < 1) + return; + + int anz = len < anzahl ? len : anzahl; + + char * result = new char[len-anz+1]; + + memcpy(result,sz,len-anz); + result[len-anz] = 0; + + delete [] sz; + sz = result; + len -= anz; +} + +void +Simstr::rem_back_from(int removeStartPos) +{ + if (removeStartPos != NO_POS) + pop_back(len-removeStartPos); +} + +void +Simstr::remove_all(char c) +{ + if (!len) + return; + char * result = new char[len]; + int i,j=0; + for (i = 0; i < len; i++) + if (sz[i] != c) + result[j++] = sz[i]; + + delete [] sz; + sz = new char[j+1]; + memcpy(sz,result,j); + sz[j] = 0; + len = j; + delete [] result; +} + +void +Simstr::remove_all(const Simstr & S) +{ + int pos; + while ( (pos=pos_first(S)) != NO_POS ) + remove(pos,S.len); +} + +void +Simstr::strip(char c) +{ + int start = 0; + if (c == ' ') + { // Sonderbehandlung: SPC entfernt auch TABs: + while ( start < len + ? sz[start] == ' ' + || sz[start] == '\t' + : false ) + start++; + } + else + { + while (start < len && sz[start] == c) + start++; + } + + int ende = len-1; + if (c == ' ') + { // Sonderbehandlung: SPC entfernt auch TABs: + while ( ende >= start + ? sz[ende] == ' ' + || sz[ende] == '\t' + : false ) + ende--; + } + else + { + while (ende >= start && sz[ende] == c) + ende--; + } + *this = get(start,ende-start+1); +} + +void +Simstr::empty() +{ + if (len > 0) + { + delete [] sz; + sz = new char[1]; + *sz = 0; + len = 0; + } +} + +Simstr +Simstr::take_first_token(char c) +{ + Simstr ret; + int pos = pos_first(c); + if (pos != NO_POS) + { + ret = get_front(pos); + pop_front(pos+1); + } + else + { + ret = sz; + delete [] sz; + sz = new char[1]; + *sz = NULCH; + len = 0; + } + + return ret; +} + +Simstr +Simstr::take_last_token(char c) +{ + Simstr ret; + int pos = pos_last(c); + if (pos != NO_POS) + { + ret = get_back(len-pos-1); + pop_back(len-pos); + } + else + { + ret = sz; + delete [] sz; + sz = new char[1]; + *sz = NULCH; + len = 0; + } + + return ret; +} + + + +// Find + +int +Simstr::pos_first(char c) const +{ + int i = 0; + for (i = 0; i < len ? sz[i] != c : false; i++) ; + if (i >= len) + return NO_POS; + else + return i; +} + +int +Simstr::pos_first_after( char c, + int startSearchPos) const +{ + int i = 0; + if (startSearchPos >= i) + i = startSearchPos+1; + for (; i < len ? sz[i] != c : false; i++) ; + if (i >= len) + return NO_POS; + else + return i; +} + + +int +Simstr::pos_last(char c) const +{ + int i = 0; + for (i = len-1; i >= 0 ? sz[i] != c : false; i--) ; + if (i < 0) + return NO_POS; + else + return i; +} + +int +Simstr::pos_first(const Simstr & S) const +{ + char * ptr = strstr(sz,S.sz); + if (ptr) + return int(ptr-sz); + else + return NO_POS; +} + +int +Simstr::pos_last(const Simstr & S) const +{ + Simstr vgl; + int i; + for (i = len-S.len; i >= 0 ; i--) + { + vgl = get(i,S.len); + if (vgl == S) + break; + } + if (i >= 0) + return i; + else + return NO_POS; +} + +int +Simstr::count(char c) const +{ + int ret = 0; + for (int i =0; i < len; i++) + if (sz[i] == c) + ret++; + return ret; +} + +bool +Simstr::is_no_text() const +{ + if (!len) + return true; + + int i; + for (i = 0; sz[i] <= 32 && i < len; i++) ; + if (i < len) + return false; + return true; +} + +// Change + +void +Simstr::replace(int pos, char c) +{ + if (pos < 0 || pos >= len) + return; + else + sz[unsigned(pos)] = c; +} + +void +Simstr::replace(int startPos, int anzahl, const Simstr & S) +{ + if (startPos >= len || startPos < 0 || anzahl < 1) + return; + + int anz = len - startPos < anzahl ? len - startPos : anzahl; + + char * result = new char[len-anz+S.len+1]; + + memcpy(result,sz,startPos); + memcpy(result+startPos, S.sz, S.len); + memcpy(result+startPos+S.len, sz+startPos+anz, len-startPos-anz+1); + + delete [] sz; + sz = result; + len = len-anz+S.len; +} + +void +Simstr::replace_all(char oldCh, char newCh) +{ + for (int i=0; i < len; i++) + if (sz[i] == oldCh) + sz[i] = newCh; +} + +void +Simstr::replace_all(const Simstr & oldS, const Simstr & newS) +{ + Simstr vgl; + int i = 0; + while (i <= len-oldS.len) + { + vgl = get(i,oldS.len); + if (strcmp(vgl.sz,oldS.sz) == 0) + { + replace(i,oldS.len,newS); + i += newS.len; + } + else + i++; + } +} + +void +Simstr::to_lower() +{ + for (int i = 0; i < len; i++) + sz[i] = (char) tolower(sz[i]); +} + + + +// Simstr addition +Simstr +operator+(const char * str, const Simstr & S) +{ + Simstr ret = S; + ret.push_front(str); + return ret; +} + +Simstr +operator+(const Simstr & S, const char * str) +{ + Simstr ret = S; + ret.push_back(str); + return ret; +} + +Simstr +operator+(char c, const Simstr & S) +{ + Simstr ret = S; + ret.push_front(c); + return ret; +} + +Simstr +operator+(const Simstr & S, char c) +{ + Simstr ret = S; + ret.push_back(c); + return ret; +} + + +// Simstr-Vergleiche mit char * +bool +operator==(const Simstr & S, const char * str) +{ + return strcmp(S,str) == 0; +} + +bool +operator!=(const Simstr & S, const char * str) +{ + return strcmp(S,str) != 0; +} + +bool +operator<(const Simstr & S, const char * str) +{ + return strcmp(S,str) < 0; +} + +bool +operator>(const Simstr & S, const char * str) +{ + return strcmp(S,str) > 0; +} + +bool +operator<=(const Simstr & S, const char * str) +{ + return strcmp(S,str) <= 0; +} + +bool +operator>=(const Simstr & S, const char * str) +{ + return strcmp(S,str) >= 0; +} + +bool +operator==(const char * str, const Simstr & S) +{ + return strcmp(str,S) == 0; +} + +bool +operator!=(const char * str, const Simstr & S) +{ + return strcmp(str,S) != 0; +} + +bool +operator<(const char * str, const Simstr & S) +{ + return strcmp(str,S) < 0; +} + +bool +operator>(const char * str, const Simstr & S) +{ + return strcmp(str,S) > 0; +} + +bool +operator<=(const char * str, const Simstr & S) +{ + return strcmp(str,S) <= 0; +} + +bool +operator>=(const char * str, const Simstr & S) +{ + return strcmp(str,S) >= 0; +} + + diff --git a/soltools/testSHL/inc/tlog.hxx b/soltools/testSHL/inc/tlog.hxx new file mode 100644 index 000000000000..acae18be7e9f --- /dev/null +++ b/soltools/testSHL/inc/tlog.hxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SOLTOOLS_TESTSHL_TLOG_HXX__ +#define _SOLTOOLS_TESTSHL_TLOG_HXX__ + +#include <osl/file.hxx> +#include <rtl/tres.hxx> + +#ifndef _SOLTOOLS_TESTSHL_TUTIL_HXX_ +#include "tutil.hxx" +#endif + +#include <iostream> + +using namespace std; + +// <namespace_tstutl> +namespace tstutl { + +// <class_tLog> +class tLog { + + // <private_members> + ::osl::File* m_logfile; // fileobject + ::rtl::OUString m_logname; // name of log + // </private_members> + + // <private_methods> + void initialize( const ::rtl::OString& name ); + // </private_methods> + +public: + + // <public_ctors> + tLog() : m_logfile( 0 ) { + } + + tLog( const sal_Char* name ) { + if( name ) { + initialize( name ); + } + else { + m_logfile = 0; + } + + } + // </public_ctors> + + // <dtor> + virtual ~tLog() { + if ( m_logfile ) { + m_logfile->close(); + delete( m_logfile ); + } + } // </dtor> + + // <public_methods> + inline ::rtl::OUString& getName() { return m_logname; } + inline ::osl::File* getFile() { return m_logfile; } + + // open logfile for overwrite (default) or append + ::osl::FileBase::RC open( sal_Bool append = sal_False ); + ::osl::FileBase::RC close(); + + ::osl::FileBase::RC writeRes( ::rtl::TestResult& oRes, sal_Bool v = sal_False , + sal_Bool xml = sal_False ); + + // write methods without (default) or with echo on display + ::osl::FileBase::RC write( const sal_Char* buf, sal_Bool v = sal_False ); + // </public_methods> + +}; // </class_tLog> + +} // </namespace_tstutl> + +#endif diff --git a/soltools/testSHL/inc/tstMgr.hxx b/soltools/testSHL/inc/tstMgr.hxx new file mode 100644 index 000000000000..208714322395 --- /dev/null +++ b/soltools/testSHL/inc/tstMgr.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SOLTOOLS_TESTSHL_TSTMGR_HXX__ +#define _SOLTOOLS_TESTSHL_TSTMGR_HXX__ + +#include <sal/types.h> + +#include <vector> + +using namespace std; + +// <namespace_tstutl> +namespace tstutl { + +// <class_tstMgr> +class tstMgr { + + // <private_members> + struct tstMgr_Impl; + tstMgr_Impl* pImpl; + // </private_members> + + // <private_methods> + void cleanup(); + // </private_methods> + +public: + + // <dtor> + ~tstMgr(){ + cleanup(); + } // </dtor> + + + // <public_methods> + sal_Bool initialize( sal_Char* moduleName, sal_Bool boom = sal_False ); + sal_Bool test_Entry( sal_Char* entry, sal_Char* logName = 0 ); + sal_Bool test_Entries( vector< sal_Char* > entries, sal_Char* logName = 0 ); + sal_Bool test_EntriesFromFile( sal_Char* fName, sal_Char* logName = 0 ); + // </public_methods> + +}; // </class_tstMgr> + +} // </namespace_tstutl> + +#endif + + + diff --git a/soltools/testSHL/inc/tutil.hxx b/soltools/testSHL/inc/tutil.hxx new file mode 100644 index 000000000000..37398a72381a --- /dev/null +++ b/soltools/testSHL/inc/tutil.hxx @@ -0,0 +1,49 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SOLTOOLS_TESTSHL_TUTIL_HXX_ +#define _SOLTOOLS_TESTSHL_TUTIL_HXX__ + +#include <osl/file.hxx> + +using namespace std; + +#include <vector> + +// <namespace_tstutl> +namespace tstutl { + +sal_uInt32 getEntriesFromFile( sal_Char* fName, vector< sal_Char* >& entries ); +::rtl::OUString cnvrtPth( ::rtl::OString sysPth ); + +// string copy, cat, len methods +sal_Char* cpy( sal_Char** dest, const sal_Char* src ); +sal_Char* cat( const sal_Char* str1, const sal_Char* str2 ); +sal_uInt32 ln( const sal_Char* str ); + +} // </namespace_tstutl> + +#endif diff --git a/soltools/testSHL/makefile.mk b/soltools/testSHL/makefile.mk new file mode 100644 index 000000000000..0377137b2274 --- /dev/null +++ b/soltools/testSHL/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=.. + +PRJNAME=soltools +TARGET=testshl +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +UWINAPILIB=$(0) +LIBSALCPPRT=$(0) + +# ------------------------------------------------------------------ + +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/$(TARGET).obj +APP1STDLIBS=$(SALLIB)\ + $(SALHELPERLIB) +APP1DEPN= $(LB)$/tstutil.lib +APP1LIBS= $(LB)$/tstutil.lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/testSHL/testshl.cxx b/soltools/testSHL/testshl.cxx new file mode 100644 index 000000000000..9642d8761f50 --- /dev/null +++ b/soltools/testSHL/testshl.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include <stdio.h> + +#ifndef _SOLTOOLS_TESTSHL_TLOG_HXX_ +#include "inc/tlog.hxx" +#endif + +#ifndef _SOLTOOLS_TESTSHL_TSTMGR_HXX_ +#include "inc/tstMgr.hxx" +#endif + +using namespace tstutl; + +void usage(); +void test_shl( vector< sal_Char* > cmdln, sal_Bool boom ); + +#if (defined UNX) || (defined OS2) +int main( int argc, char* argv[] ) +#else +int _cdecl main( int argc, char* argv[] ) +#endif +{ + if ( argc < 3 ) { + usage(); + } + sal_Bool boom = sal_False; + vector< sal_Char* > cmdln; + + sal_Int32 i; + for ( i = 1; i < argc; i++ ) { + sal_Char* ptr = argv[i]; + if ( ptr[0] == '-' ) { + boom = sal_True; + } + else { + cmdln.push_back( ptr ); + } + } + if ( cmdln.size() < 3 ) { + cmdln.push_back( 0 ); + } + if ( ! cmdln[0] || ! cmdln[1] ) { + usage(); + } + + test_shl( cmdln, boom ); + + return(0); +} + +void test_shl( vector< sal_Char*> cmdln, sal_Bool boom ) { + + tstMgr tst; + + if ( tst.initialize( cmdln[0], boom )) { + tst.test_EntriesFromFile( cmdln[1], cmdln[2] ); + } + else { + sal_Char* msg = "could not find module\n"; + fprintf( stdout, "%s\n", msg ); + } +} + +void usage(){ + fprintf( stdout, + "USAGE: testSHL shlname scename [logname] [-boom]\n" ); + exit(0); +} + diff --git a/soltools/testSHL/util/makefile.mk b/soltools/testSHL/util/makefile.mk new file mode 100644 index 000000000000..a2582f9c1abd --- /dev/null +++ b/soltools/testSHL/util/makefile.mk @@ -0,0 +1,45 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=soltools +TARGET=tstutil + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +OBJFILES =\ + $(OBJ)$/tlog.obj \ + $(OBJ)$/tutil.obj \ + $(OBJ)$/tstMgr.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/testSHL/util/tlog.cxx b/soltools/testSHL/util/tlog.cxx new file mode 100644 index 000000000000..48eeafc7908a --- /dev/null +++ b/soltools/testSHL/util/tlog.cxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" + +#include "tlog.hxx" + +using namespace std; + +// <namespace_tstutl> +namespace tstutl { + +// <method_initialize> +void tLog::initialize( const ::rtl::OString& name ) { + m_logname = cnvrtPth( name ); + m_logfile = new ::osl::File( m_logname ); +} // </method_initialize> + +// <method_open> +::osl::FileBase::RC tLog::open( sal_Bool append ) { + + if ( m_logfile ) { + ::osl::FileBase::RC ret; + + if ( ! append ) { + ret = ::osl::File::remove( m_logname ); + } + + if( m_logfile->open( OpenFlag_Write ) == ::osl::FileBase::E_NOENT ) { + ret = m_logfile->open( OpenFlag_Write | OpenFlag_Create ); + } + else { + ret = m_logfile->setPos( Pos_End, 0 ); + } + return ret; + } + return ( ::osl::FileBase::E_INVAL ); +} // </method_open> + +// <method_close> +::osl::FileBase::RC tLog::close() { + if ( m_logfile ) { + return m_logfile->close(); + } + return ( ::osl::FileBase::E_INVAL ); +} // </method_close> + +// <method_writeRes> +::osl::FileBase::RC tLog::writeRes( ::rtl::TestResult& oRes, sal_Bool v, sal_Bool xml ) { + ::osl::FileBase::RC ret; + + sal_Char* ptr = oRes.getName(); + ptr = cat( ptr, ";" ); + ptr = cat( ptr, oRes.getResult() ); + ret = write( cat( ptr, "\n" ), v ); + delete [] ptr; + + return( ret ); +} // </method_writeRes> + +// <method_write> +::osl::FileBase::RC tLog::write( const sal_Char* buf, sal_Bool v ) { + + if ( ! m_logfile ) { + fprintf( stderr, "%s", buf ); + return ( ::osl::FileBase::E_NOENT ); + } + sal_uInt64 uBytes=0; + sal_uInt32 len = ln( buf ); + const sal_Char* ptr = buf; + + if ( v ) { + fprintf( stderr, "%s", buf ); + } + return m_logfile->write( buf, len , uBytes ); +} // </method_write> + +} // </namespace_tstutl> + + + + + diff --git a/soltools/testSHL/util/tstMgr.cxx b/soltools/testSHL/util/tstMgr.cxx new file mode 100644 index 000000000000..2aad1c758d41 --- /dev/null +++ b/soltools/testSHL/util/tstMgr.cxx @@ -0,0 +1,164 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" +#include "tstMgr.hxx" +#include <osl/module.hxx> +#include <rtl/tres.hxx> + +#ifndef _SOLTOOLS_TESTSHL_TLOG_HXX_ +#include "tlog.hxx" +#endif + +#ifndef _SOLTOOLS_TESTSHL_TUTIL_HXX_ +#include "tutil.hxx" +#endif + +using namespace rtl; + +// <namespace_tstutl> +namespace tstutl { + +typedef void* ( tstFunc )( TestResult* ); +void test_Entry_Impl( ::osl::Module& oMod, TestResult* oRes ); + +// <private_members> +struct tstMgr::tstMgr_Impl { + ::osl::Module m_tstmodule; + sal_Bool m_boom; +}; +// </private_members> + +// <method_initialize> +sal_Bool tstMgr::initialize( sal_Char* modName, sal_Bool boom ) { + + ::rtl::OUString tstMod( ::rtl::OUString::createFromAscii( modName ) ); + pImpl = new tstMgr_Impl; + pImpl->m_boom = boom; + return ( pImpl->m_tstmodule.load( tstMod ) ); +} // <method_initialize> + +// <method_test_Entries> +sal_Bool tstMgr::test_Entries( vector< sal_Char* > entries, + sal_Char* logName ) { + + sal_Bool bOK = sal_False; + if ( ! entries.empty() ) { + + bOK = sal_True; + vector< sal_Char* >::iterator iter = entries.begin(); + + tLog log( logName ); + // open testLog + log.open(); + while ( iter != entries.end() ) { + if ( *iter[0] != '#' ) { + ::rtl::TestResult oRes( *iter, pImpl->m_boom ); + test_Entry_Impl( pImpl->m_tstmodule, &oRes ); + bOK &= oRes.getState(); + log.writeRes( oRes ); + } + iter++; + } + log.close(); + } + return ( bOK ); +} // </method_test_Entries> + +// <method_test_Entry> +sal_Bool tstMgr::test_Entry( sal_Char* entry, sal_Char* logName ) { + + tLog log( logName ); + // open testLog + log.open(); + ::rtl::TestResult oRes( entry, pImpl->m_boom ); + test_Entry_Impl( pImpl->m_tstmodule, &oRes ); + log.writeRes( oRes, sal_True ); + log.close(); + return ( oRes.getState() ); +} // </method_test_Entry> + +// <method_test_EntriesFromFile> +sal_Bool tstMgr::test_EntriesFromFile( sal_Char* fName, sal_Char* logName ) { + + sal_Bool bOK = sal_False; + vector< sal_Char* > entries; + + if ( getEntriesFromFile( fName, entries ) ) { + sal_Bool bOK = test_Entries( entries, logName ); + + vector< sal_Char* >::iterator iter = entries.begin(); + while ( iter != entries.end() ) { + if ( *iter ) { + delete [] *iter; + } + iter++; + } + } + else { + bOK = test_Entry( fName ); + } + return ( bOK ); + +} // </method_test_EntriesFromFile> + +// <method_cleanup> +void tstMgr::cleanup() { + if ( pImpl ) { + delete pImpl; + } +} // </method_cleanup> + + +// <function_test_Entry_Impl> +void test_Entry_Impl( ::osl::Module& oMod, ::rtl::TestResult* oRes ) { + + tstFunc* pFunc; // entry pointer + ::rtl::OString entryName( "test_" ); // entryname prefix + + // prefix entryname + entryName += oRes->getName(); + + // get entry pointer + pFunc = (tstFunc*) oMod.getSymbol( + ::rtl::OUString::createFromAscii( entryName.getStr() ) ); + + if ( pFunc ) { + // call entry + pFunc( oRes ); + oRes->end(); + } + else { + oRes->end("symbol not found"); + } + // return + return; + +} // </function_test_Entry_Impl> + +} // </namespace_tstutl> diff --git a/soltools/testSHL/util/tutil.cxx b/soltools/testSHL/util/tutil.cxx new file mode 100644 index 000000000000..60c5f6deba02 --- /dev/null +++ b/soltools/testSHL/util/tutil.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_soltools.hxx" +#include "tutil.hxx" + +// <namespace_tstutl> +namespace tstutl { + +// getcwd hack is deprecated as soon as normalizePath works as intend +#ifdef WNT +#define _getcwd getcwd +#include <direct.h> // _getcwd +#else +#include <unistd.h> // getcwd +#endif + +// <function_cnvrtPth> +::rtl::OUString cnvrtPth( ::rtl::OString sysPth ) { + + using ::osl::FileBase; + using ::rtl::OUString; + using ::rtl::OString; + + ::rtl::OUString ret; + sysPth = sysPth.replace( '\\','/' ); + OUString pth( OUString::createFromAscii( sysPth.getStr() ) ); + + if ( sysPth.indexOf("..") != -1 ) { + + // <hack> for osl_normalizePath() can't handle relatives + char buffer[256]; + OString curPth(getcwd(buffer,256)); + // </hack> + OUString nrmCurPth; + FileBase::normalizePath( OUString::createFromAscii( curPth ) , + nrmCurPth ); + FileBase::getAbsolutePath( nrmCurPth, pth, ret ); + } + else { + FileBase::normalizePath( pth, ret ); + } + return ret; + +} // </function_cnvrtPth> + +// <function_getEntriesFromFile> +sal_uInt32 getEntriesFromFile( sal_Char* fName, + vector< sal_Char* >& entries ) { + + ::osl::File inFile( cnvrtPth( fName ) ); + if ( inFile.open( OpenFlag_Read ) == ::osl::FileBase::E_None) { + ::rtl::ByteSequence byteSeq; + inFile.readLine( byteSeq ); + while ( byteSeq.getLength() ) { + sal_uInt32 len = byteSeq.getLength(); + sal_uInt32 i; + sal_Char* pEnt = new sal_Char[ len+1 ]; + sal_Char* bsPtr = (sal_Char*)byteSeq.getArray(); + for ( i=0; i<len; i++ ) { + pEnt[i] = bsPtr[i]; + } + pEnt[len] = '\0'; + entries.push_back( pEnt ); + + inFile.readLine( byteSeq ); + } + } + return ( entries.size() ); + +} // </function_getEntriesFromFile> + +// <function_cpy> +sal_Char* cpy( sal_Char** dest, const sal_Char* src ) { + + *dest = new sal_Char[ ln(src)+1 ]; + // set pointer + sal_Char* pdest = *dest; + const sal_Char* psrc = src; + + // copy string by char + while( *pdest++ = *psrc++ ); + + return ( *dest ); + +} // </function_cpy> + +// <function_cat> +sal_Char* cat( const sal_Char* str1, const sal_Char* str2 ) { + + // allocate memory for destination string + sal_Char* dest = new sal_Char[ ln(str1)+ln(str2)+1 ]; + + // set pointers + sal_Char* pdest = dest; + const sal_Char* psrc = str1; + + // copy string1 by char to dest + while( *pdest++ = *psrc++ ); + pdest--; + psrc = str2; + while( *pdest++ = *psrc++ ); + + return ( dest ); + +} // </function_cat> + +// <function_ln> +sal_uInt32 ln( const sal_Char* str ) { + + sal_uInt32 len = 0; + const sal_Char* ptr = str; + + if( ptr ) { + while( *ptr++ ) len++; + } + + return(len); +} // <function_ln> + +} // </namespace_tstutl> + diff --git a/soltools/testhxx/create.pl b/soltools/testhxx/create.pl new file mode 100644 index 000000000000..5c9f04118c78 --- /dev/null +++ b/soltools/testhxx/create.pl @@ -0,0 +1,125 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$solarversion = $ENV{SOLARVERSION}; +$solarversion =~ s![^0-9A-Za-z]!\\$&!g; +$in = <> || die 'no input'; +chomp $in; +if ($ENV{OS} eq 'LINUX') { + 1 while $in =~ s!\s+-I\s*[^/]\S*\s*! !g; # discard relative includes + $in =~ s!(\s+-I\s*)$solarversion(\S*)!$1\${SOLARVERSION}$2!og; + # macrofy includes to solver + $in =~ s!\s+-o\s*\S+! -o /dev/null! || die 'bad input: no -o'; + $in =~ s!\S+/testhxx.cxx!-x c++ /proc/self/fd/0! + || die 'bad input: no source file'; + print STDOUT '#!/bin/bash', "\n"; + print STDOUT $in, + ' <<<"#include \\"`echo $(if [ ${1%/*} != $1 ];then cd ${1%/*};fi;', + '/bin/pwd)/${1##*/}`\\""', "\n"; +} elsif ($ENV{OS} eq 'SOLARIS') { + 1 while $in =~ s!\s+-I\s*[^/]\S*\s*! !g; # discard relative includes + $in =~ s!(\s+-I\s*)$solarversion(\S*)!$1\${SOLARVERSION}$2!og; + # macrofy includes to solver + $in =~ s!\s+-o\s*\S+! -o /dev/null! || die 'bad input: no -o'; + $in =~ s!\S+/testhxx.cxx!\${my_tmp}! + || die 'bad input: no source file'; + print STDOUT '#!/bin/sh', "\n"; + print STDOUT + 'my_tmp=${TMPDIR:-/tmp}/`/usr/xpg4/bin/id -u`_$$_include.cc', "\n"; + print STDOUT 'my_pat=`dirname $1`', "\n"; + print STDOUT 'my_fil=`basename $1`', "\n"; + print STDOUT 'my_org=${PWD}', "\n"; + print STDOUT 'cd $my_pat || exit 1', "\n"; + print STDOUT 'my_pat=`pwd`', "\n"; + print STDOUT 'cd $my_org || exit 1', "\n"; + print STDOUT + 'echo "#include \\"${my_pat}/${my_fil}\\"" > ${my_tmp} || exit 1', "\n"; + print STDOUT $in, ' > ${my_tmp}.out 2>&1', "\n"; + print STDOUT 'my_ret=$?', "\n"; + print STDOUT + 'if [ ${my_ret} -ne 0 ] ; then echo $1 >&2 ; cat ${my_tmp}.out >&2 ;', + ' fi', "\n"; + print STDOUT 'unlink ${my_tmp} || exit 1', "\n"; + print STDOUT 'unlink ${my_tmp}.out || exit 1', "\n"; + print STDOUT 'exit ${my_ret}', "\n"; +} elsif ($ENV{OS} eq 'WNT') { + if ($ENV{COM} eq 'GCC') { + 1 while $in =~ s!\s+-I\s*\.\S*\s*! !g; # discard relative includes + $in =~ s!(\s+-I\s*)(?i:$solarversion)(\S*)!$1\${SOLARVERSION}$2!og; + # macrofy includes to solver + $in =~ s!\s+-o\s*\S+! -o /dev/null! || die 'bad input: no -o'; + $in =~ s!\S+/testhxx.cxx!\${my_tmp}! + || die 'bad input: no source file'; + print STDOUT '#!/bin/sh', "\n"; + print STDOUT + 'my_tmp=${TMPDIR:-/tmp}/`id -u`_$$_include.cc', "\n"; + print STDOUT 'my_pat=`dirname $1`', "\n"; + print STDOUT 'my_fil=`basename $1`', "\n"; + print STDOUT 'my_org=${PWD}', "\n"; + print STDOUT 'cd $my_pat || exit 1', "\n"; + print STDOUT 'my_pat=`cygpath -m \`pwd\``', "\n"; + print STDOUT 'cd $my_org || exit 1', "\n"; + print STDOUT + 'echo "#include \\"${my_pat}/${my_fil}\\"" > ${my_tmp} || exit 1', "\n"; + print STDOUT $in, ' > ${my_tmp}.out 2>&1', "\n"; + print STDOUT 'my_ret=$?', "\n"; + print STDOUT + 'if [ ${my_ret} -ne 0 ] ; then echo $1 >&2 ; cat ${my_tmp}.out >&2 ;', + ' fi', "\n"; + print STDOUT 'unlink ${my_tmp} || exit 1', "\n"; + print STDOUT 'unlink ${my_tmp}.out || exit 1', "\n"; + print STDOUT 'exit ${my_ret}', "\n"; + } else { + 1 while $in =~ s!\s+-I\s*\.\S*\s*! !g; # discard relative includes + $in =~ s!(\s+-I\s*)(?i:$solarversion)(\S*)!$1\${SOLARVERSION}$2!og; + # macrofy includes to solver + $in =~ s!\s+-Fo\s*\S+! -Fo$[my_tmp}obj! || die 'bad input: no -Fo'; + $in =~ s!\s+-Zi\s! !; + $in =~ s!\s+-Fd\s*\S+!!; + print STDOUT '#!/bin/sh', "\n"; + print STDOUT + 'my_tmp=${TMPDIR:-/tmp}/`id -u`_$$_include.cc', "\n"; + print STDOUT 'my_pat=`dirname $1`', "\n"; + print STDOUT 'my_fil=`basename $1`', "\n"; + print STDOUT 'my_org=${PWD}', "\n"; + print STDOUT 'cd $my_pat || exit 1', "\n"; + print STDOUT 'my_pat=`pwd`', "\n"; + print STDOUT 'cd $my_org || exit 1', "\n"; + print STDOUT + 'echo "#include \\"${my_pat}/${my_fil}\\"" > ${my_tmp} || exit 1', "\n"; + print STDOUT $in, ' > ${my_tmp}.out 2>&1', "\n"; + print STDOUT 'my_ret=$?', "\n"; + print STDOUT + 'if [ ${my_ret} -ne 0 ] ; then echo $1 >&2 ; cat ${my_tmp}.out >&2 ;', + ' fi', "\n"; + print STDOUT 'unlink ${my_tmp} || exit 1', "\n"; + print STDOUT 'unlink ${my_tmp}.out || exit 1', "\n"; + print STDOUT 'exit ${my_ret}', "\n"; + } +} else { + print STDOUT 'echo \'no testhxx on this platform\'', "\n"; +} diff --git a/soltools/testhxx/makefile.mk b/soltools/testhxx/makefile.mk new file mode 100644 index 000000000000..7a1ab97273e3 --- /dev/null +++ b/soltools/testhxx/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ := .. +PRJNAME := soltools +TARGET := testhxx +LIBTARGET := NO +ENABLE_EXCEPTIONS := TRUE + +CAPTURE_COMMAND = echo +CAPTURE_OUTPUT = > $(MISC)$/testhxx.output && $(TOUCH) $(SLO)$/testhxx.obj + +.INCLUDE: $(PRJ)$/util$/makefile.pmk +.INCLUDE: settings.mk + +SLOFILES = $(SLO)$/testhxx.obj + +.INCLUDE: target.mk + +ALLTAR: $(BIN)$/$(TARGET) + +$(BIN)$/$(TARGET) .ERRREMOVE : $(MISC)$/testhxx.output create.pl + $(PERL) -w create.pl < $(MISC)$/testhxx.output > $@ + chmod +x $@ + +$(MISC)$/testhxx.output: $(SLO)$/testhxx.obj + $(TOUCH) $< + $(TOUCH) $@ diff --git a/soltools/testhxx/testhxx.cxx b/soltools/testhxx/testhxx.cxx new file mode 100644 index 000000000000..63b15276d523 --- /dev/null +++ b/soltools/testhxx/testhxx.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// NO PCH here - breaks the purpose of this file +// MARKER(update_precomp.py): autogen include statement, do not remove +//#include "precompiled_soltools.hxx" + +// This is just a dummy file; see the makefile.mk for the real work. diff --git a/soltools/util/makefile.pmk b/soltools/util/makefile.pmk new file mode 100755 index 000000000000..bf51cf851b4c --- /dev/null +++ b/soltools/util/makefile.pmk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +# find 'makedepend' in own output tree +MAKEDEPEND=$(AUGMENT_LIBRARY_PATH) $(BIN)$/makedepend + +# find 'adjustvisibility' in own output tree +ADJUSTVISIBILITY=$(AUGMENT_LIBRARY_PATH) $(BIN)$/adjustvisibility + +# avoid STLPort +NO_DEFAULT_STL=TRUE +SOLARINC!:=$(subst,/stl$(SPACECHAR),dont_use_stl$(SPACECHAR) $(SOLARINC)) +.IF "$(STLPORT4)" != "" +SOLARINC!:=$(subst,$(STLPORT4)/include/stlport,dont_use_stl$(SPACECHAR) $(SOLARINC)) +SOLARINC!:=$(subst,$(STLPORT4)/stlport,dont_use_stl$(SPACECHAR) $(SOLARINC)) +.ENDIF + +.IF "$(OS)"=="SOLARIS" +# hack due to #i53089# +.IF "$(COMPATH:+"x")" != "$(COMPATH:+"x":s/binx//)" +HELP_COMPATH:=$(subst,/binx, $(COMPATH:+"x")) +.ELSE # "$(COMPATH:+"x")" == "$(COMPATH:s/binx//)/binx" +HELP_COMPATH:=$(COMPATH) +.ENDIF # "$(COMPATH:+"x")" == "$(COMPATH:s/binx//)/binx" +#SOLARINC+=-I$(HELP_COMPATH)/prod/include/CC/stlport4 +#SOLARLIB+=-L$(HELP_COMPATH)/prod/lib/stlport4 +SOLARINC+=-I$(HELP_COMPATH)/prod/include/CC/Cstd +.ENDIF diff --git a/soltools/winunistd/makefile.mk b/soltools/winunistd/makefile.mk new file mode 100644 index 000000000000..9fb4f512c692 --- /dev/null +++ b/soltools/winunistd/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=soltools +TARGET=winunistd +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +.IF "$(GUI)"=="WNT" +.IF "$(COM)"!="GCC" +# provide dummy header for generated sources +$(INCCOM)$/unistd.h : unistd.h + @$(COPY) $< $@ + +.ENDIF # "$(COM)"!="GCC" +.ENDIF # "$(GUI)"=="WNT" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/soltools/winunistd/unistd.h b/soltools/winunistd/unistd.h new file mode 100644 index 000000000000..372e40050187 --- /dev/null +++ b/soltools/winunistd/unistd.h @@ -0,0 +1,4 @@ +/* Dummy unistd.h for the wntmsci3 environment. Required because flex + * generates a lexical scanner which includes <unistd.h> + */ + |