fix: implemented errmsg

feat: implemented errmsg
This commit is contained in:
Renge 2022-03-04 12:15:43 -05:00
parent 3e1bf8ba92
commit c1c2feb549
5 changed files with 138 additions and 51 deletions

View File

@ -5,15 +5,36 @@
/* 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 */
/* write an error message string into errmsg, (indicating */
/* failure), being careful not to overrun the space. */
extern const char * const outofmem; /* "Out of memory.\n" */
/**
* Clear any existing error indication and free storage occupied by
* any existing error message.
*/
void clear_error();
static char * outofmem;

View File

@ -57,7 +57,7 @@ struct buffer *newbuffer(size_t itemsize)
blk = (struct block *) malloc(sizeof (struct block));
items = malloc(maxhere * itemsize);
if (!buf || !blk || !items) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto nberror;
}
@ -69,7 +69,7 @@ struct buffer *newbuffer(size_t itemsize)
blk->items = items;
blk->next = NULL;
*errmsg = '\0';
clear_error();
return buf;
nberror:
@ -123,7 +123,7 @@ void additem(struct buffer *buf, const void *item)
new = (struct block * ) malloc(sizeof (struct block));
items = malloc(maxhere * itemsize);
if (!new || !items) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto aierror;
}
blk->next = new;
@ -140,7 +140,7 @@ void additem(struct buffer *buf, const void *item)
++blk->numhere;
*errmsg = '\0';
clear_error();
return;
aierror:
@ -169,7 +169,7 @@ void *copyitems(struct buffer *buf)
r = malloc(n * itemsize);
if (!r) {
strcpy(errmsg,outofmem);
set_error(outofmem);
return NULL;
}
@ -179,7 +179,7 @@ void *copyitems(struct buffer *buf)
memcpy( ((char *) r) + (blk->numprevious * itemsize),
blk->items, blk->numhere * itemsize);
*errmsg = '\0';
clear_error();
return r;
}

View File

@ -9,8 +9,35 @@
#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";

View File

@ -80,11 +80,19 @@ static void parseopt(
const char *saveopt = opt;
char oc;
int n, r;
FILE *stream;
char *buf;
size_t len;
if (*opt == '-') ++opt;
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;
}
@ -115,11 +123,16 @@ static void parseopt(
else goto badopt;
}
*errmsg = '\0';
clear_error();
return;
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;
cbuf = newbuffer(sizeof (char));
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
pbuf = newbuffer(sizeof (char *));
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
for (blank = 1; ; ) {
c = getchar();
@ -148,11 +161,11 @@ static char **readlines(void)
break;
}
additem(cbuf, &nullchar);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
ln = copyitems(cbuf);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
additem(pbuf, &ln);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
clearbuffer(cbuf);
blank = 1;
}
@ -160,21 +173,21 @@ static char **readlines(void)
if (!isspace(c)) blank = 0;
ch = c;
additem(cbuf, &ch);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
}
}
if (!blank) {
additem(cbuf, &nullchar);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
ln = copyitems(cbuf);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
additem(pbuf, &ln);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
}
additem(pbuf, &nullline);
if (*errmsg) goto rlcleanup;
if (is_error()) goto rlcleanup;
lines = copyitems(pbuf);
rlcleanup:
@ -275,7 +288,7 @@ int original_main(int argc, const char * const *argv)
if (parinit) {
picopy = malloc((strlen(parinit) + 1) * sizeof (char));
if (!picopy) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto parcleanup;
}
strcpy(picopy,parinit);
@ -283,7 +296,7 @@ int original_main(int argc, const char * const *argv)
while (opt) {
parseopt(opt, &widthbak, &prefixbak,
&suffixbak, &hangbak, &lastbak, &minbak);
if (*errmsg) goto parcleanup;
if (is_error()) goto parcleanup;
opt = strtok(NULL,whitechars);
}
free(picopy);
@ -293,7 +306,7 @@ int original_main(int argc, const char * const *argv)
while (*++argv) {
parseopt(*argv, &widthbak, &prefixbak,
&suffixbak, &hangbak, &lastbak, &minbak);
if (*errmsg) goto parcleanup;
if (is_error()) goto parcleanup;
}
for (;;) {
@ -306,7 +319,7 @@ int original_main(int argc, const char * const *argv)
ungetc(c,stdin);
inlines = readlines();
if (*errmsg) goto parcleanup;
if (is_error()) goto parcleanup;
if (!*inlines) {
free(inlines);
inlines = NULL;
@ -320,7 +333,7 @@ int original_main(int argc, const char * const *argv)
outlines = reformat((const char * const *) inlines,
width, prefix, suffix, hang, last, min);
if (*errmsg) goto parcleanup;
if (is_error()) goto parcleanup;
freelines(inlines);
inlines = NULL;
@ -338,8 +351,9 @@ parcleanup:
if (inlines) freelines(inlines);
if (outlines) freelines(outlines);
if (*errmsg) {
fprintf(stderr, "%.163s", errmsg);
if (is_error()) {
report_error(stderr);
clear_error();
return(EXIT_FAILURE);
}

View File

@ -46,6 +46,9 @@ static int choosebreaks(
int linelen, shortest, newL, score, minlen, diff, sumsqdiff;
const char * const impossibility =
"Impossibility #%d has occurred. Please report it.\n";
FILE *stream;
char *buf;
size_t len;
/* Determine maximum length of the shortest line: */
@ -72,7 +75,12 @@ static int choosebreaks(
}
}
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;
}
}
@ -111,7 +119,12 @@ static int choosebreaks(
newL = head->next ? head->next->score : 0;
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;
}
}
@ -145,11 +158,16 @@ static int choosebreaks(
}
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;
}
*errmsg = '\0';
clear_error();
return newL;
}
@ -162,10 +180,13 @@ char **reformat(const char * const *inlines, int width,
char *q1, *q2, **outlines = NULL;
struct word dummy, *head, *tail, *w1, *w2;
struct buffer *pbuf = NULL;
FILE *stream;
char *buf;
size_t len;
/* Initialization: */
*errmsg = '\0';
clear_error();
dummy.next = dummy.prev = NULL;
head = tail = &dummy;
@ -179,7 +200,7 @@ char **reformat(const char * const *inlines, int width,
if (numin) {
suffixes = malloc(numin * sizeof (const char *));
if (!suffixes) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto rfcleanup;
}
}
@ -192,9 +213,13 @@ char **reformat(const char * const *inlines, int width,
for (line = inlines, suf = suffixes; *line; ++line, ++suf) {
for (end = *line; *end; ++end);
if (end - *line < affix) {
sprintf(errmsg,
"Line %ld shorter than <prefix> + <suffix> = %d + %d = %d\n",
stream = open_memstream(&buf, &len);
fprintf(stream,"Line %ld shorter than <prefix> + <suffix> = %d + %d = %d\n",
line - inlines + 1, prefix, suffix, affix);
fflush (stream);
set_error(buf);
fclose (stream);
free (buf);
goto rfcleanup;
}
end -= suffix;
@ -208,7 +233,7 @@ char **reformat(const char * const *inlines, int width,
if (p2 - p1 > L) p2 = p1 + L;
w1 = malloc(sizeof (struct word));
if (!w1) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto rfcleanup;
}
w1->next = NULL;
@ -235,12 +260,12 @@ char **reformat(const char * const *inlines, int width,
/* Choose line breaks according to policy in "par.doc": */
newL = choosebreaks(head,tail,L,last,min);
if (*errmsg) goto rfcleanup;
if (is_error()) goto rfcleanup;
/* Construct the lines: */
pbuf = newbuffer(sizeof (char *));
if (*errmsg) goto rfcleanup;
if (is_error()) goto rfcleanup;
numout = 0;
w1 = head->next;
@ -250,11 +275,11 @@ char **reformat(const char * const *inlines, int width,
prefix;
q1 = malloc((linelen + 1) * sizeof (char));
if (!q1) {
strcpy(errmsg,outofmem);
set_error(outofmem);
goto rfcleanup;
}
additem(pbuf, &q1);
if (*errmsg) goto rfcleanup;
if (is_error()) goto rfcleanup;
++numout;
q2 = q1 + prefix;
if (numout <= numin) memcpy(q1, inlines[numout - 1], prefix);
@ -281,7 +306,7 @@ char **reformat(const char * const *inlines, int width,
q1 = NULL;
additem(pbuf, &q1);
if (*errmsg) goto rfcleanup;
if (is_error()) goto rfcleanup;
outlines = copyitems(pbuf);