diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2023-04-13 17:56:14 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2023-04-13 17:56:14 +0200 |
commit | 9d3b555393735e08c27b04a8b616f2736afe26de (patch) | |
tree | f483cb50a59547fdc8b03ef01dfefb8123b0292b | |
download | abase-9d3b555393735e08c27b04a8b616f2736afe26de.tar.gz abase-9d3b555393735e08c27b04a8b616f2736afe26de.tar.bz2 |
created initial layout and a dummy more.c
-rw-r--r-- | LICENSE | 25 | ||||
-rw-r--r-- | Makefile | 98 | ||||
-rw-r--r-- | README | 32 | ||||
-rw-r--r-- | TODO | 0 | ||||
-rw-r--r-- | arg.h | 63 | ||||
-rw-r--r-- | config.mk | 16 | ||||
-rw-r--r-- | libutil/eprintf.c | 59 | ||||
-rw-r--r-- | more.1 | 13 | ||||
-rw-r--r-- | more.c | 22 | ||||
-rw-r--r-- | util.h | 5 |
10 files changed, 333 insertions, 0 deletions
@@ -0,0 +1,25 @@ +MIT License + +© 2023 Andreas Baumann <mail@andreasbaumann.cc> + +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. + +Authors/contributors include: + +© 2023 Andreas Baumann <mail@andreasbaumann.cc> diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0a0fdc2 --- /dev/null +++ b/Makefile @@ -0,0 +1,98 @@ +include config.mk + +.SUFFIXES: +.SUFFIXES: .o .c + +HDR =\ + arg.h\ + util.h + +LIBUTIL = libutil.a +LIBUTILSRC =\ + libutil/eprintf.c + +LIB = $(LIBUTF) $(LIBUTIL) + +BIN =\ + more + +LIBUTILOBJ = $(LIBUTILSRC:.c=.o) +OBJ = $(BIN:=.o) $(LIBUTFOBJ) $(LIBUTILOBJ) +SRC = $(BIN:=.c) +MAN = $(BIN:=.1) + +all: $(BIN) + +$(BIN): $(LIB) $(@:=.o) + +$(OBJ): $(HDR) config.mk + +.o: + $(CC) $(LDFLAGS) -o $@ $< $(LIB) + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(LIBUTIL): $(LIBUTILOBJ) + $(AR) rc $@ $? + $(RANLIB) $@ + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin + mv -f $(DESTDIR)$(PREFIX)/bin/xinstall $(DESTDIR)$(PREFIX)/bin/install + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + for m in $(MAN); do sed "s/^\.Os abase/.Os abase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done + cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) + mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 + +uninstall: + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) + cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) + +dist: clean + mkdir -p abase-$(VERSION) + cp -r LICENSE Makefile README TODO config.mk $(SRC) $(MAN) libutil $(HDR) abase-$(VERSION) + tar -cf abase-$(VERSION).tar abase-$(VERSION) + gzip abase-$(VERSION).tar + rm -rf abase-$(VERSION) + +abase-box: $(LIB) $(SRC) + mkdir -p build + cp $(HDR) build + for f in $(SRC); do sed "s/^main(/$$(echo "$${f%.c}" | sed s/-/_/g)_&/" < $$f > build/$$f; done + echo '#include <libgen.h>' > build/$@.c + echo '#include <stdio.h>' >> build/$@.c + echo '#include <stdlib.h>' >> build/$@.c + echo '#include <string.h>' >> build/$@.c + echo '#include "util.h"' >> build/$@.c + for f in $(SRC); do echo "int $$(echo "$${f%.c}" | sed s/-/_/g)_main(int, char **);"; done >> build/$@.c + echo 'int main(int argc, char *argv[]) { char *s = basename(argv[0]);' >> build/$@.c + echo 'if(!strcmp(s,"abase-box")) { argc--; argv++; s = basename(argv[0]); } if(0) ;' >> build/$@.c + for f in $(SRC); do echo "else if(!strcmp(s, \"$${f%.c}\")) return $$(echo "$${f%.c}" | sed s/-/_/g)_main(argc, argv);"; done >> build/$@.c + echo 'else {' >> build/$@.c + for f in $(SRC); do echo "fputs(\"$${f%.c} \", stdout);"; done >> build/$@.c + echo 'putchar(0xa); }; return 0; }' >> build/$@.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ build/*.c $(LIB) + rm -r build + +abase-box-install: abase-box + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f abase-box $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/abase-box + for f in $(BIN); do ln -sf abase-box $(DESTDIR)$(PREFIX)/bin/"$$f"; done + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + for m in $(MAN); do sed "s/^\.Os abase/.Os abase $(VERSION)/g" < "$$m" > $(DESTDIR)$(MANPREFIX)/man1/"$$m"; done + cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN) + mv -f $(DESTDIR)$(MANPREFIX)/man1/xinstall.1 $(DESTDIR)$(MANPREFIX)/man1/install.1 + +abase-box-uninstall: uninstall + cd $(DESTDIR)$(PREFIX)/bin && rm -f abase-box + +clean: + rm -f $(BIN) $(OBJ) $(LIB) abase-box abase-$(VERSION).tar.gz + +.gitignore: + { printf '*.o\n' ; printf '/%s\n' $(LIB) $(BIN) ; } > $@ + +.PHONY: all install uninstall dist abase-box-install abase-box-uninstall clean .gitignore @@ -0,0 +1,32 @@ +abase - Aba's tools +=================== + +abase is a collection of tools that didn't fit into ubase or sbase. + +Currently it contains the following: +- a very simple more + +Note: abase is a shameless copy of sbase/ubase in certain areas like +the Makefile, libutil, etc. This might also make an integration into +sbase/ubase easier. + +Building +-------- + +To build abase, simply type make. You may have to fiddle with config.mk +depending on your system. + +You can also build abase-box, which generates a single binary containing +all the required tools. You can then symlink the individual tools to +abase-box or run: make abase-box-install + +Ideally you will want to statically link abase. If you are on Linux we +recommend using musl-libc[1]. + +Portability +----------- + +Not really tested so far, but you should be able to build it with +gcc, clang, tcc, nwcc and pcc. + +[1] http://www.musl-libc.org/ @@ -0,0 +1,63 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..3299a72 --- /dev/null +++ b/config.mk @@ -0,0 +1,16 @@ +# abase version +VERSION = 0.0 + +# paths +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +CC = cc +AR = ar +RANLIB = ranlib + +# for NetBSD add -D_NETBSD_SOURCE +# -lrt might be needed on some systems +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_FILE_OFFSET_BITS=64 +CFLAGS = -std=c99 -Wall -pedantic +LDFLAGS = -s diff --git a/libutil/eprintf.c b/libutil/eprintf.c new file mode 100644 index 0000000..673523e --- /dev/null +++ b/libutil/eprintf.c @@ -0,0 +1,59 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../util.h" + +char *argv0; + +static void xvprintf(const char *, va_list); + +void +eprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); + + exit(1); +} + +void +enprintf(int status, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); + + exit(status); +} + +void +weprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); +} + +void +xvprintf(const char *fmt, va_list ap) +{ + if (argv0 && strncmp(fmt, "usage", strlen("usage"))) + fprintf(stderr, "%s: ", argv0); + + vfprintf(stderr, fmt, ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } +} @@ -0,0 +1,13 @@ +.Dd 2023-04-13 +.Dt MORE 1 +.Os abase +.Sh NAME +.Nm more +.Nd text pager +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +.Nm +pages text file +.Ar path +to stdout, provides navigation key shortcuts. @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ + +#include "util.h" + +static void +usage(void) +{ + eprintf("usage: %s [file ...]\n", argv0); +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + + ARGBEGIN { + default: + usage(); + } ARGEND + + return ret; +} @@ -0,0 +1,5 @@ +/* See LICENSE file for copyright and license details. */ + +#include "arg.h" + +void eprintf(const char *, ...); |