Added terminal print callbacks

Resolved #127
This commit is contained in:
2024-10-05 23:26:20 +10:00
parent ad44eeac48
commit 4805c6757a
6 changed files with 204 additions and 18 deletions

View File

@@ -1,4 +1,5 @@
#include "toy.h" #include "toy.h"
#include "toy_print.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -156,8 +157,17 @@ CmdLine parseCmdLine(int argc, const char* argv[]) {
return cmd; return cmd;
} }
//callback
static void errorAndExit(const char* msg) {
fprintf(stderr, "%s", msg);
exit(-1);
}
//main file //main file
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
Toy_setErrorCallback(errorAndExit);
Toy_setAssertFailureCallback(errorAndExit);
CmdLine cmd = parseCmdLine(argc, argv); CmdLine cmd = parseCmdLine(argc, argv);
if (cmd.error) { if (cmd.error) {

51
source/toy_print.c Normal file
View File

@@ -0,0 +1,51 @@
#include "toy_print.h"
#include <stdio.h>
static void outDefault(const char* msg) {
fprintf(stdout, "%s", msg);
}
static void errDefault(const char* msg) {
fprintf(stderr, "%s", msg);
}
static Toy_callbackType printCallback = outDefault;
static Toy_callbackType errorCallback = errDefault;
static Toy_callbackType assertCallback = errDefault;
void Toy_print(const char* msg) {
printCallback(msg);
}
void Toy_error(const char* msg) {
errorCallback(msg);
}
void Toy_assertFailure(const char* msg) {
assertCallback(msg);
}
void Toy_setPrintCallback(Toy_callbackType cb) {
printCallback = cb;
}
void Toy_setErrorCallback(Toy_callbackType cb) {
errorCallback = cb;
}
void Toy_setAssertFailureCallback(Toy_callbackType cb) {
assertCallback = cb;
}
void Toy_resetPrintCallback() {
printCallback = outDefault;
}
void Toy_resetErrorCallback() {
errorCallback = errDefault;
}
void Toy_resetAssertFailureCallback() {
assertCallback = errDefault;
}

17
source/toy_print.h Normal file
View File

@@ -0,0 +1,17 @@
#include "toy_common.h"
//handle callbacks for printing to the terminal, or elsewhere
typedef void (*Toy_callbackType)(const char*);
TOY_API void Toy_print(const char* msg); //print keyword
TOY_API void Toy_error(const char* msg); //runtime errors
TOY_API void Toy_assertFailure(const char* msg); //assert keyword failures
TOY_API void Toy_setPrintCallback(Toy_callbackType cb);
TOY_API void Toy_setErrorCallback(Toy_callbackType cb);
TOY_API void Toy_setAssertFailureCallback(Toy_callbackType cb);
TOY_API void Toy_resetPrintCallback();
TOY_API void Toy_resetErrorCallback();
TOY_API void Toy_resetAssertFailureCallback();

View File

@@ -1,5 +1,6 @@
#include "toy_table.h" #include "toy_table.h"
#include "toy_console_colors.h" #include "toy_console_colors.h"
#include "toy_print.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -58,8 +59,7 @@ static Toy_Table* adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapac
Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table)); Toy_Table* newTable = malloc(newCapacity * sizeof(Toy_TableEntry) + sizeof(Toy_Table));
if (newTable == NULL) { if (newTable == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Table' of %u capacity\n" TOY_CC_RESET, newCapacity); Toy_error(TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Table'\n" TOY_CC_RESET);
exit(-1);
} }
newTable->capacity = newCapacity; newTable->capacity = newCapacity;
@@ -99,8 +99,7 @@ void Toy_freeTable(Toy_Table* table) {
void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) { void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET); Toy_error(TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
} }
//expand the capacity //expand the capacity
@@ -113,8 +112,7 @@ void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) {
Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) { Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET); Toy_error(TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
} }
//lookup //lookup
@@ -138,8 +136,7 @@ Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) { void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET); Toy_error(TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
} }
//lookup //lookup

View File

@@ -1,14 +1,13 @@
#include "toy_value.h" #include "toy_value.h"
#include "toy_console_colors.h" #include "toy_console_colors.h"
#include "toy_print.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
bool Toy_private_isTruthy(Toy_Value value) { bool Toy_private_isTruthy(Toy_Value value) {
//null is an error //null is an error
if (TOY_VALUE_IS_NULL(value)) { if (TOY_VALUE_IS_NULL(value)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: 'null' is neither true nor false\n" TOY_CC_RESET); Toy_error(TOY_CC_ERROR "ERROR: 'null' is neither true nor false\n" TOY_CC_RESET);
exit(-1); //TODO: #127
} }
//only 'false' is falsy //only 'false' is falsy
@@ -23,8 +22,7 @@ bool Toy_private_isTruthy(Toy_Value value) {
bool Toy_private_isEqual(Toy_Value left, Toy_Value right) { bool Toy_private_isEqual(Toy_Value left, Toy_Value right) {
//temp check //temp check
if (right.type > TOY_VALUE_FLOAT) { if (right.type > TOY_VALUE_FLOAT) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown types %d and %d in equality\n" TOY_CC_RESET, left.type, right.type); Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality comparison\n" TOY_CC_RESET); //TODO: varargs
exit(-1);
} }
switch(left.type) { switch(left.type) {
@@ -58,9 +56,10 @@ bool Toy_private_isEqual(Toy_Value left, Toy_Value right) {
case TOY_VALUE_FUNCTION: case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE: case TOY_VALUE_OPAQUE:
default: default:
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown types %d and %d in equality\n" TOY_CC_RESET, left.type, right.type); Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality comparison\n" TOY_CC_RESET); //TODO: varargs
exit(-1);
} }
return 0;
} }
//hash utils //hash utils
@@ -103,7 +102,8 @@ unsigned int Toy_hashValue(Toy_Value value) {
case TOY_VALUE_FUNCTION: case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE: case TOY_VALUE_OPAQUE:
default: default:
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't hash an unknown type %d\n" TOY_CC_RESET, value.type); Toy_error(TOY_CC_ERROR "ERROR: Can't hash an unknown type\n" TOY_CC_RESET);
exit(-1);
} }
return 0;
} }

111
tests/cases/test_print.c Normal file
View File

@@ -0,0 +1,111 @@
#include "toy_print.h"
#include "toy_console_colors.h"
#include <stdio.h>
int counter = 0;
void count(const char* msg) {
counter++;
}
int test_callbacks() {
//set a custom print callback, invoke it, and reset
{
//setup
Toy_setPrintCallback(count);
//invoke
Toy_print("");
//check
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to set print callback\n" TOY_CC_RESET);
return -1;
}
//reset and retry
Toy_resetPrintCallback();
Toy_print("");
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to reset print callback\n" TOY_CC_RESET);
return -1;
}
//cleanup
counter = 0;
}
//set a custom error callback, invoke it, and reset
{
//setup
Toy_setErrorCallback(count);
//invoke
Toy_error("");
//check
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to set error callback\n" TOY_CC_RESET);
return -1;
}
//reset and retry
Toy_resetErrorCallback();
Toy_error("");
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to reset error callback\n" TOY_CC_RESET);
return -1;
}
//cleanup
counter = 0;
}
//set a custom assert failure callback, invoke it, and reset
{
//setup
Toy_setAssertFailureCallback(count);
//invoke
Toy_assertFailure("");
//check
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to set assert failure callback\n" TOY_CC_RESET);
return -1;
}
//reset and retry
Toy_resetAssertFailureCallback();
Toy_assertFailure("");
if (counter != 1) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to reset assert failure callback\n" TOY_CC_RESET);
return -1;
}
//cleanup
counter = 0;
}
return 0;
}
int main() {
//run each test set, returning the total errors given
int total = 0, res = 0;
{
res = test_callbacks();
if (res == 0) {
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
}
total += res;
}
return total;
}