fix: implemented errmsg
feat: implemented errmsg
This commit is contained in:
parent
3e1bf8ba92
commit
c1c2feb549
|
@ -5,15 +5,36 @@
|
||||||
/* Adam M. Costello */
|
/* Adam M. Costello */
|
||||||
/*********************/
|
/*********************/
|
||||||
|
|
||||||
/* This is ANSI C code. */
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
/**
|
||||||
|
* @brief Set an error indication, with a specified error message.
|
||||||
|
* @param msg Pointer to the error message. The string passed by the caller
|
||||||
|
* will be copied.
|
||||||
|
*/
|
||||||
|
void set_error(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test whether there is currently an error indication.
|
||||||
|
* @return 1 if an error indication currently exists, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int is_error();
|
||||||
|
|
||||||
extern char errmsg[163];
|
/**
|
||||||
|
* @brief Issue any existing error message to the specified output stream.
|
||||||
|
* @param file Stream to which the error message is to be issued.
|
||||||
|
* @return 0 if either there was no existing error message, or else there
|
||||||
|
* was an existing error message and it was successfully output.
|
||||||
|
* Return non-zero if the attempt to output an existing error message
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
int report_error(FILE *file);
|
||||||
|
|
||||||
/* Any function which uses errmsg must, before returning, */
|
/**
|
||||||
/* either set errmsg[0] to '\0' (indicating success), or */
|
* Clear any existing error indication and free storage occupied by
|
||||||
/* write an error message string into errmsg, (indicating */
|
* any existing error message.
|
||||||
/* failure), being careful not to overrun the space. */
|
*/
|
||||||
|
void clear_error();
|
||||||
|
static char * outofmem;
|
||||||
extern const char * const outofmem; /* "Out of memory.\n" */
|
|
|
@ -57,7 +57,7 @@ struct buffer *newbuffer(size_t itemsize)
|
||||||
blk = (struct block *) malloc(sizeof (struct block));
|
blk = (struct block *) malloc(sizeof (struct block));
|
||||||
items = malloc(maxhere * itemsize);
|
items = malloc(maxhere * itemsize);
|
||||||
if (!buf || !blk || !items) {
|
if (!buf || !blk || !items) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto nberror;
|
goto nberror;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ struct buffer *newbuffer(size_t itemsize)
|
||||||
blk->items = items;
|
blk->items = items;
|
||||||
blk->next = NULL;
|
blk->next = NULL;
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
nberror:
|
nberror:
|
||||||
|
@ -123,7 +123,7 @@ void additem(struct buffer *buf, const void *item)
|
||||||
new = (struct block * ) malloc(sizeof (struct block));
|
new = (struct block * ) malloc(sizeof (struct block));
|
||||||
items = malloc(maxhere * itemsize);
|
items = malloc(maxhere * itemsize);
|
||||||
if (!new || !items) {
|
if (!new || !items) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto aierror;
|
goto aierror;
|
||||||
}
|
}
|
||||||
blk->next = new;
|
blk->next = new;
|
||||||
|
@ -140,7 +140,7 @@ void additem(struct buffer *buf, const void *item)
|
||||||
|
|
||||||
++blk->numhere;
|
++blk->numhere;
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aierror:
|
aierror:
|
||||||
|
@ -169,7 +169,7 @@ void *copyitems(struct buffer *buf)
|
||||||
|
|
||||||
r = malloc(n * itemsize);
|
r = malloc(n * itemsize);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ void *copyitems(struct buffer *buf)
|
||||||
memcpy( ((char *) r) + (blk->numprevious * itemsize),
|
memcpy( ((char *) r) + (blk->numprevious * itemsize),
|
||||||
blk->items, blk->numhere * itemsize);
|
blk->items, blk->numhere * itemsize);
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,35 @@
|
||||||
|
|
||||||
|
|
||||||
#include "errmsg.h" /* Makes sure we're consistent with the declarations. */
|
#include "errmsg.h" /* Makes sure we're consistent with the declarations. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static char *errmsg = NULL;
|
||||||
|
|
||||||
char errmsg[163];
|
void set_error(char *msg)
|
||||||
|
{
|
||||||
|
errmsg = strdup(msg);
|
||||||
|
}
|
||||||
|
|
||||||
const char * const outofmem = "Out of memory.\n";
|
int is_error() {
|
||||||
|
return errmsg ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int report_error(FILE *file) {
|
||||||
|
if (is_error())
|
||||||
|
{
|
||||||
|
return fputs(errmsg, file) < 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_error() {
|
||||||
|
if (is_error())
|
||||||
|
{
|
||||||
|
free(errmsg);
|
||||||
|
errmsg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static char *outofmem = "Out of memory.\n";
|
||||||
|
|
|
@ -80,11 +80,19 @@ static void parseopt(
|
||||||
const char *saveopt = opt;
|
const char *saveopt = opt;
|
||||||
char oc;
|
char oc;
|
||||||
int n, r;
|
int n, r;
|
||||||
|
FILE *stream;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (*opt == '-') ++opt;
|
if (*opt == '-') ++opt;
|
||||||
|
|
||||||
if (!strcmp(opt, "version")) {
|
if (!strcmp(opt, "version")) {
|
||||||
sprintf(errmsg, "%s %s\n", progname, version);
|
stream = open_memstream(&buf, &len);
|
||||||
|
fprintf(stream, "%s %s\n", progname, version);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,11 +123,16 @@ static void parseopt(
|
||||||
else goto badopt;
|
else goto badopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
badopt:
|
badopt:
|
||||||
sprintf(errmsg, "Bad option: %.149s\n", saveopt);
|
stream = open_memstream(&buf, &len);
|
||||||
|
fprintf(stream,"Bad option: %.149s\n", saveopt);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,9 +148,9 @@ static char **readlines(void)
|
||||||
char ch, *ln, *nullline = NULL, nullchar = '\0', **lines = NULL;
|
char ch, *ln, *nullline = NULL, nullchar = '\0', **lines = NULL;
|
||||||
|
|
||||||
cbuf = newbuffer(sizeof (char));
|
cbuf = newbuffer(sizeof (char));
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
pbuf = newbuffer(sizeof (char *));
|
pbuf = newbuffer(sizeof (char *));
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
|
|
||||||
for (blank = 1; ; ) {
|
for (blank = 1; ; ) {
|
||||||
c = getchar();
|
c = getchar();
|
||||||
|
@ -148,11 +161,11 @@ static char **readlines(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
additem(cbuf, &nullchar);
|
additem(cbuf, &nullchar);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
ln = copyitems(cbuf);
|
ln = copyitems(cbuf);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
additem(pbuf, &ln);
|
additem(pbuf, &ln);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
clearbuffer(cbuf);
|
clearbuffer(cbuf);
|
||||||
blank = 1;
|
blank = 1;
|
||||||
}
|
}
|
||||||
|
@ -160,21 +173,21 @@ static char **readlines(void)
|
||||||
if (!isspace(c)) blank = 0;
|
if (!isspace(c)) blank = 0;
|
||||||
ch = c;
|
ch = c;
|
||||||
additem(cbuf, &ch);
|
additem(cbuf, &ch);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blank) {
|
if (!blank) {
|
||||||
additem(cbuf, &nullchar);
|
additem(cbuf, &nullchar);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
ln = copyitems(cbuf);
|
ln = copyitems(cbuf);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
additem(pbuf, &ln);
|
additem(pbuf, &ln);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
additem(pbuf, &nullline);
|
additem(pbuf, &nullline);
|
||||||
if (*errmsg) goto rlcleanup;
|
if (is_error()) goto rlcleanup;
|
||||||
lines = copyitems(pbuf);
|
lines = copyitems(pbuf);
|
||||||
|
|
||||||
rlcleanup:
|
rlcleanup:
|
||||||
|
@ -275,7 +288,7 @@ int original_main(int argc, const char * const *argv)
|
||||||
if (parinit) {
|
if (parinit) {
|
||||||
picopy = malloc((strlen(parinit) + 1) * sizeof (char));
|
picopy = malloc((strlen(parinit) + 1) * sizeof (char));
|
||||||
if (!picopy) {
|
if (!picopy) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto parcleanup;
|
goto parcleanup;
|
||||||
}
|
}
|
||||||
strcpy(picopy,parinit);
|
strcpy(picopy,parinit);
|
||||||
|
@ -283,7 +296,7 @@ int original_main(int argc, const char * const *argv)
|
||||||
while (opt) {
|
while (opt) {
|
||||||
parseopt(opt, &widthbak, &prefixbak,
|
parseopt(opt, &widthbak, &prefixbak,
|
||||||
&suffixbak, &hangbak, &lastbak, &minbak);
|
&suffixbak, &hangbak, &lastbak, &minbak);
|
||||||
if (*errmsg) goto parcleanup;
|
if (is_error()) goto parcleanup;
|
||||||
opt = strtok(NULL,whitechars);
|
opt = strtok(NULL,whitechars);
|
||||||
}
|
}
|
||||||
free(picopy);
|
free(picopy);
|
||||||
|
@ -293,7 +306,7 @@ int original_main(int argc, const char * const *argv)
|
||||||
while (*++argv) {
|
while (*++argv) {
|
||||||
parseopt(*argv, &widthbak, &prefixbak,
|
parseopt(*argv, &widthbak, &prefixbak,
|
||||||
&suffixbak, &hangbak, &lastbak, &minbak);
|
&suffixbak, &hangbak, &lastbak, &minbak);
|
||||||
if (*errmsg) goto parcleanup;
|
if (is_error()) goto parcleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -306,7 +319,7 @@ int original_main(int argc, const char * const *argv)
|
||||||
ungetc(c,stdin);
|
ungetc(c,stdin);
|
||||||
|
|
||||||
inlines = readlines();
|
inlines = readlines();
|
||||||
if (*errmsg) goto parcleanup;
|
if (is_error()) goto parcleanup;
|
||||||
if (!*inlines) {
|
if (!*inlines) {
|
||||||
free(inlines);
|
free(inlines);
|
||||||
inlines = NULL;
|
inlines = NULL;
|
||||||
|
@ -320,7 +333,7 @@ int original_main(int argc, const char * const *argv)
|
||||||
|
|
||||||
outlines = reformat((const char * const *) inlines,
|
outlines = reformat((const char * const *) inlines,
|
||||||
width, prefix, suffix, hang, last, min);
|
width, prefix, suffix, hang, last, min);
|
||||||
if (*errmsg) goto parcleanup;
|
if (is_error()) goto parcleanup;
|
||||||
|
|
||||||
freelines(inlines);
|
freelines(inlines);
|
||||||
inlines = NULL;
|
inlines = NULL;
|
||||||
|
@ -338,8 +351,9 @@ parcleanup:
|
||||||
if (inlines) freelines(inlines);
|
if (inlines) freelines(inlines);
|
||||||
if (outlines) freelines(outlines);
|
if (outlines) freelines(outlines);
|
||||||
|
|
||||||
if (*errmsg) {
|
if (is_error()) {
|
||||||
fprintf(stderr, "%.163s", errmsg);
|
report_error(stderr);
|
||||||
|
clear_error();
|
||||||
return(EXIT_FAILURE);
|
return(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ static int choosebreaks(
|
||||||
int linelen, shortest, newL, score, minlen, diff, sumsqdiff;
|
int linelen, shortest, newL, score, minlen, diff, sumsqdiff;
|
||||||
const char * const impossibility =
|
const char * const impossibility =
|
||||||
"Impossibility #%d has occurred. Please report it.\n";
|
"Impossibility #%d has occurred. Please report it.\n";
|
||||||
|
FILE *stream;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* Determine maximum length of the shortest line: */
|
/* Determine maximum length of the shortest line: */
|
||||||
|
|
||||||
|
@ -72,7 +75,12 @@ static int choosebreaks(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w1->score < 0) {
|
if (w1->score < 0) {
|
||||||
sprintf(errmsg,impossibility,1);
|
stream = open_memstream(&buf, &len);
|
||||||
|
fprintf(stream,impossibility,1);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +119,12 @@ static int choosebreaks(
|
||||||
|
|
||||||
newL = head->next ? head->next->score : 0;
|
newL = head->next ? head->next->score : 0;
|
||||||
if (newL > L) {
|
if (newL > L) {
|
||||||
sprintf(errmsg,impossibility,2);
|
stream = open_memstream(&buf, &len);
|
||||||
|
fprintf(stream,impossibility,2);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,11 +158,16 @@ static int choosebreaks(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (head->next && head->next->score < 0) {
|
if (head->next && head->next->score < 0) {
|
||||||
sprintf(errmsg,impossibility,3);
|
stream = open_memstream(&buf, &len);
|
||||||
|
fprintf(stream,impossibility,3);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
return newL;
|
return newL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +180,13 @@ char **reformat(const char * const *inlines, int width,
|
||||||
char *q1, *q2, **outlines = NULL;
|
char *q1, *q2, **outlines = NULL;
|
||||||
struct word dummy, *head, *tail, *w1, *w2;
|
struct word dummy, *head, *tail, *w1, *w2;
|
||||||
struct buffer *pbuf = NULL;
|
struct buffer *pbuf = NULL;
|
||||||
|
FILE *stream;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* Initialization: */
|
/* Initialization: */
|
||||||
|
|
||||||
*errmsg = '\0';
|
clear_error();
|
||||||
dummy.next = dummy.prev = NULL;
|
dummy.next = dummy.prev = NULL;
|
||||||
head = tail = &dummy;
|
head = tail = &dummy;
|
||||||
|
|
||||||
|
@ -179,7 +200,7 @@ char **reformat(const char * const *inlines, int width,
|
||||||
if (numin) {
|
if (numin) {
|
||||||
suffixes = malloc(numin * sizeof (const char *));
|
suffixes = malloc(numin * sizeof (const char *));
|
||||||
if (!suffixes) {
|
if (!suffixes) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto rfcleanup;
|
goto rfcleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,9 +213,13 @@ char **reformat(const char * const *inlines, int width,
|
||||||
for (line = inlines, suf = suffixes; *line; ++line, ++suf) {
|
for (line = inlines, suf = suffixes; *line; ++line, ++suf) {
|
||||||
for (end = *line; *end; ++end);
|
for (end = *line; *end; ++end);
|
||||||
if (end - *line < affix) {
|
if (end - *line < affix) {
|
||||||
sprintf(errmsg,
|
stream = open_memstream(&buf, &len);
|
||||||
"Line %ld shorter than <prefix> + <suffix> = %d + %d = %d\n",
|
fprintf(stream,"Line %ld shorter than <prefix> + <suffix> = %d + %d = %d\n",
|
||||||
line - inlines + 1, prefix, suffix, affix);
|
line - inlines + 1, prefix, suffix, affix);
|
||||||
|
fflush (stream);
|
||||||
|
set_error(buf);
|
||||||
|
fclose (stream);
|
||||||
|
free (buf);
|
||||||
goto rfcleanup;
|
goto rfcleanup;
|
||||||
}
|
}
|
||||||
end -= suffix;
|
end -= suffix;
|
||||||
|
@ -208,7 +233,7 @@ char **reformat(const char * const *inlines, int width,
|
||||||
if (p2 - p1 > L) p2 = p1 + L;
|
if (p2 - p1 > L) p2 = p1 + L;
|
||||||
w1 = malloc(sizeof (struct word));
|
w1 = malloc(sizeof (struct word));
|
||||||
if (!w1) {
|
if (!w1) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto rfcleanup;
|
goto rfcleanup;
|
||||||
}
|
}
|
||||||
w1->next = NULL;
|
w1->next = NULL;
|
||||||
|
@ -235,12 +260,12 @@ char **reformat(const char * const *inlines, int width,
|
||||||
/* Choose line breaks according to policy in "par.doc": */
|
/* Choose line breaks according to policy in "par.doc": */
|
||||||
|
|
||||||
newL = choosebreaks(head,tail,L,last,min);
|
newL = choosebreaks(head,tail,L,last,min);
|
||||||
if (*errmsg) goto rfcleanup;
|
if (is_error()) goto rfcleanup;
|
||||||
|
|
||||||
/* Construct the lines: */
|
/* Construct the lines: */
|
||||||
|
|
||||||
pbuf = newbuffer(sizeof (char *));
|
pbuf = newbuffer(sizeof (char *));
|
||||||
if (*errmsg) goto rfcleanup;
|
if (is_error()) goto rfcleanup;
|
||||||
|
|
||||||
numout = 0;
|
numout = 0;
|
||||||
w1 = head->next;
|
w1 = head->next;
|
||||||
|
@ -250,11 +275,11 @@ char **reformat(const char * const *inlines, int width,
|
||||||
prefix;
|
prefix;
|
||||||
q1 = malloc((linelen + 1) * sizeof (char));
|
q1 = malloc((linelen + 1) * sizeof (char));
|
||||||
if (!q1) {
|
if (!q1) {
|
||||||
strcpy(errmsg,outofmem);
|
set_error(outofmem);
|
||||||
goto rfcleanup;
|
goto rfcleanup;
|
||||||
}
|
}
|
||||||
additem(pbuf, &q1);
|
additem(pbuf, &q1);
|
||||||
if (*errmsg) goto rfcleanup;
|
if (is_error()) goto rfcleanup;
|
||||||
++numout;
|
++numout;
|
||||||
q2 = q1 + prefix;
|
q2 = q1 + prefix;
|
||||||
if (numout <= numin) memcpy(q1, inlines[numout - 1], prefix);
|
if (numout <= numin) memcpy(q1, inlines[numout - 1], prefix);
|
||||||
|
@ -281,7 +306,7 @@ char **reformat(const char * const *inlines, int width,
|
||||||
|
|
||||||
q1 = NULL;
|
q1 = NULL;
|
||||||
additem(pbuf, &q1);
|
additem(pbuf, &q1);
|
||||||
if (*errmsg) goto rfcleanup;
|
if (is_error()) goto rfcleanup;
|
||||||
|
|
||||||
outlines = copyitems(pbuf);
|
outlines = copyitems(pbuf);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user