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");
 }

Reply via email to