summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-10-09 09:55:18 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-10-09 09:55:18 -0700
commite4d2eece3ffd16cbdde18e53fe1301f2ab0837f9 (patch)
tree34e46d3a3cbfb992e3fb3923f7ea3ca7ba831242
downloadtermbaud-master.tar.gz
termbaud-master.tar.xz
termbaud-master.zip
Wrapper library defining cfencspeed() and cfdecspeed()HEADmaster
-rw-r--r--.gitignore12
-rw-r--r--Makefile58
-rw-r--r--termbaud.c55
-rw-r--r--termbaud_nontrivial.h12
-rw-r--r--termbaud_trivial.h23
-rw-r--r--termios.c1
-rw-r--r--termistriv.c7
7 files changed, 168 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b828ab8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+*~
+*.bak
+*.o
+*.obj
+*.s
+*.i
+*.exe
+termbaud.h
+speedtbl.h
+speed.list
+termistriv.h
+termistriv.i
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a6d25c9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,58 @@
+#
+# Create a wrapper around a legacy implementation
+# for the proposed new bps interfaces. This relies on the -Wp,-dM option
+# in gcc and uses a not too crazy heuristic that if all the numbers
+# equal their corresponding integer then the interface already takes
+# arbitrary integers.
+#
+
+CC = gcc
+CFLAGS = -g -O2
+MACRODEFS = -Wp,-dM -E
+
+.SUFFIXES:
+.SUFFIXES: .c .h .i .s .o
+
+all: termbaud.o termbaud.h
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+.c.i:
+ $(CC) $(CFLAGS) -E -o $@ $<
+.c.s:
+ $(CC) $(CFLAGS) -S -o $@ $<
+
+speed.list: termios.c
+ $(CC) $(CFLAGS) $(MACRODEFS) $< | \
+ sed -r -n -e 's/^#define B([0-9]+) .*$$/\1/p' | \
+ sort -n | uniq > $@
+
+termistriv.h: speed.list Makefile
+ ( echo -n "#if (1"; \
+ while read m; do \
+ echo " && \\" ; \
+ echo -n " (B$$m == $$m)"; \
+ done; \
+ echo ')'; \
+ echo '#define CFENCSPEED_IS_TRIVIAL 1'; \
+ echo '#endif' \
+ ) < $< >> $@ || ( rm -f $@ ; false )
+
+speedtbl.h: speed.list Makefile
+ ( while read m; do \
+ echo " {B$$m, $$m},"; \
+ done \
+ ) < $< >> $@ || ( rm -f $@ ; false )
+
+termistriv.i: termistriv.c termistriv.h termbaud_nontrivial.h
+
+termbaud.h: termistriv.i termbaud_nontrivial.h termbaud_trivial.h
+ cp -f `grep '^termbaud.*\.h$$' $<` termbaud.h
+
+termbaud.o: termbaud.c termbaud_nontrivial.h termistriv.h speedtbl.h
+
+clean:
+ rm -f speed.list termbaud.h termistriv.h *.o *.i *.s
+
+spotless: clean
+ rm -f *~ \#*
diff --git a/termbaud.c b/termbaud.c
new file mode 100644
index 0000000..620a005
--- /dev/null
+++ b/termbaud.c
@@ -0,0 +1,55 @@
+#include <stddef.h>
+#include <errno.h>
+
+#include "termbaud_nontrivial.h" /* Don't want inline definitions */
+#include "termistriv.h"
+
+#ifdef CFENCSPEED_IS_TRIVIAL
+
+speed_t cfencspeed(baud_t baud)
+{
+ return baud;
+}
+baud_t cfdecspeed(speed_t speed)
+{
+ return speed;
+}
+
+#else /* CFENCSPEED_IS_TRIVIAL */
+
+struct speed_baud {
+ speed_t speed;
+ baud_t baud;
+};
+
+static const struct speed_baud speed_baud_tbl[] = {
+#include "speedtbl.h"
+};
+
+#define NSPEEDS ((sizeof speed_baud_tbl)/(sizeof speed_baud_tbl[0]))
+
+speed_t cfencspeed(baud_t b)
+{
+ size_t i;
+
+ for (i = 0; i < NSPEEDS; i++)
+ if (b == speed_baud_tbl[i].baud)
+ return speed_baud_tbl[i].speed;
+
+ errno = EINVAL;
+ return (speed_t)-1;
+}
+
+baud_t cfdecspeed(speed_t s)
+{
+ size_t i;
+
+ for (i = 0; i < NSPEEDS; i++)
+ if (s == speed_baud_tbl[i].speed)
+ return speed_baud_tbl[i].baud;
+
+ errno = EINVAL;
+ return (baud_t)-1;
+}
+
+#endif /* CFENCSPEED_IS_TRIVIAL */
diff --git a/termbaud_nontrivial.h b/termbaud_nontrivial.h
new file mode 100644
index 0000000..f84175b
--- /dev/null
+++ b/termbaud_nontrivial.h
@@ -0,0 +1,12 @@
+#ifndef TERMBAUD_H
+#define TERMBAUD_H
+
+#include <termios.h>
+#include <inttypes.h>
+
+typedef uint64_t baud_t;
+
+extern speed_t cfencspeed(baud_t);
+extern baud_t cfdecspeed(speed_t x);
+
+#endif /* TERMBAUD_H */
diff --git a/termbaud_trivial.h b/termbaud_trivial.h
new file mode 100644
index 0000000..96ad75d
--- /dev/null
+++ b/termbaud_trivial.h
@@ -0,0 +1,23 @@
+#ifndef TERMBAUD_H
+#define TERMBAUD_H
+
+#include <termios.h>
+#include <inttypes.h>
+
+typedef speed_t baud_t;
+
+#define CFENCSPEED_IS_TRIVIAL 1
+
+extern inline speed_t cfencspeed(baud_t x);
+inline speed_t cfencspeed(baud_t x)
+{
+ return x;
+}
+
+extern inline speed_t cfdecspeed(baud_t x);
+inline baud_t cfdecspeed(speed_t x)
+{
+ return x;
+}
+
+#endif /* TERMBAUD_H */
diff --git a/termios.c b/termios.c
new file mode 100644
index 0000000..9e26956
--- /dev/null
+++ b/termios.c
@@ -0,0 +1 @@
+#include <termios.h>
diff --git a/termistriv.c b/termistriv.c
new file mode 100644
index 0000000..de3ba12
--- /dev/null
+++ b/termistriv.c
@@ -0,0 +1,7 @@
+#include "termbaud_nontrivial.h"
+#include "termistriv.h"
+#ifdef CFENCSPEED_IS_TRIVIAL
+termbaud_trivial.h
+#else
+termbaud_nontrivial.h
+#endif