Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8733 turbocat 1
/*
2
 * Tiny BASIC
3
 * Error Handling Module
4
 *
5
 * Released as Public Domain by Damian Gareth Walker 2019
6
 * Created: 18-Aug-2019
7
 */
8
 
9
 
10
/* included headers */
11
#include 
12
#include 
13
#include 
14
#include "errors.h"
15
 
16
 
17
/*
18
 * Internal Data Structures
19
 */
20
 
21
 
22
/* Private data */
23
typedef struct {
24
  ErrorCode error; /* the last error encountered */
25
  int line; /* the source line on which the error occurred */
26
  int label; /* the label for the source line */
27
} Private;
28
 
29
 
30
/*
31
 * Internal Data
32
 */
33
 
34
 
35
/* convenience variables */
36
ErrorHandler *this; /* object being worked on */
37
Private *data; /* private data of object being worked on */
38
 
39
/* global variables */
40
static char *messages[E_LAST] = { /* the error messages */
41
  "Successful",
42
  "Invalid line number",
43
  "Unrecognised command",
44
  "Invalid variable",
45
  "Invalid assignment",
46
  "Invalid expression",
47
  "Missing )",
48
  "Invalid PRINT output",
49
  "Bad command line",
50
  "File not found",
51
  "Invalid operator",
52
  "THEN expected",
53
  "Unexpected parameter",
54
  "RETURN without GOSUB",
55
  "Divide by zero",
56
  "Overflow",
57
  "Out of memory",
58
  "Too many gosubs"
59
};
60
 
61
 
62
/*
63
 * Public Methods
64
 */
65
 
66
 
67
/*
68
 * Record an error encountered
69
 * globals:
70
 *   ErrorCode   error       the last error encountered
71
 *   int         line        the source line
72
 *   int         label       the line's label
73
 * params:
74
 *   ErrorCode   new_error   the error code to set
75
 *   int         new_line    the source line to set
76
 *   int         new_label   the label to set
77
 */
78
static void set_code (ErrorHandler *errors, ErrorCode new_error, int new_line,
79
  int new_label) {
80
 
81
  /* initialise */
82
  this = errors;
83
  data = this->data;
84
 
85
  /* set the properties */
86
  data->error = new_error;
87
  data->line = new_line;
88
  data->label = new_label;
89
}
90
 
91
/*
92
 * Return the last error code encountered
93
 * params:
94
 *   ErrorHandler*   errors   the error handler
95
 * returns:
96
 *   ErrorCode                the last error encountered
97
 */
98
static ErrorCode get_code (ErrorHandler *errors) {
99
  this = errors;
100
  data = this->data;
101
  return data->error;
102
}
103
 
104
/*
105
 * Return the last error line encountered
106
 * params:
107
 *   ErrorHandler*   errors   the error handler
108
 * returns:
109
 *   int                      the source line of the last error
110
 */
111
static int get_line (ErrorHandler *errors) {
112
  this = errors;
113
  data = this->data;
114
  return data->line;
115
}
116
 
117
/*
118
 * Return the last error label encountered
119
 * params:
120
 *   ErrorHandler*   errors   the error handler
121
 * returns:
122
 *   int                      the line label of the last error
123
 */
124
static int get_label (ErrorHandler *errors) {
125
  this = errors;
126
  data = this->data;
127
  return data->label;
128
}
129
 
130
/*
131
 * Generate an error message
132
 * params:
133
 *   ErrorHandler*   errors     the error handler
134
 * globals:
135
 *   char*           messages   a list of error messages
136
 * returns:
137
 *   char*                      the full error message
138
 */
139
static char *get_text (ErrorHandler *errors) {
140
 
141
  /* local variables */
142
  char
143
    *message, /* the complete message */
144
    *line_text, /* source line N */
145
    *label_text; /* label N */
146
 
147
  /* initialise the error object */
148
  this = errors;
149
  data = this->data;
150
 
151
  /* get the source line, if there is one */
152
  line_text = malloc (20);
153
  if (data->line)
154
    sprintf (line_text, ", source line %d", data->line);
155
  else
156
    strcpy (line_text, "");
157
 
158
  /* get the source label, if there is one */
159
  label_text = malloc (19);
160
  if (data->label)
161
    sprintf (label_text, ", line label %d", data->label);
162
  else
163
    strcpy (label_text, "");
164
 
165
  /* put the error message together */
166
  message = malloc (strlen (messages[data->error]) + strlen (line_text)
167
    + strlen (label_text) + 1);
168
  strcpy (message, messages[data->error]);
169
  strcat (message, line_text);
170
  strcat (message, label_text);
171
  free (line_text);
172
  free (label_text);
173
 
174
  /* return the assembled error message */
175
  return message;
176
}
177
 
178
/*
179
 * ErrorHandler destructor
180
 * params:
181
 *   ErrorHandler*   errors   the doomed error handler
182
 */
183
static void destroy (ErrorHandler *errors) {
184
  if ((this = errors)) {
185
    data = this->data;
186
    free (data);
187
    free (this);
188
  }
189
}
190
 
191
 
192
/*
193
 * Constructors
194
 */
195
 
196
 
197
/*
198
 * Principal constructor
199
 * returns:
200
 *   ErrorHandler*   the new error handler object
201
 */
202
ErrorHandler *new_ErrorHandler (void) {
203
 
204
    /* allocate memory */
205
    this = malloc (sizeof (ErrorHandler));
206
    this->data = data = malloc (sizeof (Private));
207
 
208
    /* initialise the methods */
209
    this->set_code = set_code;
210
    this->get_code = get_code;
211
    this->get_line = get_line;
212
    this->get_label = get_label;
213
    this->get_text = get_text;
214
    this->destroy = destroy;
215
 
216
    /* initialise the properties */
217
    data->error = E_NONE;
218
    data->line = 0;
219
    data->label = 0;
220
 
221
    /* return the new object */
222
    return this;
223
}