summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2014-02-07 18:29:53 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2014-02-07 18:29:53 (GMT)
commit548e46e7de424c06743d844fc35b091982d5bee5 (patch) (side-by-side diff)
tree9e6e118d80a6e2d3fa52fca87c16ea453b378f58
parent4be79061e8f68f6e3174a05452d96f31e8062464 (diff)
downloadcflow-548e46e7de424c06743d844fc35b091982d5bee5.tar.gz
cflow-548e46e7de424c06743d844fc35b091982d5bee5.tar.bz2
Use exit codes consistently.
* doc/cflow.1: Document exit codes. * doc/cflow.texi: Likewise. * src/cflow.h: Define exit code constants. * src/main.c: Use exit codes consistently. * src/output.c: Likewise. * src/parser.c: Likewise. * src/posix.c: Likewise. * src/rc.c: Likewise.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--doc/cflow.112
-rw-r--r--doc/cflow.texi16
-rw-r--r--src/cflow.h6
-rw-r--r--src/main.c60
-rw-r--r--src/output.c2
-rw-r--r--src/parser.c6
-rw-r--r--src/posix.c3
-rw-r--r--src/rc.c13
8 files changed, 75 insertions, 43 deletions
diff --git a/doc/cflow.1 b/doc/cflow.1
index bf6923d..592482a 100644
--- a/doc/cflow.1
+++ b/doc/cflow.1
@@ -224,6 +224,18 @@ Print a summary of available options.
\fB\-V\fR, \fB\-\-version\fR
Print program version.
.SH "RETURN VALUE"
+.TP
+.B 0
+Successful completion.
+.TP
+.B 1
+Fatal error occurred.
+.TP
+.B 2
+Some input files cannot be read or parsed.
+.TP
+.B 3
+Command line usage error.
.SH "SEE ALSO"
Online copies of \fBGNU cflow\fR documentation in various formats can be
found at:
diff --git a/doc/cflow.texi b/doc/cflow.texi
index a9f2313..cb9326c 100644
--- a/doc/cflow.texi
+++ b/doc/cflow.texi
@@ -75,6 +75,7 @@ documents GNU cflow Version @value{VERSION}.
* Configuration:: Configuration Files and Variables.
* Makefiles:: Using @command{cflow} in Makefiles.
* Options:: Complete Listing of @command{cflow} Options.
+* Exit Codes:: Exit Codes,
* Emacs:: Using @command{cflow} with GNU Emacs.
* Reporting Bugs:: How to Report a Bug.
@@ -1449,6 +1450,21 @@ sources.
Print program version.
@end table
+@node Exit Codes
+@chapter Exit Codes
+@cindex exit codes
+
+@table @asis
+@item 0
+Successful completion.
+@item 1
+Fatal error occurred.
+@item 2
+Some input files cannot be read or parsed.
+@item 3
+Command line usage error.
+@end table
+
@node Emacs
@chapter Using @command{cflow} with GNU Emacs.
@cindex cflow-mode introduced
diff --git a/src/cflow.h b/src/cflow.h
index 28ba0db..e60d222 100644
--- a/src/cflow.h
+++ b/src/cflow.h
@@ -41,6 +41,12 @@
# define setlocale(category, locale) /* empty */
#endif
+/* Exit codes */
+#define EX_OK 0 /* Success */
+#define EX_FATAL 1 /* Fatal error */
+#define EX_SOFT 2 /* Some input files cannot be read or parsed */
+#define EX_USAGE 3 /* Command line usage error */
+
#define NUMITEMS(a) sizeof(a)/sizeof((a)[0])
struct linked_list_entry {
diff --git a/src/main.c b/src/main.c
index e78993a..4facaf5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -260,10 +260,9 @@ symbol_override(const char *str)
Symbol *sp;
ptr = strchr(str, ':');
- if (!ptr) {
- error(0, 0, _("%s: no symbol type supplied"), str);
- return;
- } else {
+ if (!ptr)
+ error(EX_USAGE, 0, _("%s: no symbol type supplied"), str);
+ else {
name = strndup(str, ptr - str);
if (ptr[1] == '=') {
Symbol *alias = lookup(ptr+2);
@@ -281,10 +280,8 @@ symbol_override(const char *str)
sp->flag = symbol_alias;
} else {
int type = find_option_type(symbol_optype, ptr+1, 0);
- if (type == 0) {
- error(0, 0, _("unknown symbol type: %s"), ptr+1);
- return;
- }
+ if (type == 0)
+ error(EX_USAGE, 0, _("unknown symbol type: %s"), ptr+1);
sp = install(name, INSTALL_OVERWRITE);
sp->type = SymToken;
sp->token_type = type;
@@ -310,7 +307,7 @@ set_print_option(char *str)
opt = find_option_type(print_optype, str, 0);
if (opt == 0) {
- error(0, 0, _("unknown print option: %s"), str);
+ error(EX_USAGE, 0, _("unknown print option: %s"), str);
return;
}
print_option |= opt;
@@ -432,19 +429,16 @@ parse_level_string(const char *str, char **return_ptr)
c = p[-1];
for (i = 1; i < num; i++) {
*p++ = c;
- if (*p == 0) {
- error(1, 0, _("level indent string is too long"));
- return;
- }
+ if (*p == 0)
+ error(EX_USAGE, 0,
+ _("level indent string is too long"));
}
break;
default:
copy:
*p++ = *str++;
- if (*p == 0) {
- error(1, 0, _("level indent string is too long"));
- return;
- }
+ if (*p == 0)
+ error(EX_USAGE, 0, _("level indent string is too long"));
}
}
*p = 0;
@@ -469,10 +463,8 @@ set_level_indent(const char *str)
p = str;
while (*p != '=') {
- if (*p == 0) {
- error(1, 0, _("level-indent syntax"));
- return;
- }
+ if (*p == 0)
+ error(EX_USAGE, 0, _("level-indent syntax"));
p++;
}
++p;
@@ -494,7 +486,7 @@ set_level_indent(const char *str)
parse_level_string(p, &level_end[1]);
break;
default:
- error(1, 0, _("unknown level indent option: %s"), str);
+ error(EX_USAGE, 0, _("unknown level indent option: %s"), str);
}
}
@@ -571,7 +563,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'f':
if (select_output_driver(arg))
- argp_error(state, _("%s: No such output driver"), optarg);
+ error(EX_USAGE, 0, _("%s: No such output driver"), optarg);
output_init();
break;
case OPT_LEVEL_INDENT:
@@ -599,7 +591,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
SYMBOL_EXCLUDE(*arg);
break;
default:
- argp_error(state, _("Unknown symbol class: %c"), *arg);
+ error(EX_USAGE, 0, _("Unknown symbol class: %c"), *arg);
}
break;
case OPT_OMIT_ARGUMENTS:
@@ -726,7 +718,7 @@ include_symbol(Symbol *sym)
void
xalloc_die(void)
{
- error(1, ENOMEM, _("Exiting"));
+ error(EX_FATAL, ENOMEM, _("Exiting"));
}
void
@@ -755,7 +747,8 @@ int
main(int argc, char **argv)
{
int index;
-
+ int status = EX_OK;
+
set_program_name(argv[0]);
argp_version_setup("cflow", program_authors);
@@ -769,14 +762,17 @@ main(int argc, char **argv)
symbol_map = SM_FUNCTIONS|SM_STATIC|SM_UNDEFINED;
if (getenv("POSIXLY_CORRECT")) {
- if (select_output_driver("posix"))
- error(1, 0, _("%s: No such output driver"), "posix");
+ if (select_output_driver("posix")) {
+ error(0, 0, _("INTERNAL ERROR: %s: No such output driver"),
+ "posix");
+ abort();
+ }
output_init();
}
sourcerc(&argc, &argv);
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
- exit(1);
+ exit(EX_USAGE);
if (print_option == 0)
print_option = PRINT_TREE;
@@ -801,13 +797,15 @@ main(int argc, char **argv)
while (argc--) {
if (source(*argv++) == 0)
yyparse();
+ else
+ status = EX_SOFT;
}
if (input_file_count == 0)
- error(1, 0, _("no input files"));
+ error(EX_USAGE, 0, _("no input files"));
output();
- return 0;
+ return status;
}
diff --git a/src/output.c b/src/output.c
index d46b496..2def906 100644
--- a/src/output.c
+++ b/src/output.c
@@ -419,7 +419,7 @@ output()
} else {
outfile = fopen(outname, "w");
if (!outfile)
- error(2, errno, _("cannot open file `%s'"), outname);
+ error(EX_FATAL, errno, _("cannot open file `%s'"), outname);
}
set_level_mark(0, 0);
diff --git a/src/parser.c b/src/parser.c
index be82197..c26cd9c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -307,8 +307,10 @@ nexttoken()
int
putback()
{
- if (curs == 0)
- error(10, 0, _("INTERNAL ERROR: cannot return token to stream"));
+ if (curs == 0) {
+ error(0, 0, _("INTERNAL ERROR: cannot return token to stream"));
+ abort();
+ }
curs--;
if (curs > 0) {
tok = token_stack[curs-1];
diff --git a/src/posix.c b/src/posix.c
index d0caac8..4a63183 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -55,7 +55,8 @@ posix_output_handler(cflow_output_command cmd,
case cflow_output_init:
/* Additional check for consistency */
if (emacs_option)
- error(1, 0, _("--format=posix is not compatible with --emacs"));
+ error(EX_USAGE, 0,
+ _("--format=posix is not compatible with --emacs"));
brief_listing = print_line_numbers = omit_symbol_names_option = 1;
break;
case cflow_output_begin:
diff --git a/src/rc.c b/src/rc.c
index 7586975..97cbca7 100644
--- a/src/rc.c
+++ b/src/rc.c
@@ -52,14 +52,10 @@ parse_rc(int *argc_ptr, char ***argv_ptr, char *name)
if (stat(name, &st))
return;
- buf = malloc(st.st_size+1);
- if (!buf) {
- error(0, 0, _("not enough memory to process rc file"));
- return;
- }
+ buf = xmalloc(st.st_size+1);
rcfile = fopen(name, "r");
if (!rcfile) {
- error(0, errno, _("cannot open `%s'"), name);
+ error(EX_FATAL, errno, _("cannot open `%s'"), name);
return;
}
size = fread(buf, 1, st.st_size, rcfile);
@@ -72,7 +68,8 @@ parse_rc(int *argc_ptr, char ***argv_ptr, char *name)
for (p = strtok(buf, "\n"); p; p = strtok(NULL, "\n")) {
++line;
if (wordsplit(p, &ws, wsflags))
- error(1, 0, "%s:%d: %s", name, line, wordsplit_strerror(&ws));
+ error(EX_FATAL, 0, "%s:%d: %s",
+ name, line, wordsplit_strerror(&ws));
wsflags |= WRDSF_REUSE;
if (ws.ws_wordc)
expand_argcv(argc_ptr, argv_ptr, ws.ws_wordc, ws.ws_wordv);
@@ -107,7 +104,7 @@ sourcerc(int *argc_ptr, char ***argv_ptr)
ws.ws_comment = "#";
if (wordsplit(env, &ws, WRDSF_DEFFLAGS | WRDSF_COMMENT))
- error(1, 0, "failed to parse CFLOW_OPTIONS: %s",
+ error(EX_FATAL, 0, "failed to parse CFLOW_OPTIONS: %s",
wordsplit_strerror(&ws));
if (ws.ws_wordc)
expand_argcv(&xargc, &xargv, ws.ws_wordc, ws.ws_wordv);

Return to:

Send suggestions and report system problems to the System administrator.