home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1990
/
02
/
mcmahon.lst
< prev
next >
Wrap
File List
|
1989-12-26
|
9KB
|
299 lines
_MULTIPLEXING ERROR CODES_
by William J. McMahon
[LISTING ONE]
/* ----------------------------------------------------------------------
ERR_CODE.C Written by: William J. McMahon
This module contains the functions used to manipulate error codes.
Global Functions Defined Herein:
err_combine(), err_format(), err_print()
----------------------------------------------------------------------- */
#include <stdio.h>
#include <limits.h>
#define ERR_BUMPER 10
#define ERR_THRESHOLD (UINT_MAX/ERR_BUMPER) /* ... for overflow. */
/* ----- Local Functions Defined Herein: ----- */
unsigned err_pop();
void err_push();
#ifdef TEST /* -------------- Test Harness ---------------- */
#define FIRST_ARG 0 /* Varies with compiler (0 or 1). */
#define NCODES 32
main(argc, argv)
int argc;
char *argv[];
{
unsigned err_combine();
void err_format();
void err_print();
unsigned err_code;
int adder = 1;
int i;
if (argc > FIRST_ARG)
/* Override default starting code. */
adder = atoi(argv[FIRST_ARG]);
err_code = adder;
printf("\nInput should be a mirror image of output.\n");
printf("\n Input sequence: %d", err_code);
for (i = 0; i < NCODES; ++i) /* Build an error code, using */
{ /* multiple err_combine() calls.*/
++adder;
if (adder >= ERR_BUMPER)
adder = 1;
printf("%d", adder); /* Output RAW codes. */
err_code = err_combine(err_code, adder);
}
printf("\nOutput sequence: ");
err_print(stdout, err_code);
}
#endif
/* ----------------------------------------------------------------------
ERR_COMBINE Combines an new individual error code with an existing one.
Returns: Combined error code.
----------------------------------------------------------------------- */
unsigned err_combine(
unsigned original, /* Original error code. */
unsigned to_add) /* Code to be added to it. */
{
if ((original % ERR_BUMPER) == 0) /* Some special codes are not */
return (original); /* changed. */
to_add %= ERR_BUMPER; /* Make sure its in range. */
if (original > ERR_THRESHOLD)
{ /* Prevent overflow. */
err_push(original);
original = 0;
}
return (original * ERR_BUMPER + to_add);
}
/* ----------------------------------------------------------------------
ERR_FORMAT Decode and format an error code (and any overflow)
into a string. Returns: Nothing.
----------------------------------------------------------------------- */
void err_format(
char *buffer, /* Buffer to put formated code into. */
unsigned err_code) /* Error code to format. */
{
char *p;
p = buffer;
while (err_code)
{
do
{
sprintf(buffer, "%d", err_code % ERR_BUMPER);
buffer += strlen(buffer);
}
while ((err_code /= ERR_BUMPER) > 0);
err_code = err_pop();
}
}
/* ----------------------------------------------------------------------
ERR_PRINT Decode and output an error code (and any overflow).
Returns: Nothing.
----------------------------------------------------------------------- */
void err_print(
FILE *stream, /* Streem to output formated code to. */
unsigned err_code) /* Error code to output. */
{
while (err_code)
{
do
{
fprintf(stream, "%d", err_code % ERR_BUMPER);
}
while ((err_code /= ERR_BUMPER) > 0);
err_code = err_pop();
}
}
/* ================= Local stack for overflow codes. ================== */
#define MAX_OVERFLOWS 10
static unsigned err_stack[MAX_OVERFLOWS];
static unsigned err_stack_top = 0;
/* ----------------------------------------------------------------------
ERR_POP Returns: Combined error code of most recent overflow, 0 if none.
----------------------------------------------------------------------- */
static unsigned err_pop()
{
if (err_stack_top <= 0)
return (0);
--err_stack_top;
return (err_stack[err_stack_top]);
}
/* ----------------------------------------------------------------------
ERR_PUSH Push error code onto stack.
Returns: Nothing.
----------------------------------------------------------------------- */
static void err_push(
unsigned err_code) /* Error code to save. */
{
if (err_stack_top < MAX_OVERFLOWS)
{
err_stack[err_stack_top] = err_code;
++err_stack_top;
}
}
Examplσ 1║ Combininτ code≤ anΣ returninτ t∩ thσ nex⌠ level
unsigned mid_level(char *parm)
{
unsigned err, low_level();
if (parm == NULL)
return (1);
...
err = low_level(i, j);
if (err)
return (ERR_COMBINE(err, 3));
...
return (0);
}
unsigned low_level(int x, int y)
{
if (x > 0)
return (1);
if (x > y)
return (2);
...
return (0)
}
Examplσ 2║ Defininτ ß simplσ ERR_COMBIN┼ macro
#define ERR_BUMPER 10
#define ERR_COMBINE(orig, to_add) ((orig * ERR_BUMPER) + to_add)
Examplσ 3║ Thi≤ functioε wil∞ decodσ thσ combineΣ erro≥ codσ anΣ ì
displa∙ thσ individua∞ codes
void err_print(FILE *stream, unsigned err_code)
{
do
{
fprintf(stream, "%d", (err_code % ERR_BUMPER));
}
while ((err_code /= ERR_BUMPER) > 0);
}
Examplσ 4: Code produced once function failure has been located
main()
{
unsigned err, function();
...
err = function();
if (err)
abort(ERR_COMBINE(err, 3));
...
}
void abort(unsigned err_code);
{
fprintf(stderr, "\n ERROR:");
err_printf(stderr, err_code);
exit (err_code);
}
Examplσ 5║ Usinτ ß functioε insteaΣ oµ ß macro
unsigned err_combine(unsigned original, unsigned to_add)
{
if (original > UINT_MAX / ERR_BUMPER)
{ /* UINT_MAX is in limits.h */
err_push(original);
original = 0;
}
return (original * ERR_BUMPER + to_add);
}
#define MAX_OVERFLOWS 10
static unsigned err_stack[MAX_OVERFLOWS];
static unsigned err_stack_top = 0;
unsigned err_pop()
{
if (err_stack_top <= 0)
return (0);
--err_stack_top;
return (err_stack[err_stack_top]);
}
void err_push(unsigned err_code)
{
if (err_stack_top < MAX_OVERFLOWS)
{
err_stack[err_stack_top] = err;
++err_stack_top;
}
}
Examplσ 6║ Changinτ ERR_PRIN╘ t∩ displa∙ thσ entirσ erro≥ code
void err_print(FILE *stream, unsigned in err_code)
{
while (err_code)
{
do
{
fprintf(stream, "%d", (err % ERR_BUMPER));
}
while ((err_code /= ERR_BUMPER) > 0);
err_code = err_pop();
}
}
Examplσ 7║ Expandinτ thσ abor⌠ function
void abort(err)
{
switch (err)
{
case DISK_SPACE_ERROR:
printf("\n Not enough disk space to run program");
break;
case MEMORY_ERROR:
printf("\n Not enough memory to run program.");
break;
case USER_ABORT:
printf(stderr, "\n Program aborted by user.");
break;
default:
printf("\n Unexpected error: %d ", err);
printf("\n Please record this error number,");
printf("\n and call technical support at");
printf("\n 1-800-555-1234.");
break;
}
exit(err);
}