summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fankhauser (@tux-six)2022-07-05 03:22:33 +0200
committerAndreas Fankhauser (@tux-six)2022-07-05 03:22:33 +0200
commit0d745cdb688eab40094c434d2564515705ce686b (patch)
treed171a9c97d644cafef67fdde361ff93da65d6dd3
parentd2c0bed52d0a293d5541940dedbfe2b5c9afd2c8 (diff)
parent2eb3a5adf2fd55f21dd9dfa20b423883a6afce12 (diff)
downloadbulk-ln-0d745cdb688eab40094c434d2564515705ce686b.zip
bulk-ln-0d745cdb688eab40094c434d2564515705ce686b.tar.gz
Merge 'Enhance configure script and other cleanup' to master
-rw-r--r--.gitignore1
-rw-r--r--Makefile91
-rw-r--r--README.txt16
-rwxr-xr-xconfigure133
-rw-r--r--doc/INSTALL.txt14
-rw-r--r--src/bulk_ln/bulk_ln.c57
6 files changed, 164 insertions, 148 deletions
diff --git a/.gitignore b/.gitignore
index 2247d5f..a3cd4a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
+/Makefile
/build
/dist
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 86b113f..0000000
--- a/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-
-CC=gcc
-TAR=tar
-MKDIRS=mkdir -p
-TOOLS=lxGcc64
-
-# See "./configure"
-PREFIX=/usr/local
-EXEC_PREFIX=$(PREFIX)
-EXEC_SUFFIX=
-BINDIR=$(EXEC_PREFIX)/bin
-
-ifndef PROJECT_VERSION
- # We just provide a primitive version string so we can see which build
- # we're using while debugging. For a release we will override the version
- # by providing it from cli args to 'make' as in:
- # make clean package PROJECT_VERSION=1.2.3
- PROJECT_VERSION=$(shell date -u +0.0.0-%Y%m%d.%H%M%S)
-endif
-
-CFLAGS= --std=c99 \
- -Wall -Wextra -Werror -fmax-errors=3 \
- -Wno-error=unused-function -Wno-error=unused-label \
- -Wno-error=unused-variable -Wno-error=unused-parameter \
- -Wno-error=unused-const-variable \
- -Werror=implicit-fallthrough=1 \
- -Wno-error=unused-but-set-variable \
- -Wno-unused-function -Wno-unused-parameter \
- -DPROJECT_VERSION=$(PROJECT_VERSION)
-
-LDFLAGS= -Wl,--no-demangle,--fatal-warnings
-
-INCDIRS= -Isrc/bulk_ln -Isrc/common
-
-ifndef NDEBUG
- CFLAGS := $(CFLAGS) -ggdb -O0 -g3
-else
- CFLAGS := $(CFLAGS) -ffunction-sections -fdata-sections -Os "-DNDEBUG=1"
- LDFLAGS := $(LDFLAGS) -Wl,--gc-sections,--as-needed
-endif
-
-
-default: link package
-
-.PHONY: clean
-clean:
- @echo "\n[INFO ] Clean"
- rm -rf build dist
-
-.PHONY: link
-link: build/bin/bulk-ln$(EXEC_SUFFIX)
-
-build/obj/%.o: src/%.c
- @echo "\n[INFO ] Compile '$@'"
- @mkdir -p $(shell dirname build/obj/$*)
- $(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
-
-build/bin/bulk-ln$(EXEC_SUFFIX): \
- build/obj/bulk_ln/bulk_ln.o \
- build/obj/bulk_ln/bulk_ln_main.o
- @echo "\n[INFO ] Link '$@'"
- @mkdir -p $(shell dirname $@)
- $(CC) -o $@ $(LDFLAGS) $^ $(LIBSDIR)
-
-.PHONY: package
-package: link
- @echo "\n[INFO ] Package"
- @rm -rf build/dist-* dist
- @mkdir dist
- @echo
- @bash -c 'if [[ -n `git status --porcelain` ]]; then echo "[WARN ] Worktree not clean!"; sleep 3; fi'
- @# Create Executable bundle.
- @rm -rf build/dist-bin && mkdir -p build/dist-bin
- @cp -t build/dist-bin \
- README*
- @mkdir build/dist-bin/bin
- @cp -t build/dist-bin/bin \
- build/bin/*$(EXEC_SUFFIX)
- @(cd build/dist-bin && find . -type f -not -name MD5SUM -exec md5sum -b {} \;) > build/MD5SUM
- @mv build/MD5SUM build/dist-bin/.
- @(cd build/dist-bin && $(TAR) --owner=0 --group=0 -czf ../../dist/BulkLn-$(PROJECT_VERSION)-$(TOOLS).tgz *)
- @echo "\n[INFO ] DONE: Artifacts created and placed in 'dist'."
- @echo
- @echo See './dist/' for result.
-
-.PHONY: install
-install:
- @$(MKDIRS) "$(BINDIR)"
- $(TAR) -f "$(shell ls dist/BulkLn-*-$(TOOLS).tgz)" \
- -C "$(BINDIR)" --strip-components=1 -x bin
-
diff --git a/README.txt b/README.txt
index 91f2c2f..1239604 100644
--- a/README.txt
+++ b/README.txt
@@ -6,5 +6,19 @@ BulkLn
Usage: bulk-ln --help
-Build: "doc/INSTALL.txt"
+
+How to build / install
+**********************
+
+Use the well-known procedure:
+
+ curl -sSL http://git.hiddenalpha.ch/bulk-ln.git/snapshot/bulk-ln-master.tar.gz | tar xz
+ cd bulk-ln-master
+ ./configure
+ make
+ make install
+
+You can get some help with:
+
+ ./configure --help
diff --git a/configure b/configure
index fea5aeb..419e9a8 100755
--- a/configure
+++ b/configure
@@ -1,16 +1,18 @@
-#!/usr/bin/env sh
+
set -e
+set -o posix
# See https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
prefix=/usr/local
exec_prefix='$(PREFIX)'
exec_suffix=
bindir='$(EXEC_PREFIX)/bin'
+verbose=0
main() {
parseArgs "$@"
- mangleMakefile
+ printMakefile > Makefile
}
@@ -19,10 +21,11 @@ printHelp() {
echo "Example usage: $0 --prefix /usr/local"
echo ''
echo 'Options:'
- echo ' --prefix <path> Default "/usr/local"'
- echo ' --exec-prefix <path> Default "$(PREFIX)"'
- echo ' --exec-suffix <path> Default <empty>'
- echo ' --bindir <path> Default "$(EXEC_PREFIX)/bin"'
+ echo ' --prefix "/usr/local"'
+ echo ' --exec-prefix "$(PREFIX)"'
+ echo ' --exec-suffix ""'
+ echo ' --bindir "$(EXEC_PREFIX)/bin"'
+ echo ' --verbose 0'
echo ''
}
@@ -31,25 +34,127 @@ parseArgs() {
# See: https://stackoverflow.com/a/14203146/4415884
while test $# -gt 0 ; do
case $1 in
- --help) printHelp; exit 1; ;;
+ --help) printHelp; exit 1; ;;
--prefix) prefix="$2" shift; shift; ;;
--exec-prefix) exec_prefix="$2" shift; shift; ;;
--exec-suffix) exec_suffix="$2" shift; shift; ;;
--bindir) bindir="$2" shift; shift; ;;
+ --verbose) verbose="$2" shift; shift; ;;
*) echo "[ERROR] Unexpected argument: $1"; exit 1 ;;
esac
done
+ if test "$verbose" != "0" -a "$verbose" != "1"; then
+ echo "[ERROR] verbose expected to be 0 or 1. But is: $verbose";
+ false;
+ fi
}
-mangleMakefile() {
- sed -i 's;^PREFIX=.*$;PREFIX='"$prefix"';' Makefile
- sed -i 's;^EXEC_PREFIX=.*$;EXEC_PREFIX='"$exec_prefix"';' Makefile
- sed -i 's;^EXEC_SUFFIX=.*$;EXEC_SUFFIX='"$exec_suffix"';' Makefile
- sed -i 's;^BINDIR=.*$;BINDIR='"$bindir"';' Makefile
-}
+printMakefile () {
+ printf '\n'
+ printf '%s\n' '# This file is generated by configure script. Manual changes may be lost'
+ printf '%s\n' '# when calling configure again.'
+ printf '\n'
+ printf '%s\n' 'CC=gcc'
+ printf '%s\n' 'TAR=tar'
+ printf '%s\n' 'MKDIRS=mkdir -p'
+ printf '%s\n' 'RIMRAF=rm -rf'
+ printf '%s\n' 'COPYTO=cp -t'
+ printf '%s\n' "PREFIX=$prefix"
+ printf '%s\n' "EXEC_PREFIX=$exec_prefix"
+ printf '%s\n' "EXEC_SUFFIX=$exec_suffix"
+ printf '%s\n' "BINDIR=$bindir"
+ # If PROJECT_VERSION set, use it.
+ # If not, try generate via git describe.
+ # If fails (eg git not avail), create pseudo version using date.
+ printf '%s' 'PROJECT_VERSION=$(shell'
+ printf '%s' ' ret=$$(git describe --tags 2>/dev/null |sed -E "s;^v;;");'
+ printf '%s' ' if test -z "$$ret"; then ret=$$(date -u +0.0.0-%Y%m%d.%H%M%S); fi;'
+ printf '%s\n' ' echo "$$ret")'
-main "$@"
+ printf '\n'
+ printf '%s' 'CFLAGS= --std=c99'
+ printf '%s' ' -Wall -Wextra -Werror -fmax-errors=3'
+ printf '%s' ' -Wno-error=unused-function -Wno-error=unused-label'
+ printf '%s' ' -Wno-error=unused-variable -Wno-error=unused-parameter'
+ printf '%s' ' -Wno-error=unused-const-variable'
+ printf '%s' ' -Werror=implicit-fallthrough=1'
+ printf '%s' ' -Wno-error=unused-but-set-variable'
+ printf '%s' ' -Wno-unused-function -Wno-unused-parameter'
+ printf '%s\n' ' -DPROJECT_VERSION=$(PROJECT_VERSION)'
+ printf '%s\n' ''
+ printf '%s\n' 'LDFLAGS= -Wl,--no-demangle,--fatal-warnings'
+ printf '%s\n' ''
+ printf '%s\n' 'INCDIRS= -Isrc/bulk_ln -Isrc/common'
+ printf '%s\n' ''
+ printf '%s\n' 'ifndef NDEBUG'
+ printf '%s\n' ' CFLAGS := $(CFLAGS) -ggdb -O0 -g3'
+ printf '%s\n' 'else'
+ printf '%s\n' ' CFLAGS := $(CFLAGS) -ffunction-sections -fdata-sections -Os "-DNDEBUG=1"'
+ printf '%s\n' ' LDFLAGS := $(LDFLAGS) -Wl,--gc-sections,--as-needed'
+ printf '%s\n' 'endif'
+
+ if test "$verbose" = "0"; then
+ printf '\n'
+ printf '%s\n' '.SILENT:';
+ fi
+
+ printf '\n'
+ printf '%s\n' 'default: link dist'
+
+ printf '\n'
+ printf '%s\n' '.PHONY: clean'
+ printf '%s\n' 'clean:'
+ printf '%s\n' ' echo $(RIMRAF) build dist'
+ printf '%s\n' ' $(RIMRAF) build dist'
+
+ printf '\n'
+ printf '%s\n' '.PHONY: link'
+ printf '%s\n' 'link: build/bin/bulk-ln$(EXEC_SUFFIX)'
+
+ printf '\n'
+ printf '%s\n' 'build/obj/%.o: src/%.c'
+ printf '%s\n' ' echo " CC $@"'
+ printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"'
+ printf '%s\n' ' $(CC) -c -o $@ $^ $(CFLAGS) $(INCDIRS)'
+ printf '\n'
+ printf '%s' 'build/bin/bulk-ln$(EXEC_SUFFIX):'
+ # dependencies
+ printf '%s' ' build/obj/bulk_ln/bulk_ln.o'
+ printf '%s' ' build/obj/bulk_ln/bulk_ln_main.o'
+ printf '\n' # commands
+ printf '%s\n' ' echo " LN $@"'
+ printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"'
+ printf '%s\n' ' $(CC) -o $@ $(LDFLAGS) $^ $(LIBSDIR)'
+ printf '\n'
+ printf '%s\n' '.PHONY: dist'
+ printf '%s\n' 'dist: link'
+ printf '%s\n' ' echo " Package"'
+ printf '%s\n' ' $(RIMRAF) build/dist-* dist'
+ printf '%s\n' ' $(MKDIRS) dist'
+ # Create Executable bundle.
+ printf '%s\n' ' $(MKDIRS) build/dist-bin && $(COPYTO) build/dist-bin \'
+ printf '%s\n' ' README.txt'
+ printf '%s\n' ' $(MKDIRS) build/dist-bin/bin && $(COPYTO) build/dist-bin/bin \'
+ printf '%s\n' ' build/bin/*'
+
+ printf '%s\n' ' (cd build/dist-bin && find . -type f -not -name MD5SUM -exec md5sum -b {} +) > build/dist-bin/MD5SUM'
+
+ printf '%s\n' ' (cd build/dist-bin && $(TAR) --owner=0 --group=0 -czf "../../dist/BulkLn-$(PROJECT_VERSION).tgz" *)'
+ printf '%s\n' ' echo "" && echo "See '\''./dist/'\'' for result." && echo ""'
+ printf '%s' ' if test -n "$$(git status --porcelain 2>/dev/null)"; then'
+ printf '%s' ' echo "[WARN ] Worktree dirty!"; sleep 2;'
+ printf '%s\n' ' fi'
+
+ printf '\n'
+ printf '%s\n' '.PHONY: install'
+ printf '%s\n' 'install:'
+ printf '%s\n' ' $(MKDIRS) "$(BINDIR)"'
+ printf '%s\n' ' $(TAR) --strip-components=1 -C "$(BINDIR)" -xzf "$(shell ls dist/BulkLn-*.tgz)" -- bin'
+}
+
+
+main "$@"
diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt
deleted file mode 100644
index 68ebc59..0000000
--- a/doc/INSTALL.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-How to build/install
-====================
-
-Use the well-known procedure:
-
- ./configure
- make
- make install
-
-You can get some help with:
-
- ./configure --help
-
diff --git a/src/bulk_ln/bulk_ln.c b/src/bulk_ln/bulk_ln.c
index 6d6b6a3..682c1aa 100644
--- a/src/bulk_ln/bulk_ln.c
+++ b/src/bulk_ln/bulk_ln.c
@@ -1,24 +1,21 @@
-/* Header for this file */
+/* This */
#include "bulk_ln.h"
/* System */
#include <assert.h>
#include <errno.h>
-#include <stdbool.h> // TODO remove
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
-/* Other packages from this project */
-/*#include ""*/
-
#define DATA_FILE_FIELD_SEP_CHR '\t'
+typedef char bool;
typedef struct BulkLn BulkLn;
@@ -31,6 +28,12 @@ struct BulkLn {
FILE *dataFd;
+ /** Count of links we created */
+ int createdLinksCount;
+
+ /** Count of direcrories we created */
+ int createdDirsCount;
+
/** If a dry-run got requested */
bool dryRun;
@@ -48,25 +51,20 @@ struct BulkLn {
/** if true, we print a summary what we did at the end of the run to stderr */
bool isPrintSummary;
- /** if true, we will override existing files. This will be on for example
- * if --force got specified. */
+ /** if true, we will override existing files. This will be enabled for
+ * example if --force got specified. */
bool isRelinkExistingFiles;
-
- /** Count of links we created */
- int createdLinksCount;
-
- /** Count of direcrories we created */
- int createdDirsCount;
};
-void printHelp(){
+static void printHelp(){
printf("\n %s%s\n", strrchr(__FILE__, '/') + 1, " @ " STR_QUOT(PROJECT_VERSION) "\n"
"\n"
"Utility to create links. Writing a custom implementation of 'ln' got necessary\n"
"as we found no way to instruct 'ln' to create a few thousand links in an\n"
- "acceptable amount of time. So we just wrote our own ;)\n"
+ "acceptable amount of time. So we just re-invented that wheel so it better fits\n"
+ "our use-case ;)\n"
"\n"
"Takes paths (pairwise) from stdin (see --stdin for details) and creates a\n"
"hardlink for each pair from the 1st path to the 2nd.\n"
@@ -95,9 +93,7 @@ void printHelp(){
"\n"
" --dry-run\n"
" Will print the actions to stdout instead executing them.\n"
- " HINT: The directory count in the summary will be implicitly set to\n"
- " zero, as our used counting strategy would deliver wrong results when we\n"
- " not actually creating the dirs.\n"
+ " HINT: Directory count in summary will be inaccurate in this mode.\n"
"\n"
" --force\n"
" Same meaning as in original 'ln' command.\n"
@@ -107,7 +103,7 @@ void printHelp(){
/** returns non-zero on errors. Error messages will already be printed
* internally. */
-int parseArgs( int argc, char**argv, BulkLn*bulkLn ){
+static int parseArgs( int argc, char**argv, BulkLn*bulkLn ){
/* init (aka set defaults) */
bulkLn->dataFilePath = NULL;
bulkLn->dryRun = 0;
@@ -118,7 +114,7 @@ int parseArgs( int argc, char**argv, BulkLn*bulkLn ){
bulkLn->isRelinkExistingFiles = 0;
// Parse args
- for( int i=1 ; i<argc ; ++i ) {
+ for( int i = 1 ; i < argc ; ++i ){
char *arg = argv[i];
if( !strcmp(arg, "--help") ){
printHelp();
@@ -131,8 +127,8 @@ int parseArgs( int argc, char**argv, BulkLn*bulkLn ){
bulkLn->isRelinkExistingFiles = !0;
}
else if( !strcmp(arg, "--quiet") ){
- bulkLn->isPrintStatus = false;
- bulkLn->isPrintSummary = false;
+ bulkLn->isPrintStatus = 0;
+ bulkLn->isPrintSummary = 0;
}
else if( !strcmp(arg, "--stdin") ){
bulkLn->dataFilePath = "-";
@@ -216,6 +212,12 @@ static int mkdirs( char*path, BulkLn*bulkLn ){
* the dir. Eg if it did NOT already exist */
bulkLn->createdDirsCount += 1;
}
+ }else{
+ /* We cannot really count how many dirs we created. Because maybe
+ * we are (hypothetically) creating this directory the 100th time
+ * now. But we have no way to tell as we do not really create em.
+ * So just increment to have some value at all */
+ bulkLn->createdDirsCount += 1;
}
if( tmpEnd == pathEnd ){
@@ -240,7 +242,7 @@ static int createHardlink( char*srcPath, char*dstPath, BulkLn*bulkLn ){
int err;
if( bulkLn->dryRun || bulkLn->isPrintEachCreateLink ){
- printf("link('%s', '%s')\n", srcPath, dstPath);
+ printf("link(\"%s\", \"%s\")\n", srcPath, dstPath);
}
if( ! bulkLn->dryRun ){
@@ -262,7 +264,7 @@ static int createHardlink( char*srcPath, char*dstPath, BulkLn*bulkLn ){
}
err = link(srcPath, dstPath);
if( err ){
- fprintf(stderr, "link('%s', '%s'): %s\n", srcPath, dstPath, strerror(errno));
+ fprintf(stderr, "link(\"%s\", \"%s\"): %s\n", srcPath, dstPath, strerror(errno));
err = -1; goto finally;
}
}
@@ -293,7 +295,7 @@ static int onPathPair( char*srcPath, char*dstPath, BulkLn*bulkLn ){
tmpEnd[0] = '\0';
/* Create missing parent dirs */
err = mkdirs(dstPath, bulkLn);
- if (err) { err = -1; goto finally; }
+ if( err ){ err = -1; goto finally; }
/* Restore path */
tmpEnd[0] = '/';
}
@@ -350,7 +352,7 @@ static int parseDataFileAsPairPerLine( BulkLn*bulkLn ){
char *dstPath = tab + 1; /* <- path starts one char after the separator */
char *dstPath_end = buf + buf_len;
for(;; --dstPath_end ){
- if( dstPath_end < buf ){
+ if(unlikely( dstPath_end < buf )){
fprintf(stderr, "IMHO cannot happen (@%s:%d)\n", __FILE__, __LINE__);
err = -1; goto finally;
}
@@ -388,7 +390,6 @@ int bulk_ln_main( int argc, char**argv ){
BulkLn bulkLn = {0};
#define bulkLn (&bulkLn)
- /* parse args */
err = parseArgs(argc, argv, bulkLn);
if( err ){ err = -1; goto finally; }
@@ -414,7 +415,7 @@ int bulk_ln_main( int argc, char**argv ){
err = 0;
finally:
if( bulkLn->dataFd != NULL && bulkLn->dataFd != stdin ){
- fclose(bulkLn->dataFd); bulkLn->dataFd = NULL;
+ fclose(bulkLn->dataFd);
}
return err;
#undef bulkLn