diff options
author | Santurysim <petershh@disroot.org> | 2022-06-18 13:08:06 +0300 |
---|---|---|
committer | Santurysim <petershh@disroot.org> | 2022-06-18 13:08:06 +0300 |
commit | 66bb9b9687948b847ee707759d940af7ae6e6748 (patch) | |
tree | 87875bbed315287d2ed571a75ae8df24635041c4 | |
download | shh-portable-utils-66bb9b9687948b847ee707759d940af7ae6e6748.tar.xz |
Initial commit
-rw-r--r-- | COPYING | 22 | ||||
-rw-r--r-- | Makefile | 149 | ||||
-rw-r--r-- | README.md | 52 | ||||
-rw-r--r-- | config.mak | 43 | ||||
-rwxr-xr-x | configure | 471 | ||||
-rw-r--r-- | meson.build | 7 | ||||
-rw-r--r-- | package/deps-build | 1 | ||||
-rw-r--r-- | package/deps.mak | 22 | ||||
-rw-r--r-- | package/info | 4 | ||||
-rw-r--r-- | package/modes | 5 | ||||
-rw-r--r-- | package/targets.mak | 8 | ||||
-rw-r--r-- | src/include/shh-portable-utils/config.h | 13 | ||||
-rw-r--r-- | src/meson.build | 1 | ||||
-rw-r--r-- | src/shh-portable-utils/basename.c | 36 | ||||
-rw-r--r-- | src/shh-portable-utils/cat.c | 70 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/basename | 0 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/cat | 1 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/false | 0 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/true | 0 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/uniq | 1 | ||||
-rw-r--r-- | src/shh-portable-utils/deps-exe/uniq.c | 0 | ||||
-rw-r--r-- | src/shh-portable-utils/false.c | 4 | ||||
-rw-r--r-- | src/shh-portable-utils/meson.build | 5 | ||||
-rw-r--r-- | src/shh-portable-utils/true.c | 4 | ||||
-rw-r--r-- | src/shh-portable-utils/uniq.c | 185 | ||||
-rwxr-xr-x | tools/gen-deps.sh | 93 | ||||
-rwxr-xr-x | tools/install.sh | 64 |
27 files changed, 1261 insertions, 0 deletions
@@ -0,0 +1,22 @@ +Copyright 2022, Peter Shkenev + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. + +This software uses code from skalibs. + +Copyright (c) 2011-2022 Laurent Bercot <ska-skaware@skarnet.org> diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cd6c7f0 --- /dev/null +++ b/Makefile @@ -0,0 +1,149 @@ +# +# This Makefile requires GNU make. +# +# Do not make changes here. +# Use the included .mak files. +# + +it: all + +make_need := 3.81 +ifeq "" "$(strip $(filter $(make_need), $(firstword $(sort $(make_need) $(MAKE_VERSION)))))" +fail := $(error Your make ($(MAKE_VERSION)) is too old. You need $(make_need) or newer) +endif + +CC = $(error Please use ./configure first) + +STATIC_LIBS := +SHARED_LIBS := +INTERNAL_LIBS := +EXTRA_TARGETS := +LIB_DEFS := + +define library_definition +LIB$(firstword $(subst =, ,$(1))) := lib$(lastword $(subst =, ,$(1))).$(if $(DO_ALLSTATIC),a,so).xyzzy +ifdef DO_SHARED +SHARED_LIBS += lib$(lastword $(subst =, ,$(1))).so.xyzzy +endif +ifdef DO_STATIC +STATIC_LIBS += lib$(lastword $(subst =, ,$(1))).a.xyzzy +endif +endef + +-include config.mak +include package/targets.mak + +$(foreach var,$(LIB_DEFS),$(eval $(call library_definition,$(var)))) + +include package/deps.mak + +version_m := $(basename $(version)) +version_M := $(basename $(version_m)) +version_l := $(basename $(version_M)) +CPPFLAGS_ALL := $(CPPFLAGS_AUTO) $(CPPFLAGS) +CFLAGS_ALL := $(CFLAGS_AUTO) $(CFLAGS) +ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) +CFLAGS_SHARED := -fPIC +else +CFLAGS_SHARED := +endif +LDFLAGS_ALL := $(LDFLAGS_AUTO) $(LDFLAGS) +AR := $(CROSS_COMPILE)ar +RANLIB := $(CROSS_COMPILE)ranlib +STRIP := $(CROSS_COMPILE)strip +INSTALL := ./tools/install.sh + +ALL_BINS := $(LIBEXEC_TARGETS) $(BIN_TARGETS) +ALL_LIBS := $(SHARED_LIBS) $(STATIC_LIBS) $(INTERNAL_LIBS) +ALL_INCLUDES := $(wildcard src/include/$(package)/*.h) + +all: $(ALL_LIBS) $(ALL_BINS) $(ALL_INCLUDES) + +clean: + @exec rm -f $(ALL_LIBS) $(ALL_BINS) $(wildcard src/*/*.o src/*/*.lo) $(EXTRA_TARGETS) + +distclean: clean + @exec rm -f config.mak src/include/$(package)/config.h + +tgz: distclean + @. package/info && \ + rm -rf /tmp/$$package-$$version && \ + cp -a . /tmp/$$package-$$version && \ + cd /tmp && \ + tar -zpcv --owner=0 --group=0 --numeric-owner --exclude=.git* -f /tmp/$$package-$$version.tar.gz $$package-$$version && \ + exec rm -rf /tmp/$$package-$$version + +strip: $(ALL_LIBS) $(ALL_BINS) +ifneq ($(strip $(STATIC_LIBS)),) + exec $(STRIP) -x -R .note -R .comment $(STATIC_LIBS) +endif +ifneq ($(strip $(ALL_BINS)$(SHARED_LIBS)),) + exec $(STRIP) -R .note -R .comment $(ALL_BINS) $(SHARED_LIBS) +endif + +install: install-dynlib install-libexec install-bin install-lib install-include +install-dynlib: $(SHARED_LIBS:lib%.so.xyzzy=$(DESTDIR)$(dynlibdir)/lib%.so) +install-libexec: $(LIBEXEC_TARGETS:%=$(DESTDIR)$(libexecdir)/%) +install-bin: $(BIN_TARGETS:%=$(DESTDIR)$(bindir)/%) +install-lib: $(STATIC_LIBS:lib%.a.xyzzy=$(DESTDIR)$(libdir)/lib%.a) +install-include: $(ALL_INCLUDES:src/include/$(package)/%.h=$(DESTDIR)$(includedir)/$(package)/%.h) +install-data: $(ALL_DATA:src/etc/%=$(DESTDIR)$(datadir)/%) + +ifneq ($(exthome),) + +$(DESTDIR)$(exthome): $(DESTDIR)$(home) + exec $(INSTALL) -l $(notdir $(home)) $(DESTDIR)$(exthome) + +update: $(DESTDIR)$(exthome) + +global-links: $(DESTDIR)$(exthome) $(SHARED_LIBS:lib%.so.xyzzy=$(DESTDIR)$(sproot)/library.so/lib%.so.$(version_M)) $(BIN_TARGETS:%=$(DESTDIR)$(sproot)/command/%) + +$(DESTDIR)$(sproot)/command/%: $(DESTDIR)$(home)/command/% + exec $(INSTALL) -D -l ..$(subst $(sproot),,$(exthome))/command/$(<F) $@ + +$(DESTDIR)$(sproot)/library.so/lib%.so.$(version_M): $(DESTDIR)$(dynlibdir)/lib%.so.$(version_M) + exec $(INSTALL) -D -l ..$(subst $(sproot),,$(exthome))/library.so/$(<F) $@ + +.PHONY: update global-links + +endif + +$(DESTDIR)$(datadir)/%: src/etc/% + exec $(INSTALL) -D -m 644 $< $@ + +$(DESTDIR)$(dynlibdir)/lib%.so $(DESTDIR)$(dynlibdir)/lib%.so.$(version_M): lib%.so.xyzzy + $(INSTALL) -D -m 755 $< $@.$(version) && \ + $(INSTALL) -l $(@F).$(version) $@.$(version_M) && \ + exec $(INSTALL) -l $(@F).$(version_M) $@ + +$(DESTDIR)$(libexecdir)/% $(DESTDIR)$(bindir)/%: % package/modes + exec $(INSTALL) -D -m 600 $< $@ + grep -- ^$(@F) < package/modes | { read name mode owner && \ + if [ x$$owner != x ] ; then chown -- $$owner $@ ; fi && \ + chmod $$mode $@ ; } + +$(DESTDIR)$(libdir)/lib%.a: lib%.a.xyzzy + exec $(INSTALL) -D -m 644 $< $@ + +$(DESTDIR)$(includedir)/$(package)/%.h: src/include/$(package)/%.h + exec $(INSTALL) -D -m 644 $< $@ + +%.o: %.c + exec $(CC) $(CPPFLAGS_ALL) $(CFLAGS_ALL) -c -o $@ $< + +%.lo: %.c + exec $(CC) $(CPPFLAGS_ALL) $(CFLAGS_ALL) $(CFLAGS_SHARED) -c -o $@ $< + +$(ALL_BINS): + exec $(CC) -o $@ $(CFLAGS_ALL) $(LDFLAGS_ALL) $(LDFLAGS_NOSHARED) $^ $(EXTRA_LIBS) $(LDLIBS) + +lib%.a.xyzzy: + exec $(AR) rc $@ $^ + exec $(RANLIB) $@ + +lib%.so.xyzzy: + exec $(CC) -o $@ $(CFLAGS_ALL) $(CFLAGS_SHARED) $(LDFLAGS_ALL) $(LDFLAGS_SHARED) -Wl,-soname,$(patsubst lib%.so.xyzzy,lib%.so.$(version_M),$@) $^ $(EXTRA_LIBS) $(LDLIBS) + +.PHONY: it all clean distclean tgz strip install install-dynlib install-bin install-lib install-include install-data + +.DELETE_ON_ERROR: diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa442d2 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# shh-portable-utils + +Shhh! + +This project aims to create a set of small, correct and POSIX-conformant set of +default utilities for the UNIX system, like echo and chmod. + +Powered by skalibs. +Works best with musl libc. + +## Dependencies +- POSIX system with default C programming environment. +- GNU Make, version 3.81 or later; +- [skalibs](https://skarnet.org/software/skalibs). This is a build-time + dependency and a run-time dependency if you do not link binaries statically. + +## Compilation and installation +``` +./configure && make && sudo make install +``` +will do. Alternatively, it can be built with muon build system and samurai (not +guaranteed to work!): +``` +muon setup build && samu -C build && muon install -C build +``` + +## License +This is free software licensed under MIT license. See COPYING for details. + +## TODO +- Draw the rest of the freaking owl! +- Create shh-linux-utils, a set of base utilities that cannot be implemented in + a nonportable fashion. This utilities are going to be Linux-specific, I + primarily use Linux distros and BSDs are unlikely to adopt them. +- I18n. I believe that utilities should be able to display text in the user's + native language. But, since language support drastically increases size of + programs, there should be a possibility to disable this at compile-tume. +- Documentation, obviously. For now, POSIX will do. +- Move repository to another server. + +## Why +- As far as the author knows, none of existing projects provide POSIX-conformant + set of utilities, while there is a demand for such set. +- Existing projects do not satisfy the author for some reasons: + - [GNU Coreutils](https//www.gnu.prg/software/coreutils): well, this is GNU, + which is translated as 'bloated, inefficient, insecure'. + - [Busybox](https://busybox.net), [Toybox](https://landley.net/toybox): + these projects provide multicall binaries. This approach has its + advantages, but it also has its drawbacks. The goal of shh-utils is + provide standalone binaries. + - [sbase](https://core.suckless.org/sbase/): Idk, need to check this out. +- Last but not least: NIH syndrome of course! diff --git a/config.mak b/config.mak new file mode 100644 index 0000000..92e0f53 --- /dev/null +++ b/config.mak @@ -0,0 +1,43 @@ +# This file was generated by: +# ./configure +# Any changes made here will be lost if configure is re-run. + +target := x86_64-alpine-linux-musl +package := shh-portable-utils +prefix := +exec_prefix := +dynlibdir := /lib +libexecdir := /libexec +bindir := /bin +libdir := /usr/lib/shh-portable-utils +includedir := /usr/include +sysdeps := /usr/lib/skalibs/sysdeps +slashpackage := false +sproot := +version := 0.0.0.1 +home := +exthome := +SPAWN_LIB := +SOCKET_LIB := +SYSCLOCK_LIB := +TIMER_LIB := +UTIL_LIB := + +CC := gcc +CPPFLAGS_AUTO := -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -iquote src/include-local -Isrc/include -fPIC -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith +CPPFLAGS := +CFLAGS_AUTO := -pipe -Wall -std=c99 -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections +CFLAGS := -O2 -fomit-frame-pointer +LDFLAGS_AUTO := -Wl,--sort-section=alignment -Wl,--sort-common +LDFLAGS := +LDFLAGS_SHARED := -shared +LDFLAGS_NOSHARED := -L/usr/lib/skalibs -Wl,--gc-sections +CROSS_COMPILE := + +vpath lib%.a /usr/lib/skalibs +vpath lib%.so +.LIBPATTERNS := lib%.a +DO_ALLSTATIC := 1 +DO_STATIC := 1 +DO_SHARED := +STATIC_LIBS_ARE_PIC := 1 diff --git a/configure b/configure new file mode 100755 index 0000000..4c9874e --- /dev/null +++ b/configure @@ -0,0 +1,471 @@ +#!/bin/sh + +cd `dirname "$0"` +. package/info + +usage () { +cat <<EOF +Usage: $0 [OPTION]... [TARGET] + +Defaults for the options are specified in brackets. + +System types: + --target=TARGET configure to run on target TARGET [detected] + --host=TARGET same as --target + +Installation directories: + --prefix=PREFIX main installation prefix [/] + --exec-prefix=EPREFIX installation prefix for executable files [PREFIX] + +Fine tuning of the installation directories: + --dynlibdir=DIR shared library files [PREFIX/lib] + --bindir=BINDIR user executables [EPREFIX/bin] + --libexecdir=DIR package-scoped executables [EPREFIX/libexec] + --libdir=DIR static library files [PREFIX/lib/$package] + --includedir=DIR C header files [PREFIX/include] + + If no --prefix option is given, by default libdir (but not dynlibdir) will be + /usr/lib/$package, and includedir will be /usr/include. + +Dependencies: + --with-sysdeps=DIR use sysdeps in DIR [PREFIX/lib/skalibs/sysdeps] + --with-include=DIR add DIR to the list of searched directories for headers + --with-lib=DIR add DIR to the list of searched directories for static libraries + --with-dynlib=DIR add DIR to the list of searched directories for shared libraries + + If no --prefix option is given, by default sysdeps will be fetched from + /usr/lib/skalibs/sysdeps. + +Optional features: + --enable-shared build shared libraries [disabled] + --disable-static do not build static libraries [enabled] + --disable-allstatic do not prefer linking against static libraries [enabled] + --enable-static-libc make entirely static binaries [disabled] + --disable-all-pic do not build executables or static libs as PIC [enabled] + --enable-slashpackage[=ROOT] assume /package installation at ROOT [disabled] + --enable-absolute-paths do not rely on PATH to access this package's binaries, + hardcode absolute BINDIR/foobar paths instead [disabled] + +EOF +exit 0 +} + +# Helper functions + +# If your system does not have printf, you can comment this, but it is +# generally not a good idea to use echo. +# See http://etalabs.net/sh_tricks.html +echo () { + IFS=" " + printf %s\\n "$*" +} + +quote () { + tr '\n' ' ' <<EOF | grep '^[-[:alnum:]_=,./:]* $' >/dev/null 2>&1 && { echo "$1" ; return 0 ; } +$1 +EOF + echo "$1" | sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/" -e "s#^'\([-[:alnum:]_,./:]*\)=\(.*\)\$#\1='\2#" -e "s|\*/|* /|g" +} + +fail () { + echo "$*" + exit 1 +} + +fnmatch () { + eval "case \"\$2\" in $1) return 0 ;; *) return 1 ;; esac" +} + +cmdexists () { + type "$1" >/dev/null 2>&1 +} + +trycc () { + test -z "$CC_AUTO" && cmdexists "$1" && CC_AUTO="$*" +} + +stripdir () { + while eval "fnmatch '*/' \"\${$1}\"" ; do + eval "$1=\${$1%/}" + done +} + +tryflag () { + echo "Checking whether compiler accepts $2 ..." + echo "typedef int x;" > "$tmpc" + if $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST "$2" -c -o "$tmpo" "$tmpc" >/dev/null 2>&1 ; then + echo " ... yes" + eval "$1=\"\${$1} \$2\"" + eval "$1=\${$1# }" + return 0 + else + echo " ... no" + return 1 + fi +} + +tryldflag () { + echo "Checking whether linker accepts $2 ..." + echo "typedef int x;" > "$tmpc" + if $CC_AUTO $CFLAGS_AUTO $CFLAGS $CFLAGS_POST $LDFLAGS_AUTO $LDFLAGS $LDFLAGS_POST -nostdlib "$2" -o "$tmpe" "$tmpc" >/dev/null 2>&1 ; then + echo " ... yes" + eval "$1=\"\${$1} \$2\"" + eval "$1=\${$1# }" + return 0 + else + echo " ... no" + return 1 + fi +} + + +# Actual script + +CC_AUTO= +CPPFLAGS_AUTO="-D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -iquote src/include-local -Isrc/include" +CPPFLAGS_POST="$CPPFLAGS" +CPPFLAGS= +CFLAGS_AUTO="-pipe -Wall" +CFLAGS_POST="$CFLAGS" +CFLAGS=-O2 +LDFLAGS_AUTO= +LDFLAGS_POST="$LDFLAGS" +LDFLAGS= +LDFLAGS_NOSHARED= +LDFLAGS_SHARED=-shared +prefix= +exec_prefix='$prefix' +dynlibdir='$prefix/lib' +libexecdir='$exec_prefix/libexec' +bindir='$exec_prefix/bin' +libdir='$prefix/lib/$package' +includedir='$prefix/include' +sysdeps='$prefix/lib/skalibs/sysdeps' +manualsysdeps=false +shared=false +static=true +allpic=true +slashpackage=false +abspath=false +sproot= +home= +exthome= +allstatic=true +evenmorestatic=false +addincpath='' +addlibspath='' +addlibdpath='' +vpaths='' +vpathd='' +build= + +for arg ; do + case "$arg" in + --help) usage ;; + --prefix=*) prefix=${arg#*=} ;; + --exec-prefix=*) exec_prefix=${arg#*=} ;; + --dynlibdir=*) dynlibdir=${arg#*=} ;; + --libexecdir=*) libexecdir=${arg#*=} ;; + --bindir=*) bindir=${arg#*=} ;; + --libdir=*) libdir=${arg#*=} ;; + --includedir=*) includedir=${arg#*=} ;; + --with-sysdeps=*) sysdeps=${arg#*=} manualsysdeps=true ;; + --with-include=*) var=${arg#*=} ; stripdir var ; addincpath="$addincpath -I$var" ;; + --with-lib=*) var=${arg#*=} ; stripdir var ; addlibspath="$addlibspath -L$var" ; vpaths="$vpaths $var" ;; + --with-dynlib=*) var=${arg#*=} ; stripdir var ; addlibdpath="$addlibdpath -L$var" ; vpathd="$vpathd $var" ;; + --enable-shared|--enable-shared=yes) shared=true ;; + --disable-shared|--enable-shared=no) shared=false ;; + --enable-static|--enable-static=yes) static=true ;; + --disable-static|--enable-static=no) static=false ;; + --enable-allstatic|--enable-allstatic=yes) allstatic=true ;; + --disable-allstatic|--enable-allstatic=no) allstatic=false ; evenmorestatic=false ;; + --enable-static-libc|--enable-static-libc=yes) allstatic=true ; evenmorestatic=true ;; + --disable-static-libc|--enable-static-libc=no) evenmorestatic=false ;; + --enable-all-pic|--enable-all-pic=yes) allpic=true ;; + --disable-all-pic|--enable-all-pic=no) allpic=false ;; + --enable-slashpackage=*) sproot=${arg#*=} ; slashpackage=true ; ;; + --enable-slashpackage) sproot= ; slashpackage=true ;; + --disable-slashpackage) sproot= ; slashpackage=false ;; + --enable-absolute-paths|--enable-absolute-paths=yes) abspath=true ;; + --disable-absolute-paths|--enable-absolute-paths=no) abspath=false ;; + --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;; + --host=*|--target=*) target=${arg#*=} ;; + --build=*) build=${arg#*=} ;; + -* ) echo "$0: unknown option $arg" ;; + *=*) eval "$arg" ;; + *) target=$arg ;; + esac +done + +# Add /usr in the default default case +if test -z "$prefix" ; then + if test "$libdir" = '$prefix/lib/$package' ; then + libdir=/usr/lib/$package + fi + if test "$includedir" = '$prefix/include' ; then + includedir=/usr/include + fi + if test "$sysdeps" = '$prefix/lib/skalibs/sysdeps' ; then + sysdeps=/usr/lib/skalibs/sysdeps + fi +fi + +# Expand installation directories +stripdir prefix +for i in exec_prefix dynlibdir libexecdir bindir libdir includedir sysdeps sproot ; do + eval tmp=\${$i} + eval $i=$tmp + stripdir $i +done + +# Get usable temp filenames +i=0 +set -C +while : ; do + i=$(($i+1)) + tmpc="./tmp-configure-$$-$PPID-$i.c" + tmpo="./tmp-configure-$$-$PPID-$i.o" + tmpe="./tmp-configure-$$-$PPID-$i.tmp" + 2>|/dev/null > "$tmpc" && break + 2>|/dev/null > "$tmpo" && break + 2>|/dev/null > "$tmpe" && break + test "$i" -gt 50 && fail "$0: cannot create temporary files" +done +set +C +trap 'rm -f "$tmpc" "$tmpo" "$tmpe"' EXIT ABRT INT QUIT TERM HUP + +# Set slashpackage values +if $slashpackage ; then + home=${sproot}/package/${category}/${package}-${version} + exthome=${sproot}/package/${category}/${package} + if $manualsysdeps ; then + : + else + sysdeps=${DESTDIR}${sproot}/package/prog/skalibs/sysdeps + fi + extbinprefix=${exthome}/command + dynlibdir=${home}/library.so + bindir=${home}/command + libdir=${home}/library + libexecdir=$bindir + includedir=${home}/include + while read dep condvar ; do + if test -n "$condvar" ; then + eval "cond=$condvar" + else + cond=true + fi + if $cond ; then + addincpath="$addincpath -I${DESTDIR}${sproot}${dep}/include" + vpaths="$vpaths ${DESTDIR}${sproot}${dep}/library" + addlibspath="$addlibspath -L${DESTDIR}${sproot}${dep}/library" + vpathd="$vpathd ${DESTDIR}${sproot}${dep}/library.so" + addlibdpath="$addlibdpath -L${DESTDIR}${sproot}${dep}/library.so" + fi + done < package/deps-build +fi + +# Find a C compiler to use +if test -n "$target" && test x${build} != x${target} ; then + cross=${target}- +else + cross= +fi +echo "Checking for C compiler..." +trycc ${CC} +if test -n "$CC_AUTO" ; then + b=`basename "$CC"` + adjust_cross=false + if test "$b" != "$CC" ; then + adjust_cross=true + echo "$0: warning: compiler $CC is declared with its own path. If it's not accessible via PATH, you will need to pass AR, RANLIB and STRIP make variables to the make invocation." 1>&2 + fi + if test -n "$cross" ; then + if test "$b" = "${b##$cross}" ; then + echo "$0: warning: compiler $CC is declared as a cross-compiler for target $target but does not start with prefix ${cross}" 1>&2 + elif $adjust_cross ; then + cross=`dirname "$CC"`/"$cross" + fi + fi +fi +trycc ${cross}gcc +trycc ${cross}clang +trycc ${cross}cc +test -n "$CC_AUTO" || { echo "$0: cannot find a C compiler" ; exit 1 ; } +echo " ... $CC_AUTO" +echo "Checking whether C compiler works... " +echo "typedef int x;" > "$tmpc" +if $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -c -o "$tmpo" "$tmpc" 2>"$tmpe" ; then + echo " ... yes" +else + echo " ... no. Compiler output follows:" + cat < "$tmpe" + exit 1 +fi + +echo "Checking target system type..." +if test -z "$target" ; then + if test -n "$build" ; then + target=$build ; + else + target=$($CC_AUTO -dumpmachine 2>/dev/null) || target=unknown + fi +fi +echo " ... $target" +if test ! -d $sysdeps || test ! -f $sysdeps/target ; then + echo "$0: error: $sysdeps is not a valid sysdeps directory" + exit 1 +fi +if [ "x$target" != "x$(cat $sysdeps/target)" ] ; then + echo "$0: error: target $target does not match the contents of $sysdeps/target" + exit 1 +fi + +spawn_lib=$(cat $sysdeps/spawn.lib) +socket_lib=$(cat $sysdeps/socket.lib) +sysclock_lib=$(cat $sysdeps/sysclock.lib) +timer_lib=$(cat $sysdeps/timer.lib) +util_lib=$(cat $sysdeps/util.lib) + +if $allpic ; then + tryflag CPPFLAGS_AUTO -fPIC +fi +tryflag CFLAGS_AUTO -std=c99 +tryflag CFLAGS -fomit-frame-pointer +tryflag CFLAGS_AUTO -fno-exceptions +tryflag CFLAGS_AUTO -fno-unwind-tables +tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables +tryflag CPPFLAGS_AUTO -Werror=implicit-function-declaration +tryflag CPPFLAGS_AUTO -Werror=implicit-int +tryflag CPPFLAGS_AUTO -Werror=pointer-sign +tryflag CPPFLAGS_AUTO -Werror=pointer-arith +tryflag CFLAGS_AUTO -ffunction-sections +tryflag CFLAGS_AUTO -fdata-sections + +tryldflag LDFLAGS_AUTO -Wl,--sort-section=alignment +tryldflag LDFLAGS_AUTO -Wl,--sort-common + +CPPFLAGS_AUTO="${CPPFLAGS_AUTO}${addincpath}" + +if $evenmorestatic ; then + LDFLAGS_NOSHARED=-static +fi + +if $shared ; then + tryldflag LDFLAGS -Wl,--hash-style=both +fi + +LDFLAGS_SHARED="${LDFLAGS_SHARED}${addlibdpath}" + +if test -z "$vpaths" ; then + while read dep ; do + base=$(basename $dep) ; + vpaths="$vpaths /usr/lib/$base" + addlibspath="$addlibspath -L/usr/lib/$base" + done < package/deps-build +fi + +if $allstatic ; then + LDFLAGS_NOSHARED="${LDFLAGS_NOSHARED}${addlibspath}" + tryldflag LDFLAGS_NOSHARED -Wl,--gc-sections +else + LDFLAGS_NOSHARED="${LDFLAGS_NOSHARED}${addlibdpath}" +fi + +echo "Creating config.mak..." +cmdline=$(quote "$0") +for i ; do cmdline="$cmdline $(quote "$i")" ; done +exec 3>&1 1>config.mak +cat << EOF +# This file was generated by: +# $cmdline +# Any changes made here will be lost if configure is re-run. + +target := $target +package := $package +prefix := $prefix +exec_prefix := $exec_prefix +dynlibdir := $dynlibdir +libexecdir := $libexecdir +bindir := $bindir +libdir := $libdir +includedir := $includedir +sysdeps := $sysdeps +slashpackage := $slashpackage +sproot := $sproot +version := $version +home := $home +exthome := $exthome +SPAWN_LIB := ${spawn_lib} +SOCKET_LIB := ${socket_lib} +SYSCLOCK_LIB := ${sysclock_lib} +TIMER_LIB := ${timer_lib} +UTIL_LIB := ${util_lib} + +CC := $CC_AUTO +CPPFLAGS_AUTO := $CPPFLAGS_AUTO +CPPFLAGS := $CPPFLAGS $CPPFLAGS_POST +CFLAGS_AUTO := $CFLAGS_AUTO +CFLAGS := $CFLAGS $CFLAGS_POST +LDFLAGS_AUTO := $LDFLAGS_AUTO +LDFLAGS := $LDFLAGS $LDFLAGS_POST +LDFLAGS_SHARED := $LDFLAGS_SHARED +LDFLAGS_NOSHARED := $LDFLAGS_NOSHARED +CROSS_COMPILE := $cross + +vpath lib%.a$vpaths +vpath lib%.so$vpathd +EOF +if $allstatic ; then + echo ".LIBPATTERNS := lib%.a" + echo "DO_ALLSTATIC := 1" +else + echo ".LIBPATTERNS := lib%.so" +fi +if $static ; then + echo "DO_STATIC := 1" +else + echo "DO_STATIC :=" +fi +if $shared ; then + echo "DO_SHARED := 1" +else + echo "DO_SHARED :=" +fi +if $allpic ; then + echo "STATIC_LIBS_ARE_PIC := 1" +else + echo "STATIC_LIBS_ARE_PIC :=" +fi + +exec 1>&3 3>&- +echo " ... done." + +echo "Creating src/include/${package}/config.h..." +mkdir -p -m 0755 src/include/${package} +exec 3>&1 1> src/include/${package}/config.h +cat <<EOF +/* ISC license. */ + +/* Generated by: $cmdline */ + +#ifndef ${package_macro_name}_CONFIG_H +#define ${package_macro_name}_CONFIG_H + +#define ${package_macro_name}_VERSION "$version" +EOF +if $slashpackage ; then + echo "#define ${package_macro_name}_BINPREFIX \"$bindir/\"" + echo "#define ${package_macro_name}_EXTBINPREFIX \"$extbinprefix/\"" +elif $abspath ; then + echo "#define ${package_macro_name}_BINPREFIX \"$bindir/\"" + echo "#define ${package_macro_name}_EXTBINPREFIX \"$bindir/\"" +else + echo "#define ${package_macro_name}_BINPREFIX \"\"" + echo "#define ${package_macro_name}_EXTBINPREFIX \"\"" +fi +echo "#define ${package_macro_name}_LIBEXECPREFIX \"$libexecdir/\"" +echo +echo "#endif" +exec 1>&3 3>&- +echo " ... done." diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..de29623 --- /dev/null +++ b/meson.build @@ -0,0 +1,7 @@ +project('shh-portable-utils', ['c'], version: '0.0.0.1', default_options: ['c_std=c99']) + +cc = meson.get_compiler('c') + +libskarnet = [cc.find_library('skarnet', required: true)] + +subdir('src') diff --git a/package/deps-build b/package/deps-build new file mode 100644 index 0000000..05d5af4 --- /dev/null +++ b/package/deps-build @@ -0,0 +1 @@ +/package/prog/skalibs diff --git a/package/deps.mak b/package/deps.mak new file mode 100644 index 0000000..08c9469 --- /dev/null +++ b/package/deps.mak @@ -0,0 +1,22 @@ +# +# This file has been generated by tools/gen-deps.sh +# + +src/shh-portable-utils/basename.o src/shh-portable-utils/basename.lo: src/shh-portable-utils/basename.c +src/shh-portable-utils/cat.o src/shh-portable-utils/cat.lo: src/shh-portable-utils/cat.c +src/shh-portable-utils/false.o src/shh-portable-utils/false.lo: src/shh-portable-utils/false.c +src/shh-portable-utils/true.o src/shh-portable-utils/true.lo: src/shh-portable-utils/true.c +src/shh-portable-utils/uniq.o src/shh-portable-utils/uniq.lo: src/shh-portable-utils/uniq.c + +basename: EXTRA_LIBS := +basename: src/shh-portable-utils/basename.o +cat: EXTRA_LIBS := -lskarnet +cat: src/shh-portable-utils/cat.o +false: EXTRA_LIBS := +false: src/shh-portable-utils/false.o +true: EXTRA_LIBS := +true: src/shh-portable-utils/true.o +uniq: EXTRA_LIBS := -lskarnet +uniq: src/shh-portable-utils/uniq.o +uniq.c: EXTRA_LIBS := +uniq.c: src/shh-portable-utils/uniq.c.o diff --git a/package/info b/package/info new file mode 100644 index 0000000..5d4a623 --- /dev/null +++ b/package/info @@ -0,0 +1,4 @@ +package=shh-portable-utils +version=0.0.0.1 +category=admin +package_macro_name=SHH_PORTABLE_UTILS diff --git a/package/modes b/package/modes new file mode 100644 index 0000000..fd0cd24 --- /dev/null +++ b/package/modes @@ -0,0 +1,5 @@ +basename 0755 +cat 0755 +false 0755 +true 0755 +uniq 0755 diff --git a/package/targets.mak b/package/targets.mak new file mode 100644 index 0000000..48946f2 --- /dev/null +++ b/package/targets.mak @@ -0,0 +1,8 @@ +BIN_TARGETS := \ +basename \ +cat \ +false \ +true \ +uniq + +LIBEXEC_TARGETS := diff --git a/src/include/shh-portable-utils/config.h b/src/include/shh-portable-utils/config.h new file mode 100644 index 0000000..5b5a36b --- /dev/null +++ b/src/include/shh-portable-utils/config.h @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* Generated by: ./configure */ + +#ifndef SHH_PORTABLE_UTILS_CONFIG_H +#define SHH_PORTABLE_UTILS_CONFIG_H + +#define SHH_PORTABLE_UTILS_VERSION "0.0.0.1" +#define SHH_PORTABLE_UTILS_BINPREFIX "" +#define SHH_PORTABLE_UTILS_EXTBINPREFIX "" +#define SHH_PORTABLE_UTILS_LIBEXECPREFIX "/libexec/" + +#endif diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..54a6c8d --- /dev/null +++ b/src/meson.build @@ -0,0 +1 @@ +subdir('shh-portable-utils') diff --git a/src/shh-portable-utils/basename.c b/src/shh-portable-utils/basename.c new file mode 100644 index 0000000..01ff546 --- /dev/null +++ b/src/shh-portable-utils/basename.c @@ -0,0 +1,36 @@ +#include <unistd.h> +#include <string.h> + +int main(int argc, char **argv) +{ + size_t pathlen, sufflen, i; + char *basename_start; + if (argc < 2) { write(1, ".\n", 2); return 0; } + pathlen = strlen(argv[1]); + if(!pathlen) { write(1, ".\n", 2); return 0; } + for (i = 1; i < pathlen; i++) + if (argv[1][pathlen - i] != '/') break; + if (i == pathlen) { + write(1, "/\n", 2); + return 0; + } + i--; + argv[1][pathlen - i] = '\0'; + pathlen = pathlen - i; + for(i = 1; i < pathlen; i++) + if (argv[1][pathlen - i] == '/') break; + if (i == pathlen) + basename_start = argv[1]; + else { + basename_start = argv[1] + pathlen - i + 1; + pathlen = i - 1; + } + if (argc > 2) { + sufflen = strlen(argv[2]); + if (!strcmp(basename_start + pathlen - sufflen, argv[2])) + pathlen -= sufflen; + } + write(1, basename_start, pathlen); + write(1, "\n", 1); + return 0; +} diff --git a/src/shh-portable-utils/cat.c b/src/shh-portable-utils/cat.c new file mode 100644 index 0000000..5913922 --- /dev/null +++ b/src/shh-portable-utils/cat.c @@ -0,0 +1,70 @@ +#include <stddef.h> +#include <string.h> + +#include <skalibs/allreadwrite.h> +#include <skalibs/strerr2.h> +#include <skalibs/sgetopt.h> +#include <skalibs/djbunix.h> + +#define USAGE "cat [-u] [file...]" + +typedef off_t (*cat_func_t)(int, int); + +off_t fd_cat_slow(int from, int to); + +off_t fd_cat_slow(int from, int to) +{ + char c; + off_t transmitted = 0; + for (;;) { + ssize_t result = fd_read(from, &c, 1); + if (result < 0) + return result; + if (result == 0) + break; + if (fd_write(to, &c, 1) < 0) + return -1; + transmitted++; + } + return transmitted; +} + +int main(int argc, char const *const *argv) +{ + cat_func_t cat = fd_cat; + subgetopt l = SUBGETOPT_ZERO; + PROG = "cat"; + for (;;) { + int opt = subgetopt_r(argc, argv, "u", &l); + if (opt == -1) + break; + switch (opt) { + case 'u': + cat = fd_cat_slow; + break; + default: + strerr_dieusage(100, USAGE); + break; + } + } + argc -= l.ind; + argv += l.ind; + if (argc == 0) + if (cat(0, 1) < 0) + strerr_diefu1sys(111, "read from stdin"); + for (char const *const *filename = argv; *filename; filename++) { + int fd; + if (!strcmp(*filename, "-")) + fd = 0; + else { + fd = openb_read(*filename); + if (fd < 0) + strerr_diefu3sys(111, "open file ", *filename, " for reading"); + } + if (cat(fd, 1) < 0) + strerr_diefu2sys(111, "read from ", fd == 1 ? "stdin" : *filename); + fd_close(fd); + } + + return 0; +} diff --git a/src/shh-portable-utils/deps-exe/basename b/src/shh-portable-utils/deps-exe/basename new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/shh-portable-utils/deps-exe/basename diff --git a/src/shh-portable-utils/deps-exe/cat b/src/shh-portable-utils/deps-exe/cat new file mode 100644 index 0000000..e7187fe --- /dev/null +++ b/src/shh-portable-utils/deps-exe/cat @@ -0,0 +1 @@ +-lskarnet diff --git a/src/shh-portable-utils/deps-exe/false b/src/shh-portable-utils/deps-exe/false new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/shh-portable-utils/deps-exe/false diff --git a/src/shh-portable-utils/deps-exe/true b/src/shh-portable-utils/deps-exe/true new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/shh-portable-utils/deps-exe/true diff --git a/src/shh-portable-utils/deps-exe/uniq b/src/shh-portable-utils/deps-exe/uniq new file mode 100644 index 0000000..e7187fe --- /dev/null +++ b/src/shh-portable-utils/deps-exe/uniq @@ -0,0 +1 @@ +-lskarnet diff --git a/src/shh-portable-utils/deps-exe/uniq.c b/src/shh-portable-utils/deps-exe/uniq.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/shh-portable-utils/deps-exe/uniq.c diff --git a/src/shh-portable-utils/false.c b/src/shh-portable-utils/false.c new file mode 100644 index 0000000..2cecef0 --- /dev/null +++ b/src/shh-portable-utils/false.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 1; +} diff --git a/src/shh-portable-utils/meson.build b/src/shh-portable-utils/meson.build new file mode 100644 index 0000000..6b205fa --- /dev/null +++ b/src/shh-portable-utils/meson.build @@ -0,0 +1,5 @@ +executable('basename', 'basename.c', install: true) +executable('cat', 'cat.c', dependencies: libskarnet, install: true) +executable('false', 'false.c', install: true) +executable('true', 'true.c', install: true,) +executable('uniq', 'uniq.c', dependencies: libskarnet, install: true) diff --git a/src/shh-portable-utils/true.c b/src/shh-portable-utils/true.c new file mode 100644 index 0000000..58fe692 --- /dev/null +++ b/src/shh-portable-utils/true.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/src/shh-portable-utils/uniq.c b/src/shh-portable-utils/uniq.c new file mode 100644 index 0000000..e8d50db --- /dev/null +++ b/src/shh-portable-utils/uniq.c @@ -0,0 +1,185 @@ +#include <errno.h> +#include <string.h> +#include <fcntl.h> + +#include <skalibs/buffer.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <skalibs/sgetopt.h> +#include <skalibs/skamisc.h> +#include <skalibs/stralloc.h> +#include <skalibs/strerr2.h> +#include <skalibs/uint32.h> + +#define USAGE "uniq [-c|-d|-u] [-f fields] [-s char] [input_file [output_file]]" + +#define byte_cmp(s1, l1, s2, l2) memcmp((s1), (s2), (l1) < (l2) ? (l1) : (l2)) + +char *prepare_string(stralloc const *sa, int fields, int chars); + +size_t byte_notin(char const *s, size_t n, char const *sep, size_t len); + +char *prepare_string(stralloc const *sa, int fields, int chars) +{ + size_t pos = 0; + for (int j = 0; j < fields; j++) { + pos += byte_notin(sa->s + pos, sa->len - pos, " \t", 2); + if (pos >= sa->len) + return sa->s + sa->len; + pos += byte_in(sa->s + pos, sa->len - pos, " \t", 2); + if (pos >= sa->len) + return sa->s + sa->len; + } + return sa->s + (pos + chars > sa->len ? sa->len : pos + chars); +} + +size_t byte_notin(char const *s, size_t n, char const *sep, size_t len) +{ + char const *t = s; + while (n) { + n--; + if (!memchr(sep, *t, len)) + break; + t++; + } + return t - s; +} + +int main(int argc, char const *const *argv) +{ + char *prev_line_start, *curr_line_start; + int counter, result; + char buf_in[BUFFER_INSIZE]; + char buf_out[BUFFER_OUTSIZE]; + buffer buffer_in_, buffer_out_; + buffer *buffer_in, *buffer_out; + stralloc prev_line = STRALLOC_ZERO; + stralloc curr_line = STRALLOC_ZERO; + subgetopt l = SUBGETOPT_ZERO; + int chars = 0, fields = 0; + int do_count = 0, pr_repeated = 1, pr_unique = 1; + + PROG = "uniq"; + for (;;) { + int opt = subgetopt_r(argc, argv, "cdf:s:u", &l); + if (opt == -1) + break; + switch (opt) { + case 'c': + do_count = 1; + break; + case 'd': + pr_unique = 0; + break; + case 'f': + if (!int32_scan(l.arg, &fields)) + strerr_dieusage(100, USAGE); + break; + case 's': + if (!int32_scan(l.arg, &chars)) + strerr_dieusage(100, USAGE); + break; + case 'u': + pr_repeated = 0; + break; + default: + strerr_dieusage(100, USAGE); + break; + } + } + argc -= l.ind; + argv += l.ind; + + if (argc >= 3) + strerr_dieusage(100, USAGE); + + if (argc >= 2) { + int out = open_create(argv[1]); + if (out < 0) + strerr_diefu3sys(111, "open file ", argv[1], " for writing"); + buffer_init(&buffer_out_, buffer_write, out, buf_out, BUFFER_OUTSIZE); + buffer_out = &buffer_out_; + } else + buffer_out = buffer_1; + + if (argc >= 1) { + if (strcmp(argv[0], "-")) { + int in = openb_read(argv[0]); + if (in < 0) + strerr_diefu3sys(111, "open file ", argv[0], " for reading"); + buffer_init(&buffer_in_, buffer_read, in, buf_in, BUFFER_INSIZE); + buffer_in = &buffer_in_; + } else + buffer_in = buffer_0; + } else + buffer_in = buffer_0; + + result = skagetln(buffer_in, &prev_line, '\n'); + if (result < 0) { + if (errno != EPIPE) + strerr_diefu1sys(111, "read line"); + else { + if (!pr_unique) + if (do_count) + buffer_puts(buffer_out, "1 "); + buffer_putflush(buffer_out, prev_line.s, prev_line.len); + return 0; + } + } + + prev_line.s[prev_line.len - 1] = '\0'; + prev_line.len--; + counter = 1; + prev_line_start = prepare_string(&prev_line, fields, chars); + + + for (;;) { + curr_line.len = 0; + result = skagetln(buffer_in, &curr_line, '\n'); + if (result > 0) { + curr_line.s[curr_line.len - 1] = '\0'; + curr_line.len--; + } + if (!result) + break; + if (result < 0) { + if (errno != EPIPE) + strerr_diefu1sys(111, "read line"); + else { + stralloc_0(&curr_line); + curr_line.len--; + } + } + curr_line_start = prepare_string(&curr_line, fields, chars); + if (!strcmp(prev_line_start, curr_line_start)) + counter++; + else { + if ((counter > 1 && pr_repeated) || (counter == 1 && pr_unique)) { + if (do_count) { + char fmt[UINT32_FMT]; + buffer_put(buffer_out, fmt, int32_fmt(fmt, counter)); + buffer_puts(buffer_out, " "); + } + buffer_put(buffer_out, prev_line.s, prev_line.len); + buffer_putsflush(buffer_out, "\n"); + } + prev_line_start = prev_line.s + (curr_line_start - curr_line.s); + stralloc_copy(&prev_line, &curr_line); + stralloc_0(&prev_line); + prev_line.len--; + counter = 1; + } + if (result < 0) // errno was EPIPE, we got EOF in the middle of a line + break; + } + if ((counter > 1 && pr_repeated) || (counter == 1 && pr_unique)) { + if (do_count) { + char fmt[UINT32_FMT]; + buffer_put(buffer_out, fmt, int32_fmt(fmt, counter)); + buffer_puts(buffer_out, " "); + } + buffer_put(buffer_out, prev_line.s, prev_line.len); + buffer_putsflush(buffer_out, "\n"); + } + return 0; +} diff --git a/tools/gen-deps.sh b/tools/gen-deps.sh new file mode 100755 index 0000000..27e5b3e --- /dev/null +++ b/tools/gen-deps.sh @@ -0,0 +1,93 @@ +#!/bin/sh -e + +. package/info + +echo '#' +echo '# This file has been generated by tools/gen-deps.sh' +echo '#' +echo + +for dir in src/include/${package} src/* ; do + for file in $(ls -1 $dir | grep -- \\.h$) ; do + { + grep -F -- "#include <${package}/" < ${dir}/$file | cut -d'<' -f2 | cut -d'>' -f1 ; + grep -- '#include ".*\.h"' < ${dir}/$file | cut -d'"' -f2 + } | sort -u | { + deps= + while read dep ; do + if echo $dep | grep -q "^${package}/" ; then + deps="$deps src/include/$dep" + elif test -f "${dir}/$dep" ; then + deps="$deps ${dir}/$dep" + else + deps="$deps src/include-local/$dep" + fi + done + if test -n "$deps" ; then + echo "${dir}/${file}:${deps}" + fi + } + done +done + +for dir in src/* ; do + for file in $(ls -1 $dir | grep -- \\.c$) ; do + { + grep -F -- "#include <${package}/" < ${dir}/$file | cut -d'<' -f2 | cut -d'>' -f1 ; + grep -- '#include ".*\.h"' < ${dir}/$file | cut -d'"' -f2 + } | sort -u | { + deps=" ${dir}/$file" + while read dep ; do + if echo $dep | grep -q "^${package}/" ; then + deps="$deps src/include/$dep" + elif test -f "${dir}/$dep" ; then + deps="$deps ${dir}/$dep" + else + deps="$deps src/include-local/$dep" + fi + done + o=$(echo $file | sed s/\\.c$/.o/) + lo=$(echo $file | sed s/\\.c$/.lo/) + echo "${dir}/${o} ${dir}/${lo}:${deps}" + } + done +done +echo + +for dir in $(ls -1 src | grep -v ^include) ; do + for file in $(ls -1 src/$dir/deps-lib) ; do + deps= + libs= + while read dep ; do + if echo $dep | grep -q -e ^-l -e '^\${.*_LIB}' ; then + libs="$libs $dep" + else + deps="$deps src/$dir/$dep" + fi + done < src/$dir/deps-lib/$file + echo 'ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)' + echo "lib${file}.a.xyzzy:$deps" + echo else + echo "lib${file}.a.xyzzy:$(echo "$deps" | sed 's/\.o/.lo/g')" + echo endif + echo "lib${file}.so.xyzzy: EXTRA_LIBS :=$libs" + echo "lib${file}.so.xyzzy:$(echo "$deps" | sed 's/\.o/.lo/g')" + done + + for file in $(ls -1 src/$dir/deps-exe) ; do + deps= + libs= + while read dep ; do + if echo $dep | grep -q -- \\.o$ ; then + dep="src/$dir/$dep" + fi + if echo $dep | grep -q -e ^-l -e '^\${.*_LIB}' ; then + libs="$libs $dep" + else + deps="$deps $dep" + fi + done < src/$dir/deps-exe/$file + echo "$file: EXTRA_LIBS :=$libs" + echo "$file: src/$dir/$file.o$deps" + done +done diff --git a/tools/install.sh b/tools/install.sh new file mode 100755 index 0000000..89f9428 --- /dev/null +++ b/tools/install.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +usage() { + echo "usage: $0 [-D] [-l] [-m mode] src dst" 1>&2 + exit 1 +} + +mkdirp=false +symlink=false +mode=0755 + +while getopts Dlm: name ; do + case "$name" in + D) mkdirp=true ;; + l) symlink=true ;; + m) mode=$OPTARG ;; + ?) usage ;; + esac +done +shift $(($OPTIND - 1)) + +test "$#" -eq 2 || usage +src=$1 +dst=$2 +tmp="$dst.tmp.$$" + +case "$dst" in + */) echo "$0: $dst ends in /" 1>&2 ; exit 1 ;; +esac + +set -C +set -e + +if $mkdirp ; then + umask 022 + case "$2" in + */*) mkdir -p "${dst%/*}" ;; + esac +fi + +trap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP + +umask 077 + +if $symlink ; then + ln -s "$src" "$tmp" +else + cat < "$1" > "$tmp" + chmod "$mode" "$tmp" +fi + +mv -f "$tmp" "$dst" +if test -d "$dst" ; then + rm -f "$dst/$(basename $tmp)" + if $symlink ; then + mkdir "$tmp" + ln -s "$src" "$tmp/$(basename $dst)" + mv -f "$tmp/$(basename $dst)" "${dst%/*}" + rmdir "$tmp" + else + echo "$0: $dst is a directory" 1>&2 + exit 1 + fi +fi |