aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolden Rohrer <hr@hrhr.dev>2020-05-28 21:36:28 -0400
committerHolden Rohrer <hr@hrhr.dev>2020-05-28 21:36:28 -0400
commit25e8bb52e091c4c546502546b23c932e4d59cddb (patch)
tree9a44c222b801a3c2eaa16867228c6b79d58e3011
parent003a1e962aab767a030dab1d451fe0abc52bd32f (diff)
improved error handling and ignorance of trailing ws
-rw-r--r--README4
-rw-r--r--badroff.c37
2 files changed, 32 insertions, 9 deletions
diff --git a/README b/README
index 1815214..843ffbf 100644
--- a/README
+++ b/README
@@ -47,4 +47,6 @@ It mostly segfaults on line overfill (i.e. trying to center oversized
text or unfoldable lines are completely unhandled). Error handling
should probably be used, but that is a nontrivial addition.
-Nonexistent commands also cause segfaults.
+# Return Value
+
+Returns 0 on success and 1 on syntax error.
diff --git a/badroff.c b/badroff.c
index 213a9c9..66fce40 100644
--- a/badroff.c
+++ b/badroff.c
@@ -2,6 +2,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <ctype.h>
#include "buf.h"
#include "sb.h"
@@ -69,8 +70,15 @@ size_t chrnfill(char chr, size_t sz){//fills to first of chr or sz
static int width = 80;
static char nbsp = 0;
+static char* strdup(char* str){
+ char* out = malloc(sizeof(char)*(strlen(str)+1));
+ strcpy(out,str);
+ return out;
+}
+
static char* center(char* txt){
- size_t len = strlen(txt);
+ int len = strlen(txt);
+ if (len >= width) return strdup(txt);
int max = width/2 + len/2; // excluding terminator
int min = max-len+1; // first index of *txt
char* str = malloc(sizeof(char)*(max + 2));
@@ -96,10 +104,16 @@ static char* token(char* txt, char c) {
return end+1;
}
static char* leader(char* txt){
- char* start = txt;
- char* repeat = token(start, '|');
- char* end = token(repeat, '|');
- char* fin = malloc(sizeof(char)*(width+2));
+ char *start, *repeat, *end, *fin;
+ start = txt;
+ if ( !(repeat = token(start, '|') ) ) {
+ repeat = " . ";
+ end = "";
+ } else if ( !(end = token(repeat, '|') ) ) {
+ repeat = " . ";
+ end = repeat;
+ }
+ fin = malloc(sizeof(char)*(width+2));
fin[width] = '\n'; fin[width+1] = 0;
strcpy(fin, start);
size_t max = width-strlen(end); size_t rptln = strlen(repeat);
@@ -206,7 +220,7 @@ static char* fingroup(char* txt){
return emptalloc();
}
static char* vert(char* txt){
- int ln; sscanf(txt, "%d", &ln);
+ int ln; if (isdigit(*txt)) sscanf(txt, "%d", &ln); else ln = 1;
return chrmult('\n', ln);
}
static char* nbrkspc(char* txt){
@@ -255,8 +269,9 @@ static char* (*call[])(char* txt) =
static char* cmd(void){
char* dat = popstrbuf(inbuf, chrfill('\n'));
- size_t low = 0; size_t high = sizeof(cmds)/sizeof(*cmds); //len
+ int low = 0; int high = sizeof(cmds)/sizeof(*cmds); //len
char* proc = NULL;
+ bool found = false;
while (high >= low){
int mid = ((unsigned int)low + (unsigned int)high) >> 1;
char* mval = cmds[mid];
@@ -267,12 +282,17 @@ static char* cmd(void){
else if (cmp > 0)
low = mid + 1;
else{
+ found = true;
proc = call[mid](dat+strlen(mval));
break;
}
}
free(dat);
- return proc;
+ if (found) return proc;
+ else {
+ fprintf(stderr, "SYNTAX ERROR\n");
+ exit(1);
+ }
}
// normal typesetting
@@ -345,6 +365,7 @@ char* line(void){
out = norm();
}
nbspsub(out);
+ wsclean(out);
return out;
}