Sat, 15 Feb 2025 23:21:29 +0100
upgrade uwproj and add lib target and README
.hgignore | file | annotate | diff | comparison | revisions | |
Makefile | file | annotate | diff | comparison | revisions | |
README | file | annotate | diff | comparison | revisions | |
configure | file | annotate | diff | comparison | revisions | |
make/configure.vm | file | annotate | diff | comparison | revisions | |
make/project.xml | file | annotate | diff | comparison | revisions | |
make/toolchain.sh | file | annotate | diff | comparison | revisions | |
make/uwproj.xsd | file | annotate | diff | comparison | revisions | |
src/c2html.h | file | annotate | diff | comparison | revisions |
--- a/.hgignore Sat Feb 15 22:56:16 2025 +0100 +++ b/.hgignore Sat Feb 15 23:21:29 2025 +0100 @@ -4,6 +4,7 @@ \.rej$ \.conflict\~$ ^build/.*$ +^dist/.*$ ^nbproject/.*$ .idea/ ^config.mk$
--- a/Makefile Sat Feb 15 22:56:16 2025 +0100 +++ b/Makefile Sat Feb 15 23:21:29 2025 +0100 @@ -29,7 +29,14 @@ include config.mk all: build build/c2html - + +lib: dist/lib dist/include build \ + build/c2html.o build/highlighter.o src/c2html.h src/highlighter.h + $(COPYFILE) LICENSE dist/ + $(COPYFILE) src/c2html.h dist/include/ + $(COPYFILE) src/highlighter.h dist/include/ + $(AR) dist/lib/libc2html.a build/c2html.o build/highlighter.o + build/c2html: build/frontend.o build/highlighter.o build/c2html.o $(CC) -o $@ $(LDFLAGS) $^ @@ -44,9 +51,15 @@ build: $(MKDIR) $@ - + +dist/lib: + $(MKDIR) $@ + +dist/include: + $(MKDIR) $@ + check: all cd test && $(MAKE) -s clean: - $(RMDIR) build + $(RMDIR) build dist
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sat Feb 15 23:21:29 2025 +0100 @@ -0,0 +1,27 @@ +c2html - Formats source code using HTML. + +Build Instructions: + + 1. Download and install UCX (https://ucx.sourceforge.io) + 2. Run ./configure --release + 3. Run make (produces c2html binary in build directory) + 4. Or run make lib (produces include dir and static lib in dist directory) + +Usage of binary file: + c2html [Options] FILE + + Options: + -h Prints help message + -j Highlight Java instead of C source code + -o <output> Output file (stdout, if not specified) + -H <header> Prepend header file + -F <footer> Append footer file + -p Disable highlighting (plain text) + -l Disable line numbers + -V, -v Prints version and exits + +Usage of static library: + + 1. Copy the contents of the dist directory to your project. + 2. Include c2html.h and use one of the functions declared in this header + 3. Link against the libc2html.a
--- a/configure Sat Feb 15 22:56:16 2025 +0100 +++ b/configure Sat Feb 15 23:21:29 2025 +0100 @@ -1,142 +1,7 @@ #!/bin/sh -# create temporary directory -TEMP_DIR=".tmp-`uname -n`" -rm -Rf "$TEMP_DIR" -if mkdir -p "$TEMP_DIR"; then - : -else - echo "Cannot create tmp dir $TEMP_DIR" - echo "Abort" - exit 1 -fi -touch "$TEMP_DIR/options" -touch "$TEMP_DIR/features" -# define standard variables -PREFIX=/usr -EPREFIX= -BINDIR= -SBINDIR= -LIBDIR= -LIBEXECDIR= -DATADIR= -SYSCONFDIR= -SHAREDSTATEDIR= -LOCALSTATEDIR= -INCLUDEDIR= -INFODIR= -MANDIR= - -# custom variables - -# features - -# clean abort -abort_configure() -{ - rm -Rf "$TEMP_DIR" - exit 1 -} - -# help text -printhelp() -{ - echo "Usage: $0 [OPTIONS]..." - cat << __EOF__ -Installation directories: - --prefix=PREFIX path prefix for architecture-independent files - [/usr] - --exec-prefix=EPREFIX path prefix for architecture-dependent files - [PREFIX] - - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR system configuration files [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --mandir=DIR man documentation [DATAROOTDIR/man] - -__EOF__ -} - -# -# parse arguments -# -BUILD_TYPE="default" -for ARG in "$@" -do - case "$ARG" in - "--prefix="*) PREFIX=${ARG#--prefix=} ;; - "--exec-prefix="*) EPREFIX=${ARG#--exec-prefix=} ;; - "--bindir="*) BINDIR=${ARG#----bindir=} ;; - "--sbindir="*) SBINDIR=${ARG#--sbindir=} ;; - "--libdir="*) LIBDIR=${ARG#--libdir=} ;; - "--libexecdir="*) LIBEXECDIR=${ARG#--libexecdir=} ;; - "--datadir="*) DATADIR=${ARG#--datadir=} ;; - "--sysconfdir="*) SYSCONFDIR=${ARG#--sysconfdir=} ;; - "--sharedstatedir="*) SHAREDSTATEDIR=${ARG#--sharedstatedir=} ;; - "--localstatedir="*) LOCALSTATEDIR=${ARG#--localstatedir=} ;; - "--includedir="*) INCLUDEDIR=${ARG#--includedir=} ;; - "--infodir="*) INFODIR=${ARG#--infodir=} ;; - "--mandir"*) MANDIR=${ARG#--mandir} ;; - "--help"*) printhelp; abort_configure ;; - "--debug") BUILD_TYPE="debug" ;; - "--release") BUILD_TYPE="release" ;; - "-"*) echo "unknown option: $ARG"; abort_configure ;; - esac -done - - -# set dir variables -: ${EPREFIX:="$PREFIX"} -: ${BINDIR:="$EPREFIX/bin"} -: ${SBINDIR:="$EPREFIX/sbin"} -: ${LIBDIR:="$EPREFIX/lib"} -: ${LIBEXECDIR:="$EPREFIX/libexec"} -: ${DATADIR:="$PREFIX/share"} -: ${SYSCONFDIR:="$PREFIX/etc"} -: ${SHAREDSTATEDIR:="$PREFIX/com"} -: ${LOCALSTATEDIR:="$PREFIX/var"} -: ${INCLUDEDIR:="$PREFIX/include"} -: ${INFODIR:="$PREFIX/info"} -: ${MANDIR:="$PREFIX/man"} - -# Test for availability of pkg-config -PKG_CONFIG=`command -v pkg-config` -: ${PKG_CONFIG:="false"} - -# Simple uname based platform detection -# $PLATFORM is used for platform dependent dependency selection -OS=`uname -s` -OS_VERSION=`uname -r` -printf "detect platform... " -if [ "$OS" = "SunOS" ]; then - PLATFORM="solaris sunos unix svr4" -fi -if [ "$OS" = "Linux" ]; then - PLATFORM="linux unix" -fi -if [ "$OS" = "FreeBSD" ]; then - PLATFORM="freebsd bsd unix" -fi -if [ "$OS" = "Darwin" ]; then - PLATFORM="macos osx bsd unix" -fi -if echo "$OS" | grep -i "MINGW" > /dev/null; then - PLATFORM="windows mingw" -fi -: ${PLATFORM:="unix"} - -PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` -echo "$PLATFORM_NAME" - +# some utility functions isplatform() { for p in $PLATFORM @@ -157,26 +22,219 @@ done return 0 } +istoolchain() +{ + for t in $TOOLCHAIN + do + if [ "$t" = "$1" ]; then + return 0 + fi + done + return 1 +} +notistoolchain() +{ + for t in $TOOLCHAIN + do + if [ "$t" = "$1" ]; then + return 1 + fi + done + return 0 +} + +# clean abort +abort_configure() +{ + rm -Rf "$TEMP_DIR" + exit 1 +} + +# Test for availability of pkg-config +PKG_CONFIG=`command -v pkg-config` +: ${PKG_CONFIG:="false"} + +# Simple uname based platform detection +# $PLATFORM is used for platform dependent dependency selection +OS=`uname -s` +OS_VERSION=`uname -r` +printf "detect platform... " +if [ "$OS" = "SunOS" ]; then + PLATFORM="solaris sunos unix svr4" +elif [ "$OS" = "Linux" ]; then + PLATFORM="linux unix" +elif [ "$OS" = "FreeBSD" ]; then + PLATFORM="freebsd bsd unix" +elif [ "$OS" = "OpenBSD" ]; then + PLATFORM="openbsd bsd unix" +elif [ "$OS" = "NetBSD" ]; then + PLATFORM="netbsd bsd unix" +elif [ "$OS" = "Darwin" ]; then + PLATFORM="macos osx bsd unix" +elif echo "$OS" | grep -i "MINGW" > /dev/null; then + PLATFORM="windows mingw" +fi +: ${PLATFORM:="unix"} + +PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` +echo "$PLATFORM_NAME" + + +# help text +printhelp() +{ + echo "Usage: $0 [OPTIONS]..." + cat << __EOF__ +Installation directories: + --prefix=PREFIX path prefix for architecture-independent files + [$prefix] + --exec-prefix=EPREFIX path prefix for architecture-dependent files + [PREFIX] + + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR system configuration files [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR run-time variable data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --mandir=DIR man documentation [DATAROOTDIR/man] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + +Build Types: +--debug add extra compile flags for debug builds +--release add extra compile flags for release builds + +__EOF__ +} + +# create temporary directory +TEMP_DIR=".tmp-`uname -n`" +rm -Rf "$TEMP_DIR" +if mkdir -p "$TEMP_DIR"; then + : +else + echo "Cannot create tmp dir $TEMP_DIR" + echo "Abort" + exit 1 +fi +touch "$TEMP_DIR/options" +touch "$TEMP_DIR/features" + +# define standard variables +# also define standard prefix (this is where we will search for config.site) +prefix=/usr +exec_prefix= +bindir= +sbindir= +libdir= +libexecdir= +datarootdir= +datadir= +sysconfdir= +sharedstatedir= +localstatedir= +runstatedir= +includedir= +infodir= +localedir= +mandir= + +# custom variables + +# features + +# +# parse arguments +# +BUILD_TYPE="default" +for ARG in "$@" +do + case "$ARG" in + "--prefix="*) prefix=${ARG#--prefix=} ;; + "--exec-prefix="*) exec_prefix=${ARG#--exec-prefix=} ;; + "--bindir="*) bindir=${ARG#----bindir=} ;; + "--sbindir="*) sbindir=${ARG#--sbindir=} ;; + "--libdir="*) libdir=${ARG#--libdir=} ;; + "--libexecdir="*) libexecdir=${ARG#--libexecdir=} ;; + "--datarootdir="*) datarootdir=${ARG#--datarootdir=} ;; + "--datadir="*) datadir=${ARG#--datadir=} ;; + "--sysconfdir="*) sysconfdir=${ARG#--sysconfdir=} ;; + "--sharedstatedir="*) sharedstatedir=${ARG#--sharedstatedir=} ;; + "--localstatedir="*) localstatedir=${ARG#--localstatedir=} ;; + "--includedir="*) includedir=${ARG#--includedir=} ;; + "--infodir="*) infodir=${ARG#--infodir=} ;; + "--mandir"*) mandir=${ARG#--mandir} ;; + "--localedir"*) localedir=${ARG#--localedir} ;; + "--help"*) printhelp; abort_configure ;; + "--debug") BUILD_TYPE="debug" ;; + "--release") BUILD_TYPE="release" ;; + "-"*) echo "unknown option: $ARG"; abort_configure ;; + esac +done + + + +# set defaults for dir variables +: ${exec_prefix:="$prefix"} +: ${bindir:='${exec_prefix}/bin'} +: ${sbindir:='${exec_prefix}/sbin'} +: ${libdir:='${exec_prefix}/lib'} +: ${libexecdir:='${exec_prefix}/libexec'} +: ${datarootdir:='${prefix}/share'} +: ${datadir:='${datarootdir}'} +: ${sysconfdir:='${prefix}/etc'} +: ${sharedstatedir:='${prefix}/com'} +: ${localstatedir:='${prefix}/var'} +: ${runstatedir:='${localstatedir}/run'} +: ${includedir:='${prefix}/include'} +: ${infodir:='${datarootdir}/info'} +: ${mandir:='${datarootdir}/man'} +: ${localedir:='${datarootdir}/locale'} + +# check if a config.site exists and load it +if [ -n "$CONFIG_SITE" ]; then + # CONFIG_SITE may contain space separated file names + for cs in $CONFIG_SITE; do + printf "loading defaults from $cs... " + . "$cs" + echo ok + done +elif [ -f "$prefix/share/config.site" ]; then + printf "loading site defaults... " + . "$prefix/share/config.site" + echo ok +elif [ -f "$prefix/etc/config.site" ]; then + printf "loading site defaults... " + . "$prefix/etc/config.site" + echo ok +fi # generate vars.mk cat > "$TEMP_DIR/vars.mk" << __EOF__ -PREFIX="$PREFIX" -EPREFIX="$EPREFIX" -BINDIR="$BINDIR" -SBINDIR="$SBINDIR" -LIBDIR="$LIBDIR" -LIBEXECDIR="$LIBEXECDIR" -DATADIR="$DATADIR" -SYSCONFDIR="$SYSCONFDIR" -SHAREDSTATEDIR="$SHAREDSTATEDIR" -LOCALSTATEDIR="$LOCALSTATEDIR" -INCLUDEDIR="$INCLUDEDIR" -INFODIR="$INFODIR" -MANDIR="$MANDIR" +prefix=$prefix +exec_prefix=$exec_prefix +bindir=$bindir +sbindir=$sbindir +libdir=$libdir +libexecdir=$libexecdir +datarootdir=$datarootdir +datadir=$datadir +sysconfdir=$sysconfdir +sharedstatedir=$sharedstatedir +localstatedir=$localstatedir +runstatedir=$runstatedir +includedir=$includedir +infodir=$infodir +mandir=$mandir +localedir=$localedir __EOF__ -sort -u -o "$TEMP_DIR/vars.mk" "$TEMP_DIR/vars.mk" - # toolchain detection utilities . make/toolchain.sh @@ -208,9 +266,17 @@ return 0 } +print_check_msg() +{ + if [ -z "$1" ]; then + shift + printf "$@" + fi +} + dependency_error_ucx() { - printf "checking for ucx... " + print_check_msg "$dep_checked_ucx" "checking for ucx... " # dependency ucx while true do @@ -220,16 +286,18 @@ break fi TEMP_LDFLAGS="$TEMP_LDFLAGS -lucx" - echo yes + print_check_msg "$dep_checked_ucx" "yes\n" + dep_checked_ucx=1 return 1 done - echo no + print_check_msg "$dep_checked_ucx" "no\n" + dep_checked_ucx=1 return 0 } dependency_error_tools() { - printf "checking for tools... " + print_check_msg "$dep_checked_tools" "checking for tools... " # dependency tools platform="unix" while true do @@ -240,28 +308,28 @@ # Dependency: tools RMDIR=rm -fR MKDIR=mkdir -p - +COPYFILE=cp +AR=ar cr __EOF__ - echo yes + print_check_msg "$dep_checked_tools" "yes\n" + dep_checked_tools=1 return 1 done - echo no + print_check_msg "$dep_checked_tools" "no\n" + dep_checked_tools=1 return 0 } - - - # start collecting dependency information echo > "$TEMP_DIR/flags.mk" DEPENDENCIES_FAILED= ERROR=0 # unnamed dependencies -TEMP_CFLAGS= -TEMP_CXXFLAGS= -TEMP_LDFLAGS= +TEMP_CFLAGS="$CFLAGS" +TEMP_CXXFLAGS="$CXXFLAGS" +TEMP_LDFLAGS="$LDFLAGS" while true do while true @@ -278,10 +346,10 @@ # add general dependency flags to flags.mk echo "# general flags" >> "$TEMP_DIR/flags.mk" -if [ -n "${TEMP_CFLAGS}" ]; then +if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi -if [ -n "${TEMP_CXXFLAGS}" ]; then +if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then @@ -297,7 +365,7 @@ # echo >> "$TEMP_DIR/flags.mk" -# Target: default +echo "configuring target: default" echo "# flags for target default" >> "$TEMP_DIR/flags.mk" TEMP_CFLAGS= TEMP_CXXFLAGS= @@ -315,19 +383,27 @@ # Features -if [ -n "${TEMP_CFLAGS}" ]; then +if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi -if [ -n "${TEMP_CXXFLAGS}" ]; then +if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ "$BUILD_TYPE" = "debug" ]; then - echo 'CFLAGS += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" - echo 'CXXFLAGS += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + if [ -n "$lang_c" ]; then + echo 'CFLAGS += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi + if [ -n "$lang_cpp" ]; then + echo 'CXXFLAGS += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi fi if [ "$BUILD_TYPE" = "release" ]; then - echo 'CFLAGS += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" - echo 'CXXFLAGS += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + if [ -n "$lang_c" ]; then + echo 'CFLAGS += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi + if [ -n "$lang_cpp" ]; then + echo 'CXXFLAGS += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi fi if [ -n "${TEMP_LDFLAGS}" ]; then echo "LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" @@ -345,8 +421,8 @@ echo "configure finished" echo echo "Build Config:" -echo " PREFIX: $PREFIX" -echo " TOOLCHAIN: $TOOLCHAIN_NAME" +echo " PREFIX: $prefix" +echo " TOOLCHAIN: $TOOLCHAIN_NAME" echo # generate the config.mk file @@ -359,5 +435,3 @@ write_toolchain_defaults "$TEMP_DIR/toolchain.mk" cat "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk rm -Rf "$TEMP_DIR" - -
--- a/make/configure.vm Sat Feb 15 22:56:16 2025 +0100 +++ b/make/configure.vm Sat Feb 15 23:21:29 2025 +0100 @@ -1,183 +1,8 @@ #!/bin/sh -# create temporary directory -TEMP_DIR=".tmp-`uname -n`" -rm -Rf "$TEMP_DIR" -if mkdir -p "$TEMP_DIR"; then - : -else - echo "Cannot create tmp dir $TEMP_DIR" - echo "Abort" - exit 1 -fi -touch "$TEMP_DIR/options" -touch "$TEMP_DIR/features" - -# define standard variables -PREFIX=/usr -EPREFIX= -BINDIR= -SBINDIR= -LIBDIR= -LIBEXECDIR= -DATADIR= -SYSCONFDIR= -SHAREDSTATEDIR= -LOCALSTATEDIR= -INCLUDEDIR= -INFODIR= -MANDIR= - -# custom variables -#foreach( $var in $vars ) -#if( $var.exec ) -${var.varName}=`${var.value}` -#else -${var.varName}="${var.value}" -#end -#end - -# features -#foreach( $feature in $features ) -#if( ${feature.isDefault()} ) -${feature.getVarName()}=auto -#end -#end - -# clean abort -abort_configure() -{ - rm -Rf "$TEMP_DIR" - exit 1 -} - -# help text -printhelp() -{ - echo "Usage: $0 [OPTIONS]..." - cat << __EOF__ -Installation directories: - --prefix=PREFIX path prefix for architecture-independent files - [/usr] - --exec-prefix=EPREFIX path prefix for architecture-dependent files - [PREFIX] - - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR system configuration files [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --mandir=DIR man documentation [DATAROOTDIR/man] - -#if( $options.size() > 0 ) -Options: - --debug add extra compile flags for debug builds - --release add extra compile flags for release builds -#foreach( $opt in $options ) - --${opt.getArgument()}=${opt.getValuesString()} -#end - -#end -#if( $features.size() > 0 ) -Optional Features: -#foreach( $feature in $features ) -#if( $feature.default ) - --disable-${feature.arg} -#else - --enable-${feature.arg} -#end -#end - -#end -__EOF__ -} - -# -# parse arguments -# -BUILD_TYPE="default" #set( $D = '$' ) -for ARG in "$@" -do - case "$ARG" in - "--prefix="*) PREFIX=${D}{ARG#--prefix=} ;; - "--exec-prefix="*) EPREFIX=${D}{ARG#--exec-prefix=} ;; - "--bindir="*) BINDIR=${D}{ARG#----bindir=} ;; - "--sbindir="*) SBINDIR=${D}{ARG#--sbindir=} ;; - "--libdir="*) LIBDIR=${D}{ARG#--libdir=} ;; - "--libexecdir="*) LIBEXECDIR=${D}{ARG#--libexecdir=} ;; - "--datadir="*) DATADIR=${D}{ARG#--datadir=} ;; - "--sysconfdir="*) SYSCONFDIR=${D}{ARG#--sysconfdir=} ;; - "--sharedstatedir="*) SHAREDSTATEDIR=${D}{ARG#--sharedstatedir=} ;; - "--localstatedir="*) LOCALSTATEDIR=${D}{ARG#--localstatedir=} ;; - "--includedir="*) INCLUDEDIR=${D}{ARG#--includedir=} ;; - "--infodir="*) INFODIR=${D}{ARG#--infodir=} ;; - "--mandir"*) MANDIR=${D}{ARG#--mandir} ;; - "--help"*) printhelp; abort_configure ;; - "--debug") BUILD_TYPE="debug" ;; - "--release") BUILD_TYPE="release" ;; - #foreach( $opt in $options ) - "--${opt.getArgument()}="*) ${opt.getVarName()}=${D}{ARG#--${opt.getArgument()}=} ;; - #end - #foreach( $feature in $features ) - "--enable-${feature.arg}") ${feature.getVarName()}=on ;; - "--disable-${feature.arg}") unset ${feature.getVarName()} ;; - #end - "-"*) echo "unknown option: $ARG"; abort_configure ;; - esac -done - -## Begin unparsed content. ** #[[ -# set dir variables -: ${EPREFIX:="$PREFIX"} -: ${BINDIR:="$EPREFIX/bin"} -: ${SBINDIR:="$EPREFIX/sbin"} -: ${LIBDIR:="$EPREFIX/lib"} -: ${LIBEXECDIR:="$EPREFIX/libexec"} -: ${DATADIR:="$PREFIX/share"} -: ${SYSCONFDIR:="$PREFIX/etc"} -: ${SHAREDSTATEDIR:="$PREFIX/com"} -: ${LOCALSTATEDIR:="$PREFIX/var"} -: ${INCLUDEDIR:="$PREFIX/include"} -: ${INFODIR:="$PREFIX/info"} -: ${MANDIR:="$PREFIX/man"} - -# Test for availability of pkg-config -PKG_CONFIG=`command -v pkg-config` -: ${PKG_CONFIG:="false"} - -# Simple uname based platform detection -# $PLATFORM is used for platform dependent dependency selection -OS=`uname -s` -OS_VERSION=`uname -r` -printf "detect platform... " -if [ "$OS" = "SunOS" ]; then - PLATFORM="solaris sunos unix svr4" -fi -if [ "$OS" = "Linux" ]; then - PLATFORM="linux unix" -fi -if [ "$OS" = "FreeBSD" ]; then - PLATFORM="freebsd bsd unix" -fi -if [ "$OS" = "Darwin" ]; then - PLATFORM="macos osx bsd unix" -fi -if echo "$OS" | grep -i "MINGW" > /dev/null; then - PLATFORM="windows mingw" -fi -: ${PLATFORM:="unix"} - -PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` -echo "$PLATFORM_NAME" - +# some utility functions isplatform() { for p in $PLATFORM @@ -198,30 +23,269 @@ done return 0 } +istoolchain() +{ + for t in $TOOLCHAIN + do + if [ "$t" = "$1" ]; then + return 0 + fi + done + return 1 +} +notistoolchain() +{ + for t in $TOOLCHAIN + do + if [ "$t" = "$1" ]; then + return 1 + fi + done + return 0 +} + +# clean abort +abort_configure() +{ + rm -Rf "$TEMP_DIR" + exit 1 +} + +# Test for availability of pkg-config +PKG_CONFIG=`command -v pkg-config` +: ${PKG_CONFIG:="false"} + +# Simple uname based platform detection +# $PLATFORM is used for platform dependent dependency selection +OS=`uname -s` +OS_VERSION=`uname -r` +printf "detect platform... " +if [ "$OS" = "SunOS" ]; then + PLATFORM="solaris sunos unix svr4" +elif [ "$OS" = "Linux" ]; then + PLATFORM="linux unix" +elif [ "$OS" = "FreeBSD" ]; then + PLATFORM="freebsd bsd unix" +elif [ "$OS" = "OpenBSD" ]; then + PLATFORM="openbsd bsd unix" +elif [ "$OS" = "NetBSD" ]; then + PLATFORM="netbsd bsd unix" +elif [ "$OS" = "Darwin" ]; then + PLATFORM="macos osx bsd unix" +elif echo "$OS" | grep -i "MINGW" > /dev/null; then + PLATFORM="windows mingw" +fi +: ${PLATFORM:="unix"} + +PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` +echo "$PLATFORM_NAME" +]]# + +# help text +printhelp() +{ + echo "Usage: $0 [OPTIONS]..." + cat << __EOF__ +Installation directories: + --prefix=PREFIX path prefix for architecture-independent files + [${D}prefix] + --exec-prefix=EPREFIX path prefix for architecture-dependent files + [PREFIX] + + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR system configuration files [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR run-time variable data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --mandir=DIR man documentation [DATAROOTDIR/man] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + +Build Types: +--debug add extra compile flags for debug builds +--release add extra compile flags for release builds +#if( $options.size() > 0 ) + +Options: +#foreach( $opt in $options ) + --${opt.argument}=${opt.valuesString} +#end +#end +#if( $features.size() > 0 ) + +Optional Features: +#foreach( $feature in $features ) +${feature.helpText} +#end +#end + +__EOF__ +} + +# create temporary directory +TEMP_DIR=".tmp-`uname -n`" +rm -Rf "$TEMP_DIR" +if mkdir -p "$TEMP_DIR"; then + : +else + echo "Cannot create tmp dir $TEMP_DIR" + echo "Abort" + exit 1 +fi +touch "$TEMP_DIR/options" +touch "$TEMP_DIR/features" + +# define standard variables +# also define standard prefix (this is where we will search for config.site) +prefix=/usr +exec_prefix= +bindir= +sbindir= +libdir= +libexecdir= +datarootdir= +datadir= +sysconfdir= +sharedstatedir= +localstatedir= +runstatedir= +includedir= +infodir= +localedir= +mandir= + +# custom variables +#foreach( $cfg in $config ) +if true \ +#if( $cfg.platform ) + && isplatform "${cfg.platform}" \ +#end +#foreach( $np in $cfg.notList ) + && notisplatform "${np}" \ +#end + ; then + #foreach( $var in $cfg.vars ) + #if( $var.exec ) + ${var.varName}=`${var.value}` + #else + ${var.varName}="${var.value}" + #end + #end +fi +#end + +# features +#foreach( $feature in $features ) +#if( ${feature.auto} ) +${feature.varName}=auto +#end +#end + +# +# parse arguments +# +BUILD_TYPE="default" +for ARG in "$@" +do + case "$ARG" in + "--prefix="*) prefix=${D}{ARG#--prefix=} ;; + "--exec-prefix="*) exec_prefix=${D}{ARG#--exec-prefix=} ;; + "--bindir="*) bindir=${D}{ARG#----bindir=} ;; + "--sbindir="*) sbindir=${D}{ARG#--sbindir=} ;; + "--libdir="*) libdir=${D}{ARG#--libdir=} ;; + "--libexecdir="*) libexecdir=${D}{ARG#--libexecdir=} ;; + "--datarootdir="*) datarootdir=${D}{ARG#--datarootdir=} ;; + "--datadir="*) datadir=${D}{ARG#--datadir=} ;; + "--sysconfdir="*) sysconfdir=${D}{ARG#--sysconfdir=} ;; + "--sharedstatedir="*) sharedstatedir=${D}{ARG#--sharedstatedir=} ;; + "--localstatedir="*) localstatedir=${D}{ARG#--localstatedir=} ;; + "--includedir="*) includedir=${D}{ARG#--includedir=} ;; + "--infodir="*) infodir=${D}{ARG#--infodir=} ;; + "--mandir"*) mandir=${D}{ARG#--mandir} ;; + "--localedir"*) localedir=${D}{ARG#--localedir} ;; + "--help"*) printhelp; abort_configure ;; + "--debug") BUILD_TYPE="debug" ;; + "--release") BUILD_TYPE="release" ;; + #foreach( $opt in $options ) + "--${opt.argument}="*) ${opt.varName}=${D}{ARG#--${opt.argument}=} ;; + "--${opt.argument}") echo "option '$ARG' needs a value:"; echo " $ARG=${opt.valuesString}"; abort_configure ;; + #end + #foreach( $feature in $features ) + "--enable-${feature.arg}") ${feature.varName}=on ;; + "--disable-${feature.arg}") unset ${feature.varName} ;; + #end + "-"*) echo "unknown option: $ARG"; abort_configure ;; + esac +done + +## Begin unparsed content. ** +#[[ + +# set defaults for dir variables +: ${exec_prefix:="$prefix"} +: ${bindir:='${exec_prefix}/bin'} +: ${sbindir:='${exec_prefix}/sbin'} +: ${libdir:='${exec_prefix}/lib'} +: ${libexecdir:='${exec_prefix}/libexec'} +: ${datarootdir:='${prefix}/share'} +: ${datadir:='${datarootdir}'} +: ${sysconfdir:='${prefix}/etc'} +: ${sharedstatedir:='${prefix}/com'} +: ${localstatedir:='${prefix}/var'} +: ${runstatedir:='${localstatedir}/run'} +: ${includedir:='${prefix}/include'} +: ${infodir:='${datarootdir}/info'} +: ${mandir:='${datarootdir}/man'} +: ${localedir:='${datarootdir}/locale'} + +# check if a config.site exists and load it +if [ -n "$CONFIG_SITE" ]; then + # CONFIG_SITE may contain space separated file names + for cs in $CONFIG_SITE; do + printf "loading defaults from $cs... " + . "$cs" + echo ok + done +elif [ -f "$prefix/share/config.site" ]; then + printf "loading site defaults... " + . "$prefix/share/config.site" + echo ok +elif [ -f "$prefix/etc/config.site" ]; then + printf "loading site defaults... " + . "$prefix/etc/config.site" + echo ok +fi ]]# ## End of unparsed content ** # generate vars.mk cat > "$TEMP_DIR/vars.mk" << __EOF__ -PREFIX="$PREFIX" -EPREFIX="$EPREFIX" -BINDIR="$BINDIR" -SBINDIR="$SBINDIR" -LIBDIR="$LIBDIR" -LIBEXECDIR="$LIBEXECDIR" -DATADIR="$DATADIR" -SYSCONFDIR="$SYSCONFDIR" -SHAREDSTATEDIR="$SHAREDSTATEDIR" -LOCALSTATEDIR="$LOCALSTATEDIR" -INCLUDEDIR="$INCLUDEDIR" -INFODIR="$INFODIR" -MANDIR="$MANDIR" +prefix=$prefix +exec_prefix=$exec_prefix +bindir=$bindir +sbindir=$sbindir +libdir=$libdir +libexecdir=$libexecdir +datarootdir=$datarootdir +datadir=$datadir +sysconfdir=$sysconfdir +sharedstatedir=$sharedstatedir +localstatedir=$localstatedir +runstatedir=$runstatedir +includedir=$includedir +infodir=$infodir +mandir=$mandir +localedir=$localedir #foreach( $var in $vars ) -${var.varName}="$${var.varName}" +${var.varName}=${D}${var.varName} #end __EOF__ -sort -u -o "$TEMP_DIR/vars.mk" "$TEMP_DIR/vars.mk" - # toolchain detection utilities . make/toolchain.sh @@ -255,12 +319,20 @@ return 0 } -#foreach( $dependency in $namedDependencies ) -dependency_error_${dependency.name}() +print_check_msg() { - printf "checking for ${dependency.name}... " - #foreach( $sub in $dependency.getSubdependencies() ) - # dependency $sub.getFullName() + if [ -z "$1" ]; then + shift + printf "$@" + fi +} + +#foreach( $dependency in $namedDependencies ) +dependency_error_${dependency.id}() +{ + print_check_msg "${D}dep_checked_${dependency.id}" "checking for ${dependency.name}... " + #foreach( $sub in $dependency.subdependencies ) + # dependency $sub.fullName while true do #if( $sub.platform ) @@ -268,8 +340,13 @@ break fi #end - #foreach( $np in $sub.getNotList() ) - if isplatform "${np}"; then + #if( $sub.toolchain ) + if notistoolchain "${sub.toolchain}"; then + break + fi + #end + #foreach( $np in $sub.notList ) + if isplatform "${np}" || istoolchain "${np}"; then break fi #end @@ -315,19 +392,18 @@ $sub.make __EOF__ #end - echo yes + print_check_msg "${D}dep_checked_${dependency.id}" "yes\n" + dep_checked_${dependency.id}=1 return 1 done #end - echo no + print_check_msg "${D}dep_checked_${dependency.id}" "no\n" + dep_checked_${dependency.id}=1 return 0 } #end - - - # start collecting dependency information echo > "$TEMP_DIR/flags.mk" @@ -335,9 +411,9 @@ ERROR=0 #if( $dependencies.size() > 0 ) # unnamed dependencies -TEMP_CFLAGS= -TEMP_CXXFLAGS= -TEMP_LDFLAGS= +TEMP_CFLAGS="$CFLAGS" +TEMP_CXXFLAGS="$CXXFLAGS" +TEMP_LDFLAGS="$LDFLAGS" #foreach( $dependency in $dependencies ) while true do @@ -346,8 +422,13 @@ break fi #end - #foreach( $np in $dependency.getNotList() ) - if isplatform "${np}"; then + #if( $dependency.toolchain ) + if notistoolchain "${dependency.toolchain}"; then + break + fi + #end + #foreach( $np in $dependency.notList ) + if isplatform "${np}" || istoolchain "${np}"; then break fi #end @@ -366,13 +447,15 @@ fi #end #foreach( $pkg in $dependency.pkgconfig ) - printf "checking for pkg-config package $pkg.name... " + print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "checking for pkg-config package $pkg.name... " if test_pkg_config "$pkg.name" "$pkg.atleast" "$pkg.exact" "$pkg.max" ; then - echo yes + print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "yes\n" + dep_pkgconfig_checked_${pkg.id}=1 TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags $pkg.name`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs $pkg.name`" else - echo no + print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "no\n" + dep_pkgconfig_checked_${pkg.id}=1 ERROR=1 break fi @@ -404,10 +487,10 @@ # add general dependency flags to flags.mk echo "# general flags" >> "$TEMP_DIR/flags.mk" -if [ -n "${TEMP_CFLAGS}" ]; then +if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi -if [ -n "${TEMP_CXXFLAGS}" ]; then +if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then @@ -452,10 +535,10 @@ #foreach( $target in $targets ) echo >> "$TEMP_DIR/flags.mk" #if ( $target.name ) -# Target: $target.name +echo "configuring target: $target.name" echo "# flags for target $target.name" >> "$TEMP_DIR/flags.mk" #else -# Target +echo "configuring global target" echo "# flags for unnamed target" >> "$TEMP_DIR/flags.mk" #end TEMP_CFLAGS= @@ -471,28 +554,58 @@ # Features #foreach( $feature in $target.features ) -if [ -n "$${feature.getVarName()}" ]; then +if [ -n "${D}${feature.varName}" ]; then #foreach( $dependency in $feature.dependencies ) # check dependency if dependency_error_$dependency ; then # "auto" features can fail and are just disabled in this case - if [ "$${feature.getVarName()}" = "auto" ]; then - DISABLE_${feature.getVarName()}=1 + if [ "${D}${feature.varName}" = "auto" ]; then + DISABLE_${feature.varName}=1 else DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} " ERROR=1 fi fi #end - if [ -n "$DISABLE_${feature.getVarName()}" ]; then - unset ${feature.getVarName()} + if [ -n "$DISABLE_${feature.varName}" ]; then + unset ${feature.varName} fi fi +if [ -n "${D}${feature.varName}" ]; then + : +#foreach( $def in $feature.defines ) + TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}" + TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}" +#end +#if( $feature.hasMake() ) + cat >> "$TEMP_DIR/make.mk" << __EOF__ +$feature.make +__EOF__ +#end +else + : +#foreach( $def in $feature.disabled.defines ) + TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}" + TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}" +#end +#if( $feature.disabled.hasMake() ) + cat >> "$TEMP_DIR/make.mk" << __EOF__ +$feature.disabled.make +__EOF__ +#end +#foreach( $dependency in $feature.disabled.dependencies ) + if dependency_error_$dependency ; then + DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} " + ERROR=1 + fi +#end +fi #end #foreach( $opt in $target.options ) # Option: --${opt.argument} -if [ -z ${D}${opt.getVarName()} ]; then +if [ -z "${D}${opt.varName}" ]; then + echo "auto-detecting option '${opt.argument}'" SAVED_ERROR="$ERROR" SAVED_DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED" ERROR=1 @@ -515,41 +628,57 @@ done if [ $ERROR -ne 0 ]; then SAVED_ERROR=1 + SAVED_DEPENDENCIES_FAILED="option '${opt.argument}' $SAVED_DEPENDENCIES_FAILED" fi ERROR="$SAVED_ERROR" DEPENDENCIES_FAILED="$SAVED_DEPENDENCIES_FAILED" else + echo "checking option ${opt.argument} = ${D}${opt.varName}" if false; then false #foreach( $optval in $opt.values ) - elif [ "${D}${opt.getVarName()}" = "${optval.value}" ]; then - echo " ${opt.argument}: ${D}${opt.getVarName()}" >> $TEMP_DIR/options + elif [ "${D}${opt.varName}" = "${optval.value}" ]; then + echo " ${opt.argument}: ${D}${opt.varName}" >> $TEMP_DIR/options if $optval.func ; then : else ERROR=1 + DEPENDENCIES_FAILED="option '${opt.argument}' $DEPENDENCIES_FAILED" fi #end + else + echo + echo "Invalid option value - usage:" + echo " --${opt.argument}=${opt.valuesString}" + abort_configure fi fi #end -if [ -n "${TEMP_CFLAGS}" ]; then - echo "${target.getCFlags()} += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" +if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then + echo "${target.cFlags} += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi -if [ -n "${TEMP_CXXFLAGS}" ]; then - echo "${target.getCXXFlags()} += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" +if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then + echo "${target.cxxFlags} += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ "$BUILD_TYPE" = "debug" ]; then - echo '${target.getCFlags()} += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" - echo '${target.getCXXFlags()} += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + if [ -n "$lang_c" ]; then + echo '${target.cFlags} += ${DEBUG_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi + if [ -n "$lang_cpp" ]; then + echo '${target.cxxFlags} += ${DEBUG_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi fi if [ "$BUILD_TYPE" = "release" ]; then - echo '${target.getCFlags()} += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" - echo '${target.getCXXFlags()} += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + if [ -n "$lang_c" ]; then + echo '${target.cFlags} += ${RELEASE_CC_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi + if [ -n "$lang_cpp" ]; then + echo '${target.cxxFlags} += ${RELEASE_CXX_FLAGS}' >> "$TEMP_DIR/flags.mk" + fi fi if [ -n "${TEMP_LDFLAGS}" ]; then - echo "${target.getLDFlags()} += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" + echo "${target.ldFlags} += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" fi #end @@ -565,8 +694,8 @@ echo "configure finished" echo echo "Build Config:" -echo " PREFIX: $PREFIX" -echo " TOOLCHAIN: $TOOLCHAIN_NAME" +echo " PREFIX: $prefix" +echo " TOOLCHAIN: $TOOLCHAIN_NAME" #if ( $options.size() > 0 ) echo "Options:" cat "$TEMP_DIR/options" @@ -574,7 +703,7 @@ #if ( $features.size() > 0 ) echo "Features:" #foreach( $feature in $features ) -if [ -n "$${feature.getVarName()}" ]; then +if [ -n "${D}${feature.varName}" ]; then echo " $feature.name: on" else echo " $feature.name: off" @@ -593,5 +722,3 @@ write_toolchain_defaults "$TEMP_DIR/toolchain.mk" cat "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk rm -Rf "$TEMP_DIR" - -
--- a/make/project.xml Sat Feb 15 22:56:16 2025 +0100 +++ b/make/project.xml Sat Feb 15 23:21:29 2025 +0100 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://unixwork.de/uwproj"> +<project xmlns="http://unixwork.de/uwproj" version="0.3"> <dependency> <lang>c</lang> </dependency> @@ -7,6 +7,8 @@ <make> RMDIR=rm -fR MKDIR=mkdir -p +COPYFILE=cp +AR=ar cr </make> </dependency> <dependency name="ucx">
--- a/make/toolchain.sh Sat Feb 15 22:56:16 2025 +0100 +++ b/make/toolchain.sh Sat Feb 15 23:21:29 2025 +0100 @@ -3,64 +3,74 @@ # toolchain detection # -C_COMPILERS="gcc clang suncc cc" -CPP_COMPILERS="g++ clang++ sunCC CC" +if isplatform "bsd" && notisplatform "openbsd"; then + C_COMPILERS="clang gcc cc" + CPP_COMPILERS="clang++ g++ CC" +else + C_COMPILERS="gcc clang suncc cc" + CPP_COMPILERS="g++ clang++ sunCC CC" +fi +unset TOOLCHAIN unset TOOLCHAIN_NAME unset TOOLCHAIN_CC unset TOOLCHAIN_CXX check_c_compiler() { - cat > "$TEMP_DIR/test.c" << __EOF__ + cat > "$TEMP_DIR/test.c" << __EOF__ /* test file */ #include <stdio.h> int main(int argc, char **argv) { -#if defined(__clang__) - printf("clang\n"); +#if defined(_MSC_VER) + printf("msc\n"); +#elif defined(__clang__) + printf("clang gnuc\n"); #elif defined(__GNUC__) - printf("gcc\n"); + printf("gcc gnuc\n"); #elif defined(__sun) - printf("suncc\n"); + printf("suncc\n"); #else - printf("unknown\n"); + printf("unknown\n"); #endif - return 0; + return 0; } __EOF__ - rm -f "$TEMP_DIR/checkcc" - $1 -o "$TEMP_DIR/checkcc" $CFLAGS $LDFLAGS "$TEMP_DIR/test.c" 2> /dev/null + rm -f "$TEMP_DIR/checkcc" + $1 -o "$TEMP_DIR/checkcc" $CFLAGS $LDFLAGS "$TEMP_DIR/test.c" 2> /dev/null } check_cpp_compiler() { - cat > "$TEMP_DIR/test.cpp" << __EOF__ + cat > "$TEMP_DIR/test.cpp" << __EOF__ /* test file */ #include <iostream> int main(int argc, char **argv) { -#if defined(__clang__) - std::cout << "clang" << std::endl; +#if defined(_MSC_VER) + std::cout << "msc" << std::endl; +#elif defined(__clang__) + std::cout << "clang gnuc" << std::endl; #elif defined(__GNUC__) - std::cout << "gcc" << std::endl; + std::cout << "gcc gnuc" << std::endl; #elif defined(__sun) - std::cout << "suncc" << std::endl; + std::cout << "suncc" << std::endl; #else - std::cout << "cc" << std::endl; + std::cout << "cc" << std::endl; #endif - return 0; + return 0; } __EOF__ - rm -f "$TEMP_DIR/checkcc" - $1 -o "$TEMP_DIR/checkcc" $CXXFLAGS $LDFLAGS "$TEMP_DIR/test.cpp" 2> /dev/null + rm -f "$TEMP_DIR/checkcc" + $1 -o "$TEMP_DIR/checkcc" $CXXFLAGS $LDFLAGS "$TEMP_DIR/test.cpp" 2> /dev/null } create_libtest_source() { # $1: filename # $2: optional include - cat > "$TEMP_DIR/$1" << __EOF__ + cat > "$TEMP_DIR/$1" << __EOF__ /* libtest file */ int main(int argc, char **argv) { - return 0; + return 0; } __EOF__ if [ -n "$2" ]; then @@ -77,7 +87,7 @@ fi create_libtest_source "test.c" "$2" rm -f "$TEMP_DIR/checklib" - $TOOLCHAIN_CC -o "$TEMP_DIR/checklib" $CFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.c" 2> /dev/null + $TOOLCHAIN_CC -o "$TEMP_DIR/checklib" $CFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.c" 2> /dev/null } check_cpp_lib() @@ -87,20 +97,20 @@ if [ -z "$TOOLCHAIN_CXX" ]; then return 1 fi - create_libtest_source "test.cpp" "$2" + create_libtest_source "test.cpp" "$2" rm -f "$TEMP_DIR/checklib" - $TOOLCHAIN_CXX -o "$TEMP_DIR/checklib" $CXXFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.cpp" 2> /dev/null + $TOOLCHAIN_CXX -o "$TEMP_DIR/checklib" $CXXFLAGS $LDFLAGS "-l$1" "$TEMP_DIR/test.cpp" 2> /dev/null } check_lib() { # $1: libname # $2: optional include - if [ -n "$TOOLCHAIN_CC" ]; then - check_c_lib "$1" "$2" - elif [ -n "$TOOLCHAIN_CXX" ]; then - check_cpp_lib "$1" "$2" - fi + if [ -n "$TOOLCHAIN_CC" ]; then + check_c_lib "$1" "$2" + elif [ -n "$TOOLCHAIN_CXX" ]; then + check_cpp_lib "$1" "$2" + fi } detect_c_compiler() @@ -112,7 +122,8 @@ if [ -n "$CC" ]; then if check_c_compiler "$CC"; then TOOLCHAIN_CC=$CC - TOOLCHAIN_NAME=`"$TEMP_DIR/checkcc"` + TOOLCHAIN=`"$TEMP_DIR/checkcc"` + TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -` echo "$CC" return 0 else @@ -124,7 +135,8 @@ do if check_c_compiler "$COMP"; then TOOLCHAIN_CC=$COMP - TOOLCHAIN_NAME=`"$TEMP_DIR/checkcc"` + TOOLCHAIN=`"$TEMP_DIR/checkcc"` + TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -` echo "$COMP" return 0 fi @@ -144,7 +156,8 @@ if [ -n "$CXX" ]; then if check_cpp_compiler "$CXX"; then TOOLCHAIN_CXX=$CXX - TOOLCHAIN_NAME=`"$TEMP_DIR/checkcc"` + TOOLCHAIN=`"$TEMP_DIR/checkcc"` + TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -` echo "$CXX" return 0 else @@ -156,7 +169,8 @@ do if check_cpp_compiler "$COMP"; then TOOLCHAIN_CXX=$COMP - TOOLCHAIN_NAME=`"$TEMP_DIR/checkcc"` + TOOLCHAIN=`"$TEMP_DIR/checkcc"` + TOOLCHAIN_NAME=`echo "$TOOLCHAIN" | cut -f1 -d' ' -` echo "$COMP" return 0 fi
--- a/make/uwproj.xsd Sat Feb 15 22:56:16 2025 +0100 +++ b/make/uwproj.xsd Sat Feb 15 23:21:29 2025 +0100 @@ -3,25 +3,63 @@ xmlns="http://unixwork.de/uwproj" targetNamespace="http://unixwork.de/uwproj" elementFormDefault="qualified" - version="0.1" + version="0.3" > <xs:element name="project" type="ProjectType"/> <xs:complexType name="ProjectType"> + <xs:annotation> + <xs:documentation> + The root element of an uwproj project. + Consists of an optional <code>config</code> element + and an arbitrary number of <code>dependency</code> + and <code>target</code> elements. + </xs:documentation> + </xs:annotation> <xs:sequence> - <xs:element name="config" type="ConfigType" minOccurs="0"/> + <xs:element name="config" type="ConfigType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="dependency" type="DependencyType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="target" type="TargetType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> + <xs:attribute name="version" type="xs:string" use="required" /> </xs:complexType> <xs:complexType name="ConfigType"> + <xs:annotation> + <xs:documentation> + <p> + The configuration section. + Consists of an arbitrary number of <code>var</code> elements. + </p> + <p> + The optional <code>platform</code> attribute may specify a <em>single</em> platform identifier and + the optional <code>not</code> attribute may specify a comma-separated list of platform identifiers. + The configure script shall skip this config declaration if the detected platform is not matching + the filter specification of these attributes. + </p> + </xs:documentation> + </xs:annotation> <xs:sequence> <xs:element name="var" type="ConfigVarType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> + <xs:attribute name="platform" type="xs:string"/> + <xs:attribute name="not" type="xs:string"/> </xs:complexType> <xs:complexType name="ConfigVarType"> + <xs:annotation> + <xs:documentation> + The definition of a configuration variable. + <p> + Configuration variables are supposed to be used in the configure script and are also + written to the resulting config file (in contrast to make variables, which are only + written to the config file). + The <code>name</code> attribute is mandatory, the value is defined by the text body of the element. + The optional Boolean <code>exec</code> attribute (false by default) controls, whether the entire + definition is automatically executed under command substitution. + </p> + </xs:documentation> + </xs:annotation> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="name" type="xs:string" use="required"/> @@ -31,6 +69,13 @@ </xs:complexType> <xs:complexType name="PkgConfigType"> + <xs:annotation> + <xs:documentation> + Instructs configure to invoke <code>pkg-config</code>, if present on the system, to determine + compiler and linker flags. The text body of this element defines the package name to search. + To constrain the allowed versions, use the attributes <code>atleast, exact, max</code>. + </xs:documentation> + </xs:annotation> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="atleast" type="xs:string"/> @@ -41,6 +86,12 @@ </xs:complexType> <xs:simpleType name="LangType"> + <xs:annotation> + <xs:documentation> + Requests a compiler for the specified language. Allowed values are + c, cpp. + </xs:documentation> + </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration value="c"/> <xs:enumeration value="cpp"/> @@ -48,21 +99,57 @@ </xs:simpleType> <xs:complexType name="DependencyType"> + <xs:annotation> + <xs:documentation> + Declares a dependency. + <p> + If the optional <code>name</code> attribute is omitted, the dependency is global + and must be satisfied, otherwise configuration shall fail. + A <em>named dependency</em> can be referenced by a target (or is implicitly referenced + by the default target, if no targets are specified). + Multiple declarations for the same named dependency may exist, in which case each declaration + is checked one after another, until one block is satisfied. The result of the first satisfied + dependency declaration is supposed to be applied to the config file. + </p> + <p> + The optional <code>platform</code> attribute may specify a <em>single</em> platform identifier and + the optional <code>toolchain</code> attribute may specify a <em>single</em> toolchain. + The optional <code>not</code> attribute may specify a comma-separated list of platform and/or + toolchain identifiers. + The configure script shall skip this dependency declaration if the detected platform and toolchain + is not matching the filter specification of these attributes. + </p> + </xs:documentation> + </xs:annotation> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="lang" type="LangType"/> <xs:element name="cflags" type="FlagsType"/> <xs:element name="cxxflags" type="FlagsType"/> <xs:element name="ldflags" type="FlagsType"/> <xs:element name="pkgconfig" type="PkgConfigType"/> - <xs:element name="test" type="xs:string"/> - <xs:element name="make" type="xs:string"/> + <xs:element name="test" type="xs:string"> + <xs:annotation> + <xs:documentation> + Specifies a custom command that shall be executed to test whether this dependency is satisfied. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="make" type="MakeVarType"/> </xs:choice> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="platform" type="xs:string"/> + <xs:attribute name="toolchain" type="xs:string"/> <xs:attribute name="not" type="xs:string"/> </xs:complexType> <xs:complexType name="FlagsType"> + <xs:annotation> + <xs:documentation> + Instructs configure to append the contents of the element's body to the respective flags variable. + If the optional <code>exec</code> flag is set to <code>true</code>, the contents are supposed to be + executed under command substitution <em>at configuration time</em> before they are applied. + </xs:documentation> + </xs:annotation> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="exec" type="xs:boolean" default="false"/> @@ -71,6 +158,25 @@ </xs:complexType> <xs:complexType name="TargetType"> + <xs:annotation> + <xs:documentation> + Declares a build target that is supposed to be configured. + <p> + If no build target is declared explicitly, an implicit default + target is generated, which has the <code>alldependencies</code> + flag set. + </p> + <p> + The optional <code>name</code> attribute is also used to generate a prefix + for the compiler and linker flags variables. + Furthermore, a target may consist of an arbitrary number of <code>feature</code>, + <code>option</code>, and <code>define</code> elements. + Named dependencies can be listed (separated by comma) in the <code>dependencies</code> + element. If this target shall use <em>all</em> available named dependencies, the empty + element <code>alldependencies</code> can be used as a shortcut. + </p> + </xs:documentation> + </xs:annotation> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="feature" type="FeatureType"/> <xs:element name="option" type="OptionType"/> @@ -84,8 +190,33 @@ </xs:complexType> <xs:complexType name="FeatureType"> + <xs:annotation> + <xs:documentation> + Declares an optional feature, that can be enabled during configuration, if all + <code>dependencies</code> are satisfied. + If a feature is enabled, all <code>define</code> and <code>make</code> definitions are + supposed to be applied to the config file. + If a feature is disabled, an optional <code>disabled</code> element may specify which + <code>define</code> and <code>make</code> definitions are supposed to be applied. + There might also be <code>dependencies</code> when the feature is disabled (e.g. specifying a fallback). + In case the optional <code>default</code> attribute is set to true, the feature is enabled by default + and is supposed to be automatically disabled (without error) when the dependencies are not satisfied. + The name that is supposed to be used for the --enable and --disable arguments can be optionally + specified with the <code>arg</code> attribute. Otherwise, the <code>name</code> is used by default. + Optionally, a description for the help text of the resulting configure script can be specified by + adding a <code>desc</code> element. + </xs:documentation> + </xs:annotation> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="TargetDataGroup"/> + <xs:element name="desc" type="xs:string"/> + <xs:element name="disabled"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="TargetDataGroup"/> + </xs:choice> + </xs:complexType> + </xs:element> </xs:choice> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="arg" type="xs:string"/> @@ -93,14 +224,31 @@ </xs:complexType> <xs:complexType name="OptionType"> + <xs:annotation> + <xs:documentation> + Declares a configuration option. + The option argument name is specified with the <code>arg</code> attribute. + Then, the children of this element specify possible <code>values</code> by defining the conditions + (in terms of dependencies) and effects (in terms of defines and make variables) of each value. + Finally, a set of <code>default</code>s is specified which supposed to automagically select the most + appropriate value for a specific platform under the available dependencies (in case the option is not + explicitly specified by using the command line argument). + </xs:documentation> + </xs:annotation> <xs:sequence> <xs:element name="value" type="OptionValueType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="default" type="OptionDefaultType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> - <xs:attribute name="arg" type="xs:string"/> + <xs:attribute name="arg" type="xs:string" use="required"/> </xs:complexType> <xs:complexType name="OptionValueType"> + <xs:annotation> + <xs:documentation> + Declares a possible value for the option (in the <code>str</code> attribute) and + the conditions (<code>dependencies</code>) and effects, the value has. + </xs:documentation> + </xs:annotation> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="TargetDataGroup"/> </xs:choice> @@ -108,6 +256,14 @@ </xs:complexType> <xs:complexType name="OptionDefaultType"> + <xs:annotation> + <xs:documentation> + Specifies a default value for this option. Multiple default values can be specified, in which case + they are checked one after another for availability. With the optional <code>platform</code> attribute, + the default value can be constrained to a <em>single</em> specific platform and is supposed to be + skipped by configure, when this platform is not detected. + </xs:documentation> + </xs:annotation> <xs:attribute name="value" type="xs:string" use="required"/> <xs:attribute name="platform" type="xs:string"/> </xs:complexType> @@ -116,16 +272,37 @@ <xs:choice> <xs:element name="define" type="DefineType" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="dependencies" type="DependenciesType" minOccurs="0" maxOccurs="unbounded"/> - <xs:element name="make" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="make" type="MakeVarType" minOccurs="0" maxOccurs="unbounded"/> </xs:choice> </xs:group> <xs:complexType name="DefineType"> + <xs:annotation> + <xs:documentation> + Specifies C/C++ pre-processor definitions that are supposed to + be appended to the compiler flags, if supported. + (Note: for example, Fortran also supports C/C++ style pre-processor definitions under + certain circumstances) + </xs:documentation> + </xs:annotation> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="value" type="xs:string"/> </xs:complexType> <xs:simpleType name="DependenciesType"> + <xs:annotation> + <xs:documentation>A comma-separated list of named dependencies.</xs:documentation> + </xs:annotation> <xs:restriction base="xs:string"/> </xs:simpleType> -</xs:schema> \ No newline at end of file + + <xs:simpleType name="MakeVarType"> + <xs:annotation> + <xs:documentation> + The text contents in the body of this element are supposed to be appended literally + to the config file without prior processing. + </xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"/> + </xs:simpleType> +</xs:schema>
--- a/src/c2html.h Sat Feb 15 22:56:16 2025 +0100 +++ b/src/c2html.h Sat Feb 15 23:21:29 2025 +0100 @@ -39,8 +39,8 @@ #endif #define VERSION_MAJOR 3 -#define VERSION_MINOR 1 -#define VERSION_DEVELOP 0 /* set this to zero for release version */ +#define VERSION_MINOR 2 +#define VERSION_DEVELOP 1 /* set this to zero for release version */ /** * Writes the formatted source data to the output buffer.