whining about roken.h

Jeffrey Hutzelman jhutz+ at cmu.edu
Wed Jul 7 01:11:14 CEST 1999


Back in February, I started working on a project to develop a free
Ubik-like distributed database, starting from the original Ubik papers
(which Derrick Brashear was kind enough to find for me).  For various
reasons, I chose to use Rx and LWP, as those before me have done.  And,
since Assar was in the room at the time, I ended up using ydr and libroken.

Recently, due mostly to Derrick's nagging, I've picked up the project
again.  Last night, I pulled down the arla-0.25 distribution, and
(re)discovered that roken.h and libroken.a do not get installed by default,
and worse, that the former contains many references to preprocessor symbols
defined by configure, which might not be available to a program wishing to
use the library.

This annoyed me, so I did some work to correct these problems.  The result
is the attached patch, which makes some relatively minor makefile changes
and adds a program which generates roken.h at compile time, using
information collected by configure.  The result is a header that can be
used in more or less any program.

In the name of maintainability, I chose a two-step process.  The final
roken.h file is generated by the program 'roken_h', which is very similar
in form to the 'bits' program in the include directory.  However, to avoid
a completely unmaintainable mess, roken_h.c itself is generated by the
program 'roken_h_c', which takes 'roken.h.in' as its input.  The input file
looks very similar to the original roken.h in the distribution, with the
following differences:

* Lines beginning '% ' are ignored completely; this mechanism allows
comments in the input file.

* Other lines beginning with '%' are preprocessor directives which must be
evaluated at compile time, usually because they depend on data collected by
configure.  These will appear in roken_h.c with the '%' replaced by '#'.

* All other lines are things which may potentially be emitted by the
roken_h program and appear in the final roken.h.  Naturally, whether any
given line is emitted will depend on the %-directives surrounding it (if
any).  Note that each line of this type appears as a string in the roken_h
program; at present, any necessary \-escapes must appear in the input file.

-- Jeffrey T. Hutzelman (N3NHS) <jhutz+ at cmu.edu>
   Sr. Research Systems Programmer
   School of Computer Science - Research Computing Facility
   Carnegie Mellon University - Pittsburgh, PA


diff -ruP arla-0.25-dist/include/Makefile.in arla-0.25/include/Makefile.in--- arla-0.25-dist/include/Makefile.in	Mon May 17 09:57:42 1999+++ arla-0.25/include/Makefile.in	Tue Jul  6 18:05:09 1999@@ -73,7 +73,7 @@ 	cd ..; CONFIG_FILES=include/Makefile CONFIG_HEADERS= ./config.status  roken.h:-	$(LN_S) $(srcdir)/../lib/roken/roken.h .+	$(LN_S) ../lib/roken/roken.h . sl.h: 	$(LN_S) $(srcdir)/../lib/sl/sl.h . ko.h:diff -ruP arla-0.25-dist/lib/roken/Makefile.in arla-0.25/lib/roken/Makefile.in--- arla-0.25-dist/lib/roken/Makefile.in	Sat Feb 13 00:16:26 1999+++ arla-0.25/lib/roken/Makefile.in	Tue Jul  6 18:58:06 1999@@ -11,7 +11,7 @@ CPP	= @CPP@ AR	= ar RANLIB	= @RANLIB at -DEFS	= @DEFS at +DEFS	= @DEFS@ -DHOST=\"@CANONICAL_HOST@\" CFLAGS	= @CFLAGS@  INSTALL = @INSTALL@@@ -21,6 +21,7 @@ prefix = @prefix@ exec_prefix = @exec_prefix@ libdir = @libdir at +includedir = @includedir@  #PICFLAGS = # @PICFLAGS@  @@ -33,6 +34,12 @@ #LDSHARED = @LDSHARED@ LIB = $(LIBNAME).$(LIBEXT) +BUILDSOURCES = roken_h.c++BUILDHEADERS = roken.h++HEADERS = $(BUILDHEADERS)+ SOURCES =					\ 	base64.c				\ 	chown.c					\@@ -89,7 +96,8 @@ 	vwarnx.c				\ 	warn.c					\ 	warnerr.c				\-	warnx.c+	warnx.c					\+	roken_h_c.c  OBJECTS =					\ 	base64.o				\@@ -111,7 +119,11 @@ 	parse_units.o				\ 	@LIBOBJS@ -all: $(LIB)+ROKENHC_OBJECTS = roken_h_c.o++ROKENH_OBJECTS  = roken_h.o++all: $(HEADERS) $(LIB)  Wall: 	make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"@@ -120,8 +132,39 @@ 	$(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $(PICFLAGS) $<  install: all+	$(MKINSTALLDIRS) $(DESTDIR)$(libdir)+	$(INSTALL_DATA) -m 0555 $(LIB) $(DESTDIR)$(libdir)/$(LIB)+	$(MKINSTALLDIRS) $(DESTDIR)$(includedir)+	for x in $(HEADERS); \+	  do \+	  b=`basename $$x`; \+	  if test -f $$b; then \+	    $(INSTALL_DATA) $$b $(DESTDIR)$(includedir)/$$b; \+	  else \+	    $(INSTALL_DATA) $(srcdir)/$$b $(DESTDIR)$(includedir)/$$b; \+	  fi; \+	done  uninstall:+	rm -f $(DESTDIR)$(libdir)/$(LIB)+	for x in $(HEADERS); \+		$(RM_F) $(DESTDIR)$(includedir)/$$x; \+	done++roken_h_c: $(ROKENHC_OBJECTS)+	$(CC) -o $@ $(ROKENHC_OBJECTS)++roken_h: $(ROKENH_OBJECTS)+	$(CC) -o $@ $(ROKENH_OBJECTS)++roken_h.c: roken.hin roken_h_c+	./roken_h_c roken.hin $@++roken.h: roken_h+	./roken_h $@++roken.hin: roken.h.in+	cp -f $< $@  TAGS: $(SOURCES) 	etags $(SOURCES)@@ -129,7 +172,7 @@ check:  clean:-	rm -f $(LIB) *.o *.a+	rm -f $(LIB) $(BUILDHEADERS) $(BUILDSOURCES) *.o *.a  mostlyclean: clean @@ -158,3 +201,5 @@ #	$(LDSHARED) -o $@ $(OBJECTS)  $(OBJECTS): ./../include/config.h+roken_h.o: roken_h.c ./../include/config.h+roken_h_c.o: roken_h_c.c ../../include/config.hOnly in arla-0.25-dist/lib/roken: roken.hdiff -ruP arla-0.25-dist/lib/roken/roken.h.in arla-0.25/lib/roken/roken.h.in--- arla-0.25-dist/lib/roken/roken.h.in	Wed Dec 31 19:00:00 1969+++ arla-0.25/lib/roken/roken.h.in	Tue Jul  6 16:59:31 1999@@ -0,0 +1,494 @@+% Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan+% (Royal Institute of Technology, Stockholm, Sweden).+% All rights reserved.+% +% Redistribution and use in source and binary forms, with or without+% modification, are permitted provided that the following conditions+% are met:+% +% 1. Redistributions of source code must retain the above copyright+%    notice, this list of conditions and the following disclaimer.+% +% 2. Redistributions in binary form must reproduce the above copyright+%    notice, this list of conditions and the following disclaimer in the+%    documentation and/or other materials provided with the distribution.+% +% 3. All advertising materials mentioning features or use of this software+%    must display the following acknowledgement:+%      This product includes software developed by the Kungliga Tekniska+%      Högskolan and its contributors.+% +% 4. Neither the name of the Institute nor the names of its contributors+%    may be used to endorse or promote products derived from this software+%    without specific prior written permission.+% +% THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND+% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+% ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE+% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+% OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+% SUCH DAMAGE.++% $Id: $++#ifndef __ROKEN_H__+#define __ROKEN_H__++#include <stdio.h>+#include <stdlib.h>+#include <stdarg.h>+#include <string.h>+#include <signal.h>+%ifdef HAVE_SYS_PARAM_H+#include <sys/param.h>+%endif+%ifdef HAVE_SYS_TYPES_H+#include <sys/types.h>+%endif+%ifdef HAVE_UNISTD_H+#include <unistd.h>+%endif+%ifdef HAVE_SYS_UIO_H+#include <sys/uio.h>+%endif+%ifdef HAVE_GRP_H+#include <grp.h>+%endif+%ifdef HAVE_SYS_STAT_H+#include <sys/stat.h>+%endif+%ifdef HAVE_SYS_SOCKET_H+#include <sys/socket.h>+%endif+%ifdef HAVE_NETINET_IN_H+#include <netinet/in.h>+%endif+%ifdef HAVE_NETINET_IN6_H+#include <netinet/in6.h>+%endif+%ifdef HAVE_NETINET6_IN6_H+#include <netinet6/in6.h>+%endif++%ifdef HAVE_FCNTL_H+#include <fcntl.h>+%endif++%ifdef HAVE_ERRNO_H+#include <errno.h>+%endif++%ifdef HAVE_TERMIOS_H+#include <termios.h>+%endif++%if defined(HAVE_SYS_IOCTL_H) && SunOS != 4+#include <sys/ioctl.h>+%endif++%ifndef HAVE_SSIZE_T+typedef int ssize_t;  /* XXX real hot stuff */+%endif++%if !defined(HAVE_SETSID) && defined(HAVE__SETSID)+#define setsid _setsid+%endif++%ifndef HAVE_PUTENV+int putenv(const char *string);+%endif++%ifndef HAVE_SETENV+int setenv(const char *var, const char *val, int rewrite);+%endif++%ifndef HAVE_UNSETENV+void unsetenv(const char *name);+%endif++%if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)+char *getusershell(void);+%endif++%ifndef HAVE___ATTRIBUTE__+#define __attribute__(x)+%endif++%ifndef HAVE_SNPRINTF+int snprintf (char *str, size_t sz, const char *format, ..)+     __attribute__ ((format (printf, 3, 4)));+%endif++%ifndef HAVE_VSNPRINTF+int vsnprintf (char *str, size_t sz, const char *format, va_list ap)+     __attribute__((format (printf, 3, 0)));+%endif++%ifndef HAVE_ASPRINTF+int asprintf (char **ret, const char *format, ...)+     __attribute__ ((format (printf, 2, 3)));+%endif++%ifndef HAVE_VASPRINTF+int vasprintf (char **ret, const char *format, va_list ap)+     __attribute__((format (printf, 2, 0)));+%endif++%ifndef HAVE_ASNPRINTF+int asnprintf (char **ret, size_t max_sz, const char *format, ...)+     __attribute__ ((format (printf, 3, 4)));+%endif++%ifndef HAVE_VASNPRINTF+int vasnprintf (char **ret, size_t max_sz, const char *format, va_list ap)+     __attribute__((format (printf, 3, 0)));+%endif++%ifndef HAVE_STRDUP+char * strdup(const char *old);+%endif++%ifndef HAVE_STRLWR+char * strlwr(char *);+%endif++%ifndef HAVE_STRNLEN+int strnlen(char*, int);+%endif++%ifndef HAVE_STRSEP+char *strsep(char**, const char*);+%endif++%ifdef NEED_FCLOSE_PROTO+int fclose(FILE *);+%endif++%ifdef NEED_STRTOK_R_PROTO+char *strtok_r(char *s1, const char *s2, char **lasts);+%endif++%ifndef HAVE_STRUPR+char * strupr(char *);+%endif++%ifndef HAVE_GETDTABLESIZE+int getdtablesize(void);+%endif++#if IRIX != 4 /* fix for compiler bug */+#ifdef RETSIGTYPE+typedef RETSIGTYPE (*SigAction)(/* int??? */);+SigAction signal(int iSig, SigAction pAction); /* BSD compatible */+#endif+#endif++#ifndef SIG_ERR+#define SIG_ERR ((RETSIGTYPE (*)())-1)+#endif++%if !defined(HAVE_STRERROR) && !defined(strerror)+char *strerror(int eno);+%endif++%ifdef NEED_HSTRERROR_PROTO+%ifdef NEED_HSTRERROR_CONST+const+%endif+char *hstrerror(int herr);+%endif++%ifndef HAVE_H_ERRNO_DECLARATION+extern int h_errno;+%endif++%if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)+int inet_aton(const char *cp, struct in_addr *adr);+%endif++%if !defined(HAVE_GETCWD)+char* getcwd(char *path, size_t size);+%endif++%ifdef HAVE_PWD_H+#include <pwd.h>+struct passwd *k_getpwnam (char *user);+struct passwd *k_getpwuid (uid_t uid);+%endif++%ifndef HAVE_SETEUID+int seteuid(uid_t euid);+%endif++%ifndef HAVE_SETEGID+int setegid(gid_t egid);+%endif++%ifndef HAVE_LSTAT+int lstat(const char *path, struct stat *buf);+%endif++%ifndef HAVE_MKSTEMP+int mkstemp(char *);+%endif++%ifndef HAVE_INITGROUPS+int initgroups(const char *name, gid_t basegid);+%endif++%ifndef HAVE_FCHOWN+int fchown(int fd, uid_t owner, gid_t group);+%endif++%ifndef HAVE_CHOWN+int chown(const char *path, uid_t owner, gid_t group);+%endif++%ifndef HAVE_RCMD+int rcmd(char **ahost, unsigned short inport, const char *locuser,+	 const char *remuser, const char *cmd, int *fd2p);+%endif++%ifndef HAVE_STRUCT_IOVEC+struct iovec {+  void		*iov_base;+  size_t	 iov_len;+};+%endif++%ifndef HAVE_WRITEV+ssize_t+writev(int d, const struct iovec *iov, int iovcnt);+%endif++%ifndef HAVE_READV+ssize_t+readv(int d, const struct iovec *iov, int iovcnt);+%endif++%ifndef HAVE_STRUCT_MSGHDR+struct msghdr {+  void		*msg_name;+  size_t	 msg_namelen;+  struct iovec	*msg_iov;+  int		 msg_iovlen;+  void		*msg_control;+  size_t	 msg_controllen;+  int		 msg_flags;+};+%endif++%ifndef HAVE_RECVMSG+ssize_t+recvmsg(int s, struct msghdr *msg, int flags);+%endif++%ifndef HAVE_SENDMSG+ssize_t+sendmsg(int s, const struct msghdr *msg, int flags);+%endif++%ifndef HAVE_FLOCK+#ifndef LOCK_SH+#define LOCK_SH   1		/* Shared lock */+#endif+#ifndef	LOCK_EX+#define LOCK_EX   2		/* Exclusive lock */+#endif+#ifndef LOCK_NB+#define LOCK_NB   4		/* Don't block when locking */+#endif+#ifndef LOCK_UN+#define LOCK_UN   8		/* Unlock */+#endif++int flock(int fd, int operation);+%endif /* HAVE_FLOCK */++%ifdef TIME_WITH_SYS_TIME+#include <sys/time.h>+#include <time.h>+%elif defined(HAVE_SYS_TIME_H)+#include <sys/time.h>+%else+#include <time.h>+%endif++time_t tm2time (struct tm tm, int local);++int unix_verify_user(char *user, char *password);++void inaddr2str(struct in_addr addr, char *s, size_t len);++void mini_inetd (int port);++%ifndef HAVE_STRUCT_WINSIZE+struct winsize {+	unsigned short ws_row, ws_col;+	unsigned short ws_xpixel, ws_ypixel;+};+%endif++int get_window_size(int fd, struct winsize *);++#ifndef INADDR_NONE+#define INADDR_NONE 0xffffffff+#endif++#ifndef SOMAXCONN+#define SOMAXCONN 5+#endif++#ifndef STDIN_FILENO+#define STDIN_FILENO 0+#endif++#ifndef STDOUT_FILENO+#define STDOUT_FILENO 1+#endif++#ifndef STDERR_FILENO+#define STDERR_FILENO 2+#endif++#ifndef max+#define max(a,b) (((a)>(b))?(a):(b))+#endif++#ifndef min+#define min(a,b) (((a)<(b))?(a):(b))+#endif++#ifndef TRUE+#define TRUE 1+#endif++#ifndef FALSE+#define FALSE 0+#endif++%ifdef HAVE_SYSLOG_H+#include <syslog.h>+/* Misc definitions for old syslogs */++#ifndef LOG_DAEMON+#define openlog(id,option,facility) openlog((id),(option))+#define	LOG_DAEMON	0+#endif+#ifndef LOG_ODELAY+#define LOG_ODELAY 0+#endif+#ifndef LOG_NDELAY+#define LOG_NDELAY 0x08+#endif+#ifndef LOG_CONS+#define LOG_CONS 0+#endif+#ifndef LOG_AUTH+#define LOG_AUTH 0+#endif+#ifndef LOG_AUTHPRIV+#define LOG_AUTHPRIV LOG_AUTH+#endif+%endif++%ifndef HAVE_VSYSLOG+void vsyslog(int pri, const char *fmt, va_list ap);+%endif++%ifndef HAVE_OPTARG_DECLARATION+extern char *optarg;+%endif+%ifndef HAVE_OPTIND_DECLARATION+extern int optind;+%endif+%ifndef HAVE_OPTERR_DECLARATION+extern int opterr;+%endif++%ifndef HAVE___PROGNAME_DECLARATION+extern const char *__progname;+%endif++/*+ * kludges and such+ */++%ifdef GETHOSTBYNAME_PROTO_COMPATIBLE+#define roken_gethostbyname(x) gethostbyname(x)+%else+#define roken_gethostbyname(x) gethostbyname((char *)x)+%endif++%ifdef GETHOSTBYADDR_PROTO_COMPATIBLE+#define roken_gethostbyaddr(a, l, t) gethostbyaddr(a, l, t)+%else+#define roken_gethostbyaddr(a, l, t) gethostbyaddr((char *)a, l, t)+%endif++%ifdef GETSERVBYNAME_PROTO_COMPATIBLE+#define roken_getservbyname(x,y) getservbyname(x,y)+%else+#define roken_getservbyname(x,y) getservbyname((char *)x, (char *)y)+%endif++%ifdef OPENLOG_PROTO_COMPATIBLE+#define roken_openlog(a,b,c) openlog(a,b,c)+%else+#define roken_openlog(a,b,c) openlog((char *)a,b,c)+%endif++void set_progname(char *argv0);++#ifndef F_OK+#define F_OK 0+#endif++#ifndef O_ACCMODE+#define O_ACCMODE	003+#endif++#ifndef O_BINARY+#define O_BINARY	0+#endif++%ifdef HAVE_PATHS_H+#include <paths.h>+%endif++#ifndef _PATH_DEVNULL+#define _PATH_DEVNULL \"/dev/null\"+#endif++#ifndef MAXPATHLEN+#define MAXPATHLEN (1024+4)+#endif+++%ifdef NEED_SELECT_PROTO+int+select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,+       struct timeval *timeout);+%endif++%ifdef HAVE_REPAIRABLE_HTONL+#define htonl(x) __cpu_to_be32(x)+#define ntohl(x) __be32_to_cpu(x)+#define htons(x) __cpu_to_be16(x)+#define ntohs(x) __be16_to_cpu(x)+%endif++#if !defined(NSIG) && defined(_NSIG)+#define NSIG _NSIG+#endif++void *emalloc (size_t sz);+void *erealloc (void *ptr, size_t sz);+char *estrdup (const char *);++#endif /*  __ROKEN_H__ */diff -ruP arla-0.25-dist/lib/roken/roken_h_c.c arla-0.25/lib/roken/roken_h_c.c--- arla-0.25-dist/lib/roken/roken_h_c.c	Wed Dec 31 19:00:00 1969+++ arla-0.25/lib/roken/roken_h_c.c	Tue Jul  6 16:59:31 1999@@ -0,0 +1,154 @@+/*+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan+ * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + *+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + *+ * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + *+ * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + *+ * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *      This product includes software developed by Kungliga Tekniska + *      Högskolan and its contributors. + *+ * 4. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + *+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */++#ifdef HAVE_CONFIG_H+#include <config.h>+#endif+#include <errno.h>+#include <stdio.h>+#include <string.h>+#include <stdlib.h>+#include <ctype.h>++int main(int argc, char **argv)+{+    char *fn, *in_fn, buf[1024];+    FILE *f, *in_f;+    int l;++    if (argc < 2) {+	in_fn = "<stdin>";+	in_f = stdin;+    } else {+	in_fn = argv[1];+	in_f = fopen(argv[1], "r");+	if (!in_f) {+		fprintf(stderr, "%s: %s\n", in_fn, strerror(errno));+		exit(1);+	}+    }+    if (argc < 3) {+	fn = "roken_h.c";+	f = stdout;+    } else {+	fn = argv[2];+	f = fopen(argv[2], "w");+	if (!f) {+		fprintf(stderr, "%s: %s\n", in_fn, strerror(errno));+		exit(1);+	}+    }+    fprintf(f, "/* %s -- this file was generated for %s\n", fn, HOST);+    fprintf(f, " * %*s    from %s\n", strlen(fn), "", in_fn);+    fprintf(f, " * %*s    by %s\n", strlen(fn), "", +	    "$Id: $");+    fprintf(f, " */\n");++    fputs("\n#ifdef HAVE_CONFIG_H\n"+          "#include <config.h>\n"+          "#endif\n"+          "#include <errno.h>\n"+          "#include <stdio.h>\n"+          "#include <string.h>\n"+          "#include <stdlib.h>\n"+          "#include <ctype.h>\n"+          "\n"+          "int main(int argc, char **argv)\n"+          "{\n" "    FILE *f;\n"+          "    char *fn, *hb;\n"+          "    \n"+          "    if (argc < 2) {\n"+          "	fn = \"roken.h\";\n"+          "	hb = \"__ROKEN_H__\";\n"+          "	f = stdout;\n"+          "    } else {\n"+          "	char *p;\n"+          "	fn = argv[1];\n"+          "	hb = malloc(strlen(fn) + 5);\n"+          "	sprintf(hb, \"__%s__\", fn);\n"+          "	for(p = hb; *p; p++){\n"+          "	    if(!isalnum((int)*p))\n"+          "		*p = '_';\n"+          "	}\n"+          "	f = fopen(argv[1], \"w\");\n"+          "	if (!f) {\n"+          "		fprintf(stderr, \"%s: %s\\n\", fn, strerror(errno));\n"+          "		exit(1);\n"+          "	}\n"+          "    }\n",+          f);++    fprintf(f, "    fprintf(f, \"%s\", fn, HOST);\n",+               "/* %s -- this file was generated for %s by\\n");++    fprintf(f, "    fprintf(f, \"%s\", strlen(fn), \"\", \"%s\");\n",+               " * %*s    by %s\\n", fn);++    fprintf(f, "    fprintf(f, \"%s\", strlen(fn), \"\", \"%s\");\n",+               " * %*s    [by %s]\\n",+	     "$Id: $");++    fprintf(f, "    fprintf(f, \"%s\", strlen(fn), \"\", \"%s\");\n",+               " * %*s    [from %s]\\n", in_fn);++    fprintf(f, "    fprintf(f, \" */\\n\");\n");++    fprintf(f, "    fprintf(f, \"#ifndef %%s\\n\", hb);\n"+               "    fprintf(f, \"#define %%s\\n\", hb);\n"+               "    fprintf(f, \"\\n\");\n");++    while (fgets(buf, 1024, in_f)) {+	if (buf[0] == '%' && buf[1] == ' ') continue;+	if (buf[0] == '%') {+	    buf[0] = '#';+	    fputs(buf, f);+	} else {+	    l = strlen(buf);+	    if (l && buf[l-1] == '\n') buf[l-1] = 0;+	    fprintf(f, "  fputs(\"%s\\n\", f);\n", buf);+	}+    }++    fputs("    fprintf(f, \"\\n\");\n"+          "    fprintf(f, \"#endif /* %s */\\n\", hb);\n"+          "    return 0;\n"+          "}\n",+    f);++    return 0;+}




More information about the Arla-drinkers mailing list