Introduction
Introduction Statistics Contact Development Disclaimer Help
trangetest: switch to C implementation - numtools - perform numerical operation…
git clone git://src.adamsgaard.dk/numtools
Log
Files
Refs
README
LICENSE
---
commit 7a3d0ac06b0b914fbd04bd19e76fc682fcb38a20
parent 1fb885b94e493d9d36da5ddf5d2cd8fb8a99510f
Author: Anders Damsgaard <[email protected]>
Date: Tue, 31 Aug 2021 10:41:51 +0200
rangetest: switch to C implementation
Diffstat:
M Makefile | 51 +++++++++++++++++++++++++----…
D rangetest | 75 -----------------------------…
A rangetest.c | 137 +++++++++++++++++++++++++++++…
3 files changed, 178 insertions(+), 85 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -8,25 +8,53 @@ PREFIX = /usr/local
MANPREFIX = ${PREFIX}/man
DOCPREFIX = ${PREFIX}/share/doc/${NAME}
-SCRIPTS = \
+SCRIPTS =\
histpdf\
max\
mean\
min\
- rangetest\
sum\
- transpose
+ transpose\
+
+BIN =\
+ rangetest\
+
+SRC = ${BIN:=.c}
-MAN1 = ${SCRIPTS:=.1}
-DOC = \
+HDR =\
+ arg.h\
+
+LIBS = -lm
+
+_CFLAGS = ${CFLAGS} ${INCS} -DVERSION=\"${VERSION}\"
+_LDFLAGS = ${LDFLAGS} ${LIBS}
+_CPPFLAGS = ${CPPFLAGS}
+
+MAN1 = ${BIN:=.1} ${SCRIPTS:=.1}
+DOC =\
LICENSE\
- README
+ README\
+
+all: ${BIN}
+
+${BIN}: ${@:=.o}
+
+OBJ = ${SRC:.c=.o}
+
+${OBJ}: ${HDR}
+
+.o:
+ ${CC} -o $@ $< ${_LDFLAGS}
+
+.c.o:
+ ${CC} ${_CFLAGS} ${_CPPFLAGS} -o $@ -c $<
+
install:
# installing executable files and scripts.
mkdir -p "${DESTDIR}${PREFIX}/bin"
cp -f ${SCRIPTS} "${DESTDIR}${PREFIX}/bin"
- for f in ${SCRIPTS}; do chmod 755 "${DESTDIR}${PREFIX}/bin/$$f"; done
+ for f in ${BIN} ${SCRIPTS}; do chmod 755 "${DESTDIR}${PREFIX}/bin/$$f"…
# installing documentation files.
mkdir -p "${DESTDIR}${DOCPREFIX}"
cp -f ${DOC} "${DESTDIR}${DOCPREFIX}"
t@@ -38,7 +66,7 @@ install:
uninstall:
# removing executable files and scripts.
- for f in ${SCRIPTS}; do rm -f "${DESTDIR}${PREFIX}/bin/$$f"; done
+ for f in ${BIN} ${SCRIPTS}; do rm -f "${DESTDIR}${PREFIX}/bin/$$f"; do…
# removing example files.
for d in ${DOC}; do rm -f "${DESTDIR}${DOCPREFIX}/$$d"; done
-rmdir "${DESTDIR}${DOCPREFIX}"
t@@ -48,10 +76,13 @@ uninstall:
dist:
rm -rf "${NAME}-${VERSION}"
mkdir -p "${NAME}-${VERSION}"
- cp -rf ${MAN1} ${DOC} ${SCRIPTS} "${NAME}-${VERSION}"
+ cp -rf ${MAN1} ${DOC} ${BIN} ${SCRIPTS} "${NAME}-${VERSION}"
# make tarball
tar cf - "${NAME}-${VERSION}" | \
gzip -c > "${NAME}-${VERSION}.tar.gz"
rm -rf "${NAME}-${VERSION}"
-.PHONY: install uninstall dist
+clean:
+ rm -f ${BIN} ${OBJ}
+
+.PHONY: install uninstall dist clean
diff --git a/rangetest b/rangetest
t@@ -1,75 +0,0 @@
-#!/usr/bin/awk -f
-# uses a binary search to run a "cmd" where the first occurence of
-# string @VAL@ is substituted for a value between "min_val" and
-# "max_val". Successful runs are reported on stdout, failed runs
-# on stderr. The "cmd" command must successfully run with either
-# "min_val" or "max_val".
-
-function die(s) {
- printf "error: %s\n", s > "/dev/stderr"
- exit 1
-}
-
-function launch(cmd, val) {
- sub(/@VAL@/, val, cmd)
- if (system(cmd)) {
- printf "%g\n", val > "/dev/stderr"
- return 1
- } else {
- printf "%g\n", val > "/dev/stdout"
- return 0
- }
-}
-
-function binary_search(cmd, min, max, maxiter) {
-
- minfail = launch(cmd, min)
- maxfail = launch(cmd, max)
-
- if (minfail && maxfail)
- die("both min_val and max_val runs errored")
-
- if (!minfail && !maxfail)
- die("both min_val and max_val ran successfully")
-
- while (min <= max && iter < maxiter) {
- val = min + 0.5 * (max - min)
-
- if (launch(cmd, val)) { # the cmd fails
- if (maxfail) {
- max = val
- maxfail = 1
- } else {
- min = val
- minfail = 1
- }
- } else { # the cmd is ok
- if (maxfail) {
- min = val
- minfail = 0
- } else {
- max = val
- maxfail = 0
- }
- }
- iter++
- }
-}
-
-BEGIN {
-
- if (ARGC != 4)
- die("usage: rangetest cmd min_val max_val")
-
- cmd = ARGV[1]
- min = ARGV[2]
- max = ARGV[3]
-
- if (!match(cmd, /@VAL@/))
- die("@VAL@ not found in cmd")
-
- if (min >= max)
- die("min_val must be smaller than max_val")
-
- binary_search(cmd, min, max, 10)
-}
diff --git a/rangetest.c b/rangetest.c
t@@ -0,0 +1,137 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <limits.h>
+#include <string.h>
+
+#include "arg.h"
+
+#define VALUESTR "@VAL@"
+
+char *argv0;
+
+#ifdef NEED_STRLCPY /* OpenBSD implementation */
+size_t
+strlcpy(char *dst, const char *src, size_t dsize) {
+ const char *osrc = src;
+ size_t nleft = dsize;
+
+ if (nleft != 0) {
+ while (--nleft != 0) {
+ if ((*dst++= *src++) == '\0')
+ break;
+ }
+ }
+
+ if (nleft == 0) {
+ if (dsize != 0)
+ *dst = '\0';
+ while (*src++)
+ ;
+ }
+
+ return(src - osrc - 1);
+}
+#endif /* NEED_STRLCPY */
+
+static void
+usage(void)
+{
+ errx(1, "usage: %s [-h] [-n maxiter] cmd min_val max_val\n"
+ "where cmd must contain the string '" VALUESTR "'", argv0);
+}
+
+static int
+launch(char *cmd, char *cmd0, double val)
+{
+ char *c;
+
+ if ((c = strstr(cmd0, VALUESTR)) == NULL)
+ errx(1, VALUESTR " not found in cmd");
+
+ if (strlcpy(cmd, cmd0, PATH_MAX) >= PATH_MAX)
+ err(1, "cmd too long");
+
+ sprintf(cmd + (c - cmd0), "%g%s >/dev/null", val, c + strnlen(VALUESTR…
+ if (system(cmd)) {
+ fprintf(stderr, "%g\n", val);
+ return 1;
+ } else {
+ printf("%g\n", val);
+ return 0;
+ }
+}
+
+static void
+binary_search(char *cmd, char *cmd0, double minv, double maxv, int maxiter)
+{
+ int minfail, maxfail;
+ int iter;
+ double val;
+
+ minfail = launch(cmd, cmd0, minv);
+ maxfail = launch(cmd, cmd0, maxv);
+
+ if (minfail && maxfail)
+ errx(2, "both min_val and max_val runs errored");
+
+ else if (!minfail && !maxfail)
+ errx(3, "both min_val and max_val ran successfully");
+
+ while (minv <= maxv && iter < maxiter) {
+ val = minv + 0.5 * (maxv - minv);
+
+ if (launch(cmd, cmd0, val)) {
+ if (maxfail) {
+ maxv = val;
+ maxfail = 1;
+ } else {
+ minv = val;
+ minfail = 1;
+ }
+ } else {
+ if (maxfail) {
+ minv = val;
+ minfail = 0;
+ } else {
+ maxv = val;
+ maxfail = 0;
+ }
+ }
+ iter++;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int maxiter = 10;
+ double minv, maxv;
+ char cmd0[PATH_MAX] = "", cmd[PATH_MAX] = "";
+
+ ARGBEGIN {
+ case 'h':
+ usage();
+ break;
+ case 'n':
+ maxiter = atoi(EARGF(usage()));
+ if (maxiter < 1)
+ errx(1, "maxiter (-n) must be positive");
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc == 3) {
+ if (strlcpy(cmd0, argv[0], sizeof(cmd0)) >= sizeof(cmd0))
+ err(1, "cmd too long");
+ minv = atof(argv[1]);
+ maxv = atof(argv[2]);
+ if (minv >= maxv)
+ errx(1, "min_val must be smaller than max_val");
+ binary_search(cmd, cmd0, minv, maxv, maxiter);
+ } else
+ usage();
+
+ return 0;
+}
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.