Skip to content

Commit

Permalink
Use error codes instead of plain integers (#42)
Browse files Browse the repository at this point in the history
* Add error code constants
* Improve error detection on incorrect bar lengths
  • Loading branch information
zzril authored Oct 15, 2024
1 parent 737c878 commit ac2d506
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 66 deletions.
37 changes: 37 additions & 0 deletions src/error_codes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef ERROR_CODES_H
#define ERROR_CODES_H
// --------

#include <limits.h>

// --------

enum ErrorCodes {

ERROR_CODE_UNKNOWN_SYSTEM_ERROR = INT_MIN,

ERROR_CODE_MALLOC_FAILURE,
ERROR_CODE_OPEN_FAILURE,

ERROR_CODE_SDL_ERROR = -1,

ERROR_CODE_SUCCESS = 0,

ERROR_CODE_UNKNOWN_ERROR,

ERROR_CODE_INVALID_STATE,
ERROR_CODE_INVALID_ARGUMENT,

ERROR_CODE_UNEXPECTED_EOF,
ERROR_CODE_UNEXPECTED_CHARACTER,

ERROR_CODE_INSTRUMENT_BUFFER_OVERFLOW,

ERROR_CODE_BAR_TOO_SHORT,
ERROR_CODE_BAR_TOO_LONG,

};

// --------
#endif

59 changes: 39 additions & 20 deletions src/instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,44 @@
#include <string.h>

#include "config.h"
#include "error_codes.h"
#include "instrument.h"
#include "wave.h"

// --------

static int add_note(Instrument* instrument, Note* note);
static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_off);
static bool is_buffer_full(Instrument* instrument);

// --------

static int add_note(Instrument* instrument, Note* note) {
static int add_note(Instrument* instrument, Note* note, bool* done, bool* cut_off) {

size_t samples_to_write;
size_t remaining_buffer_space;
bool overflow;

if(note == NULL) {
return 2;
if(instrument == NULL || note == NULL || done == NULL || cut_off == NULL) {
return ERROR_CODE_INVALID_ARGUMENT;
}

if(is_buffer_full(instrument)) {
return 3;
*done = true;
return ERROR_CODE_INSTRUMENT_BUFFER_OVERFLOW;
}

overflow = false;
*done = false;
*cut_off = false;

remaining_buffer_space = instrument->num_samples - instrument->buffer_position;
samples_to_write = Note_get_length_in_samples(note);

if(samples_to_write > remaining_buffer_space) {
samples_to_write = remaining_buffer_space;
overflow = true;
*cut_off = true;
}

if(samples_to_write == remaining_buffer_space) {
*done = true;
}

if(!Note_is_rest(note)) {
Expand All @@ -45,7 +51,7 @@ static int add_note(Instrument* instrument, Note* note) {

instrument->buffer_position += samples_to_write;

return overflow? 1: 0;
return 0;
}

static bool is_buffer_full(Instrument* instrument) {
Expand All @@ -62,7 +68,7 @@ int Instrument_init_at(Instrument* instrument, void* instrument_definition) {
instrument->buffer = reallocarray(NULL, instrument->num_samples, sizeof(float));
if(instrument->buffer == NULL) {
perror("malloc");
return -1;
return ERROR_CODE_MALLOC_FAILURE;
}

reset_buffer(instrument);
Expand Down Expand Up @@ -92,26 +98,39 @@ int Instrument_add_notes_for_bar(Instrument* instrument, NoteProvider note_provi

Note note;
int status = 0;
bool provider_done = false;
bool instrument_done = false;
bool cut_off = false;

while((status = note_provider(arg, &note)) == 0) {
while((status = note_provider(arg, &note, &provider_done)) == 0 && !provider_done && !instrument_done) {

int rv = add_note(instrument, &note);
int rv = add_note(instrument, &note, &instrument_done, &cut_off);

if(rv != 0) {
if(rv == 1) {
fputs("WARNING: Instrument buffer full, cutting off remaining note(s)\n", stderr);
return 0;
}
else {
return rv;
}
return rv;
}

if(cut_off) {
fputs("WARNING: Instrument buffer full, cutting off note.\n", stderr);
}
}

if(!is_buffer_full(instrument)) {
if(status != 0) {
return status;
}

if(!instrument_done) {
return ERROR_CODE_BAR_TOO_SHORT;
}

if(!is_buffer_full(instrument)) {
fputs("WARNING: Instrument buffer not completely filled, making up with silence.\n", stderr);
}

if(!provider_done) {
return ERROR_CODE_BAR_TOO_LONG;
}

return 0;
}

3 changes: 2 additions & 1 deletion src/instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define INSTRUMENT_H
// --------

#include <stdbool.h>
#include <stddef.h>

#include "note.h"
Expand All @@ -14,7 +15,7 @@ struct Instrument;

typedef struct Instrument Instrument;

typedef int (*NoteProvider)(void*, Note*);
typedef int (*NoteProvider)(void*, Note*, bool*);

// --------

Expand Down
9 changes: 5 additions & 4 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <string.h>

#include "error_codes.h"
#include "instrument.h"
#include "interpreter.h"
#include "lexer.h"
Expand Down Expand Up @@ -30,7 +31,7 @@ static int play_bar_token(Player* player, Instrument* instrument, Token* bar_tok
Instrument* instruments[] = {instrument};

if(bar_token == NULL || bar_token->type != TOKEN_BAR || bar_token->content == NULL) {
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

NoteCompiler_init_at(&compiler, (char*) (bar_token->content), bar_token->content_length);
Expand Down Expand Up @@ -155,7 +156,7 @@ int Interpreter_interpret(Interpreter* interpreter, FILE* stream) {

if(lexer.error) {
fprintf(stderr, "Error at %s:%u:%u\n", interpreter->filename, lexer.line, lexer.col);
status = status != 0? status: 1;
status = status != 0? status: ERROR_CODE_UNKNOWN_ERROR;
}

if(interpreter->error) {
Expand Down Expand Up @@ -186,7 +187,7 @@ int Interpreter_interpret(Interpreter* interpreter, FILE* stream) {
break;
}

status = status != 0? status: 1;
status = status != 0? status: ERROR_CODE_UNKNOWN_ERROR;
}

Token_destroy_at(&token);
Expand All @@ -202,7 +203,7 @@ int Interpreter_interpret_file(Interpreter* interpreter, char* filename) {
FILE* stream = fopen(filename, "r");
if(stream == NULL) {
perror(filename);
return -1;
return ERROR_CODE_OPEN_FAILURE;
}

interpreter->filename = strdup(filename);
Expand Down
23 changes: 12 additions & 11 deletions src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <string.h>

#include "error_codes.h"
#include "lexer.h"

// --------
Expand Down Expand Up @@ -38,13 +39,13 @@ static int fill_buffer_until(Lexer* lexer, char** buffer, size_t initial_capacit
size_t capacity = initial_capacity;

if(*buffer != NULL || initial_capacity == 0 || *length != 0) {
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

*buffer = malloc(initial_capacity);

if(*buffer == NULL) {
return -1;
return ERROR_CODE_MALLOC_FAILURE;
}

if(!skip_first) {
Expand All @@ -67,7 +68,7 @@ static int fill_buffer_until(Lexer* lexer, char** buffer, size_t initial_capacit

new_buffer = realloc(*buffer, capacity);
if(new_buffer == NULL) {
return -2;
return ERROR_CODE_MALLOC_FAILURE;
}

*buffer = new_buffer;
Expand All @@ -82,7 +83,7 @@ static int fill_buffer_until(Lexer* lexer, char** buffer, size_t initial_capacit
lexer->finished = true;
lexer->error = true;

return 2;
return ERROR_CODE_UNEXPECTED_EOF;
}

// --------
Expand All @@ -98,7 +99,7 @@ int Lexer_init_at(Lexer* lexer, FILE* stream) {
lexer->col = 0;
lexer->finished = true;
lexer->error = true;
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

lexer->line = 1;
Expand All @@ -113,13 +114,13 @@ int Lexer_init_at(Lexer* lexer, FILE* stream) {
int Lexer_get_next_token(Lexer* lexer, Token* token) {

if(lexer == NULL || (lexer->finished | lexer->error)) {
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

if(token == NULL) {
lexer->finished = true;
lexer->error = true;
return 2;
return ERROR_CODE_INVALID_ARGUMENT;
}

memset(token, 0, sizeof(Token));
Expand Down Expand Up @@ -156,15 +157,15 @@ int Lexer_get_next_token(Lexer* lexer, Token* token) {
default:
lexer->error = true;
lexer->finished = true;
return 3;
return ERROR_CODE_UNEXPECTED_CHARACTER;
}

case LEXER_STATE_EXPECTING_TRACK_START:

if(lexer->symbol != '|') {
lexer->error = true;
lexer->finished = true;
return 4;
return ERROR_CODE_UNEXPECTED_CHARACTER;
}

lexer->state = LEXER_STATE_EXPECTING_BAR;
Expand Down Expand Up @@ -211,7 +212,7 @@ int Lexer_get_next_token(Lexer* lexer, Token* token) {
case LEXER_STATE_EXPECTING_BAR_COMMENT:

if(!(lexer->symbol == '/')) {
return 5;
return ERROR_CODE_UNEXPECTED_CHARACTER;
}

status = fill_buffer_until(lexer, &buffer, 16, &length, lexer->state == LEXER_STATE_EXPECTING_BAR_COMMENT? '|': '\n', true);
Expand All @@ -232,7 +233,7 @@ int Lexer_get_next_token(Lexer* lexer, Token* token) {
default:
lexer->error = true;
lexer->finished = true;
return 6;
return ERROR_CODE_INVALID_STATE;
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string.h>

#include "config.h"
#include "error_codes.h"
#include "mixer.h"
#include "wave.h"

Expand All @@ -16,7 +17,7 @@ int Mixer_init_at(Mixer* mixer) {
mixer->buffer = reallocarray(NULL, mixer->num_samples, sizeof(float));
if(mixer->buffer == NULL) {
perror("malloc");
return -1;
return ERROR_CODE_MALLOC_FAILURE;
}

Mixer_clear_buffer(mixer);
Expand All @@ -27,7 +28,7 @@ int Mixer_init_at(Mixer* mixer) {
int Mixer_clear_buffer(Mixer* mixer) {

if(mixer == NULL || mixer->buffer == NULL) {
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

generate_silence(mixer->buffer, mixer->num_samples);
Expand All @@ -50,11 +51,11 @@ void Mixer_destroy_at(Mixer* mixer) {
int Mixer_add_notes_from_instrument(Mixer* mixer, Instrument* instrument) {

if(mixer == NULL || mixer->buffer == NULL || instrument == NULL || instrument->buffer == NULL) {
return 1;
return ERROR_CODE_INVALID_ARGUMENT;
}

if(mixer->num_samples != instrument->num_samples) {
return 2;
return ERROR_CODE_INVALID_STATE;
}

for(size_t t = 0; t < mixer->num_samples; t++) {
Expand Down
Loading

0 comments on commit ac2d506

Please sign in to comment.