mirror of
https://github.com/jeremysrand/abCalc.git
synced 2024-12-30 10:30:28 +00:00
Add error handling support
This commit is contained in:
parent
d8d4bc60d4
commit
822c7ab0ac
14
Makefile
14
Makefile
@ -1,15 +1,21 @@
|
|||||||
OBJS=abCalc.o abCalcExpr.o abCalcExprReal.o abCalcExprInt.o abCalcStack.o abCalcMode.o abCalcMain.o
|
OBJS=abCalc.o abCalcExpr.o abCalcExprReal.o abCalcExprInt.o abCalcStack.o \
|
||||||
|
abCalcMode.o abCalcMain.o abCalcOp.o abCalcOpAdd.o abCalcError.o
|
||||||
|
|
||||||
NAME=abCalc
|
NAME=abCalc
|
||||||
|
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
abCalcExpr.o: abCalcExpr.h
|
abCalcExpr.o: abCalcExpr.h
|
||||||
abCalcExprReal.o: abCalcExpr.h abCalcExprReal.h
|
abCalcExprReal.o: abCalcExpr.h abCalcExprReal.h
|
||||||
abCalcStack.o: abCalcExpr.h abCalcStack.h
|
abCalcStack.o: abCalcExpr.h abCalcStack.h abCalcError.h
|
||||||
abCalcMode.o: abCalcMode.h abCalcExpr.h
|
abCalcMode.o: abCalcMode.h abCalcExpr.h
|
||||||
abCalcExprInt.o: abCalcExpr.h abCalcMode.h abCalcExprInt.h
|
abCalcExprInt.o: abCalcExpr.h abCalcMode.h abCalcExprInt.h
|
||||||
abCalc.o: abCalc.h abCalcExpr.h abCalcMode.h abCalcExprReal.h abCalcExprInt.h abCalcStack.h
|
abCalc.o: abCalc.h abCalcExpr.h abCalcMode.h abCalcExprReal.h abCalcExprInt.h \
|
||||||
abCalcMain.o: abCalc.h abCalcStack.h abCalcExpr.h
|
abCalcStack.h abCalcOp.h abCalcError.h
|
||||||
|
abCalcMain.o: abCalc.h abCalcStack.h abCalcExpr.h abCalcOp.h abCalcError.h
|
||||||
|
abCalcOp.o: abCalcOp.h abCalcOpAdd.h
|
||||||
|
abCalcOpAdd.o: abCalcOp.h abCalcOpAdd.h
|
||||||
|
abCalcError.o: abCalcError.h
|
||||||
|
|
||||||
CFLAGS=-g
|
CFLAGS=-g
|
||||||
|
|
||||||
|
6
abCalc.c
6
abCalc.c
@ -9,6 +9,8 @@
|
|||||||
#include "abCalcExprReal.h"
|
#include "abCalcExprReal.h"
|
||||||
#include "abCalcMode.h"
|
#include "abCalcMode.h"
|
||||||
#include "abCalcStack.h"
|
#include "abCalcStack.h"
|
||||||
|
#include "abCalcOp.h"
|
||||||
|
#include "abCalcError.h"
|
||||||
|
|
||||||
|
|
||||||
void abCalcInit(void)
|
void abCalcInit(void)
|
||||||
@ -19,6 +21,10 @@ void abCalcInit(void)
|
|||||||
|
|
||||||
abCalcModeInit();
|
abCalcModeInit();
|
||||||
abCalcStackInit();
|
abCalcStackInit();
|
||||||
|
|
||||||
|
abCalcOpInit();
|
||||||
|
|
||||||
|
abCalcErrorInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
73
abCalcError.c
Normal file
73
abCalcError.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
abCalcError.c
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "abCalcError.h"
|
||||||
|
|
||||||
|
|
||||||
|
static char *gErrorStrings[abCalcErrorTypeMax];
|
||||||
|
|
||||||
|
static abCalcErrorType gCurrErrorType = abCalcNoError;
|
||||||
|
static char *gCurrErrorOpName = NULL;
|
||||||
|
|
||||||
|
static char gErrorBuffer[128];
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcErrorInit(void)
|
||||||
|
{
|
||||||
|
gErrorStrings[abCalcNoError] = NULL;
|
||||||
|
gErrorStrings[abCalcSyntaxError] = "Syntax Error";
|
||||||
|
gErrorStrings[abCalcBadArgTypeError] = "Bad Argument Type";
|
||||||
|
gErrorStrings[abCalcBadArgValueError] = "Bad Argument Value";
|
||||||
|
gErrorStrings[abCalcTooFewArgsError] = "Too Few Arguments";
|
||||||
|
gErrorStrings[abCalcStackFullError] = "Stack Full";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcRaiseError(abCalcErrorType type, char *opName)
|
||||||
|
{
|
||||||
|
if ((type < abCalcErrorTypeMin) ||
|
||||||
|
(type >= abCalcErrorTypeMax))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gCurrErrorType == abCalcNoError) {
|
||||||
|
gCurrErrorType = type;
|
||||||
|
gCurrErrorOpName = opName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *abCalcGetError(void)
|
||||||
|
{
|
||||||
|
char *errorString;
|
||||||
|
|
||||||
|
if ((gCurrErrorType < abCalcErrorTypeMin) ||
|
||||||
|
(gCurrErrorType >= abCalcErrorTypeMax))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
errorString = gErrorStrings[gCurrErrorType];
|
||||||
|
|
||||||
|
if (errorString == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (gCurrErrorOpName != NULL) {
|
||||||
|
sprintf(gErrorBuffer, "%s Error: %s", gCurrErrorOpName, gErrorStrings[gCurrErrorType]);
|
||||||
|
} else {
|
||||||
|
sprintf(gErrorBuffer, "Error: %s", gErrorStrings[gCurrErrorType]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gErrorBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcClearError(void)
|
||||||
|
{
|
||||||
|
gCurrErrorType = abCalcNoError;
|
||||||
|
gCurrErrorOpName = NULL;
|
||||||
|
}
|
||||||
|
|
33
abCalcError.h
Normal file
33
abCalcError.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
abCalcError.h
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ABCALCERROR_H
|
||||||
|
#define ABCALCERROR_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum abCalcErrorType {
|
||||||
|
abCalcErrorTypeMin = 0,
|
||||||
|
abCalcNoError,
|
||||||
|
abCalcSyntaxError,
|
||||||
|
abCalcBadArgTypeError,
|
||||||
|
abCalcBadArgValueError,
|
||||||
|
abCalcTooFewArgsError,
|
||||||
|
abCalcStackFullError,
|
||||||
|
|
||||||
|
abCalcErrorTypeMax
|
||||||
|
} abCalcErrorType;
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcErrorInit(void);
|
||||||
|
|
||||||
|
void abCalcRaiseError(abCalcErrorType type, char *opName);
|
||||||
|
|
||||||
|
char *abCalcGetError(void);
|
||||||
|
|
||||||
|
void abCalcClearError(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
21
abCalcMain.c
21
abCalcMain.c
@ -11,6 +11,8 @@
|
|||||||
#include "abCalc.h"
|
#include "abCalc.h"
|
||||||
#include "abCalcExpr.h"
|
#include "abCalcExpr.h"
|
||||||
#include "abCalcStack.h"
|
#include "abCalcStack.h"
|
||||||
|
#include "abCalcOp.h"
|
||||||
|
#include "abCalcError.h"
|
||||||
|
|
||||||
|
|
||||||
char gBuffer[AB_CALC_EXPR_STRING_MAX];
|
char gBuffer[AB_CALC_EXPR_STRING_MAX];
|
||||||
@ -23,6 +25,8 @@ int main(void)
|
|||||||
int depth;
|
int depth;
|
||||||
int item;
|
int item;
|
||||||
int len;
|
int len;
|
||||||
|
abCalcOp *op;
|
||||||
|
char *errorString;
|
||||||
|
|
||||||
abCalcInit();
|
abCalcInit();
|
||||||
|
|
||||||
@ -39,6 +43,12 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorString = abCalcGetError();
|
||||||
|
if (errorString != NULL) {
|
||||||
|
printf("\n %s\n", errorString);
|
||||||
|
abCalcClearError();
|
||||||
|
}
|
||||||
|
|
||||||
timeToQuit = 1;
|
timeToQuit = 1;
|
||||||
if (fgets(gBuffer, sizeof(gBuffer), stdin) != NULL) {
|
if (fgets(gBuffer, sizeof(gBuffer), stdin) != NULL) {
|
||||||
len = strlen(gBuffer);
|
len = strlen(gBuffer);
|
||||||
@ -47,9 +57,14 @@ int main(void)
|
|||||||
gBuffer[len - 1] = '\0';
|
gBuffer[len - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((abCalcParseExpr(&gExpr, gBuffer) != NULL) &&
|
op = abCalcOpLookup(gBuffer);
|
||||||
(abCalcStackExprPush(&gExpr) != NULL)) {
|
|
||||||
timeToQuit = 0;
|
if (op != NULL) {
|
||||||
|
op->execute();
|
||||||
|
} else if (abCalcParseExpr(&gExpr, gBuffer) != NULL) {
|
||||||
|
abCalcStackExprPush(&gExpr);
|
||||||
|
} else {
|
||||||
|
abCalcRaiseError(abCalcSyntaxError, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
54
abCalcOp.c
Normal file
54
abCalcOp.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
abCalcOp.c
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "abCalcOp.h"
|
||||||
|
|
||||||
|
#include "abCalcOpAdd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define AB_CALC_MAX_OPS 128
|
||||||
|
|
||||||
|
|
||||||
|
static abCalcOp gOps[AB_CALC_MAX_OPS];
|
||||||
|
static int gNumOps = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcOpInit(void)
|
||||||
|
{
|
||||||
|
memset(gOps, 0, sizeof(gOps));
|
||||||
|
|
||||||
|
abCalcOpAddInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcOpRegister(char *name, void (*execute)(void))
|
||||||
|
{
|
||||||
|
if (gNumOps >= AB_CALC_MAX_OPS) {
|
||||||
|
fprintf(stderr, "Operation registration overflow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gOps[gNumOps].name = name;
|
||||||
|
gOps[gNumOps].execute = execute;
|
||||||
|
gNumOps++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abCalcOp *abCalcOpLookup(char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < gNumOps; i++) {
|
||||||
|
if (strcmp(gOps[i].name, name) == 0) {
|
||||||
|
return &gOps[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
24
abCalcOp.h
Normal file
24
abCalcOp.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
abCalcOp.h
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ABCALCOP_H
|
||||||
|
#define ABCALCOP_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct abCalcOp {
|
||||||
|
char *name;
|
||||||
|
void (*execute)(void);
|
||||||
|
} abCalcOp;
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcOpInit(void);
|
||||||
|
|
||||||
|
void abCalcOpRegister(char *name, void (*execute)(void));
|
||||||
|
|
||||||
|
abCalcOp *abCalcOpLookup(char *name);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
28
abCalcOpAdd.c
Normal file
28
abCalcOpAdd.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
abCalcOpAdd.c
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "abCalcOpAdd.h"
|
||||||
|
#include "abCalcOp.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define OP_NAME "+"
|
||||||
|
|
||||||
|
|
||||||
|
static void addExecute(void);
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcOpAddInit(void)
|
||||||
|
{
|
||||||
|
abCalcOpRegister(OP_NAME, addExecute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addExecute(void)
|
||||||
|
{
|
||||||
|
printf("In add!\n");
|
||||||
|
}
|
14
abCalcOpAdd.h
Normal file
14
abCalcOpAdd.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
abCalcOpAdd.h
|
||||||
|
By: Jeremy Rand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ABCALCOPADD_H
|
||||||
|
#define ABCALCOPADD_H
|
||||||
|
|
||||||
|
|
||||||
|
void abCalcOpAddInit(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -8,6 +8,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "abCalcStack.h"
|
#include "abCalcStack.h"
|
||||||
|
#include "abCalcError.h"
|
||||||
|
|
||||||
|
|
||||||
#define AB_CALC_STACK_DEPTH 128
|
#define AB_CALC_STACK_DEPTH 128
|
||||||
@ -25,6 +26,12 @@ void abCalcStackInit(void)
|
|||||||
abCalcExpr *abCalcStackExprPush(abCalcExpr *expr)
|
abCalcExpr *abCalcStackExprPush(abCalcExpr *expr)
|
||||||
{
|
{
|
||||||
abCalcExpr *result = NULL;
|
abCalcExpr *result = NULL;
|
||||||
|
|
||||||
|
if (gStackNumItems >= AB_CALC_STACK_DEPTH) {
|
||||||
|
abCalcRaiseError(abCalcStackFullError, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((gStackNumItems < AB_CALC_STACK_DEPTH) &&
|
if ((gStackNumItems < AB_CALC_STACK_DEPTH) &&
|
||||||
(expr != NULL)) {
|
(expr != NULL)) {
|
||||||
result = &(gStack[gStackNumItems]);
|
result = &(gStack[gStackNumItems]);
|
||||||
|
Loading…
Reference in New Issue
Block a user