Module Name: src
Committed By: ginsbach
Date: Thu Jun 11 03:16:34 UTC 2009
Modified Files:
src/usr.bin/unifdef: unifdef.1 unifdef.c
Log Message:
Add -o output option, which can be used to specify an output file. The
file can even be the same as the input file. Idea from IRIX unifdef(1).
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/unifdef/unifdef.1
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/unifdef/unifdef.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/unifdef/unifdef.1
diff -u src/usr.bin/unifdef/unifdef.1:1.11 src/usr.bin/unifdef/unifdef.1:1.12
--- src/usr.bin/unifdef/unifdef.1:1.11 Tue Nov 11 13:48:50 2003
+++ src/usr.bin/unifdef/unifdef.1 Thu Jun 11 03:16:34 2009
@@ -1,4 +1,4 @@
-.\" $NetBSD: unifdef.1,v 1.11 2003/11/11 13:48:50 wiz Exp $
+.\" $NetBSD: unifdef.1,v 1.12 2009/06/11 03:16:34 ginsbach Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -65,7 +65,7 @@
.\" $dotat: things/unifdef.1,v 1.45 2003/01/20 14:37:08 fanf2 Exp $
.\" $FreeBSD: src/usr.bin/unifdef/unifdef.1,v 1.19 2003/01/20 12:41:41 fanf Exp $
.\"
-.Dd September 24, 2002
+.Dd June 5, 2009
.Dt UNIFDEF 1
.Os
.Sh NAME
@@ -81,6 +81,7 @@
.Op Fl iD Ns Ar sym Ns Op = Ns Ar val
.Op Fl iU Ns Ar sym
.Ar ...
+.Op Fl o Ar output
.Op Ar file
.Nm unifdefall
.Op Fl I Ns Ar path
@@ -212,6 +213,11 @@
.It Fl l
Replace removed lines with blank lines
instead of deleting them.
+.It Fl o Ar output
+The argument given is the name of an
+.Ar output
+file to be used instead of the standard output.
+This file can be the same as the input file.
.It Fl s
Instead of processing the input file as usual,
this option causes
Index: src/usr.bin/unifdef/unifdef.c
diff -u src/usr.bin/unifdef/unifdef.c:1.13 src/usr.bin/unifdef/unifdef.c:1.14
--- src/usr.bin/unifdef/unifdef.c:1.13 Sun Apr 30 23:56:42 2006
+++ src/usr.bin/unifdef/unifdef.c Thu Jun 11 03:16:34 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: unifdef.c,v 1.13 2006/04/30 23:56:42 christos Exp $ */
+/* $NetBSD: unifdef.c,v 1.14 2009/06/11 03:16:34 ginsbach Exp $ */
/*
* Copyright (c) 1985, 1993
@@ -77,7 +77,7 @@
#endif
#ifdef __IDSTRING
__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93");
-__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.13 2006/04/30 23:56:42 christos Exp $");
+__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.14 2009/06/11 03:16:34 ginsbach Exp $");
__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.161 2003/07/01 15:32:48 fanf2 Exp $");
#endif
#endif /* not lint */
@@ -102,12 +102,16 @@
#include <ctype.h>
#include <err.h>
+#include <libgen.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
#include "stdbool.h"
/* types of input lines: */
@@ -216,8 +220,12 @@
static int nsyms; /* number of symbols */
static FILE *input; /* input file pointer */
+static FILE *output; /* output file pointer */
static const char *filename; /* input file name */
+static char *ofilename; /* output file name */
+static char tmpname[MAXPATHLEN]; /* used when overwriting */
static int linenum; /* current line number */
+static int overwriting; /* output overwrites input */
static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
static char *keyword; /* used for editing #elif's */
@@ -260,8 +268,9 @@
main(int argc, char *argv[])
{
int opt;
+ struct stat isb, osb;
- while ((opt = getopt(argc, argv, "i:D:U:I:cdeklst")) != -1)
+ while ((opt = getopt(argc, argv, "i:D:U:I:o:cdeklst")) != -1)
switch (opt) {
case 'i': /* treat stuff controlled by these symbols as text */
/*
@@ -301,6 +310,9 @@
case 'l': /* blank deleted lines instead of omitting them */
lnblank = true;
break;
+ case 'o': /* output to a file */
+ ofilename = optarg;
+ break;
case 's': /* only output list of symbols that control #ifs */
symlist = true;
break;
@@ -327,6 +339,32 @@
filename = "[stdin]";
input = stdin;
}
+ if (ofilename == NULL) {
+ output = stdout;
+ } else {
+ if (stat(ofilename, &osb) != 0)
+ err(2, "can't stat %s", ofilename);
+ if (fstat(fileno(input), &isb) != 0)
+ err(2, "can't fstat %s", filename);
+
+ overwriting = (osb.st_dev == isb.st_dev &&
+ osb.st_ino == osb.st_ino);
+ if (overwriting) {
+ int ofd;
+
+ snprintf(tmpname, sizeof(tmpname), "%s/unifdef.XXXXXX",
+ dirname(ofilename));
+ if ((ofd = mkstemp(tmpname)) != -1)
+ output = fdopen(ofd, "w+");
+ if (output == NULL)
+ err(2, "can't create temporary file");
+ fchmod(ofd, isb.st_mode & ACCESSPERMS);
+ } else {
+ output = fopen(ofilename, "w");
+ if (output == NULL)
+ err(2, "can't open %s", ofilename);
+ }
+ }
process();
abort(); /* bug */
}
@@ -334,7 +372,7 @@
static void
usage(void)
{
- fprintf(stderr, "usage: unifdef [-cdeklst]"
+ fprintf(stderr, "usage: unifdef [-cdeklst] [-o output]"
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
exit(2);
}
@@ -465,6 +503,16 @@
{
if (incomment)
error("EOF in comment");
+ if (fclose(output)) {
+ if (overwriting) {
+ unlink(tmpname);
+ errx(2, "%s unchanged", filename);
+ }
+ }
+ if (overwriting && rename(tmpname, filename)) {
+ unlink(tmpname);
+ errx(2, "%s unchanged", filename);
+ }
exit(exitstat);
}
static void
@@ -506,10 +554,10 @@
if (symlist)
return;
if (keep ^ complement)
- fputs(tline, stdout);
+ fputs(tline, output);
else {
if (lnblank)
- putc('\n', stdout);
+ putc('\n', output);
exitstat = 1;
}
}
@@ -983,5 +1031,10 @@
else
warnx("%s: %d: %s (#if line %d depth %d)",
filename, linenum, msg, stifline[depth], depth);
+ fclose(output);
+ if (overwriting) {
+ unlink(tmpname);
+ errx(2, "%s unchanged", filename);
+ }
errx(2, "output may be truncated");
}