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).
This commit is contained in:
ginsbach 2009-06-11 03:16:34 +00:00
parent 0a833e378f
commit 2248a77687
2 changed files with 67 additions and 8 deletions

View File

@ -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 would be rude to strip them out, just as it would be for normal comments.
.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

View File

@ -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 @@ static const char copyright[] =
#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 @@ __FBSDID("$FreeBSD: src/usr.bin/unifdef/unifdef.c,v 1.18 2003/07/01 15:30:43 fan
#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 bool ignore[MAXSYMS]; /* -iDsym or -iUsym */
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 @@ int
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 @@ main(int argc, char *argv[])
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 @@ main(int argc, char *argv[])
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 @@ main(int argc, char *argv[])
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 @@ done(void)
{
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 @@ flushline(bool keep)
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 @@ error(const char *msg)
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");
}