commit 96978f737a38b5587e04360ebd78684ec26346f5
parent 82618ad625d4d97f4ac7eaa61acd67e3aa4a9eb5
Author: William Casarin <jb55@jb55.com>
Date: Fri, 3 Jul 2020 08:32:59 -0700
cleanups, word helpers
Diffstat:
M | describe.c | | | 99 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
1 file changed, 78 insertions(+), 21 deletions(-)
diff --git a/describe.c b/describe.c
@@ -2,6 +2,8 @@
#include "describe.h"
#include <assert.h>
#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
#define ADJ_PUSHED 1
#define ADJ_NOT_PUSHED 2
@@ -14,6 +16,26 @@ struct describe {
struct cursor *strs;
};
+static int push_sized_word(struct cursor *strs, const char *str, int len)
+{
+ int ok;
+
+ if (strs->p-1 >= strs->start && !isspace(*(strs->p-1))) {
+ ok = push_str(strs, " ");
+ if (!ok) return 0;
+ }
+
+ ok = push_sized_str(strs, str, len);
+ if (!ok) return 0;
+
+ return 1;
+}
+
+static int push_word(struct cursor *strs, const char *str)
+{
+ return push_sized_word(strs, str, strlen(str));
+}
+
static int push_adjective(struct cursor *strs, struct attribute *attr)
{
int ok;
@@ -73,7 +95,7 @@ static int push_adjectives(struct describe *desc)
if (adjs > 0) {
if (adjs == adj_count-1)
- push_str(desc->strs, " and");
+ push_word(desc->strs, "and");
else if (adjs != adj_count-1)
push_str(desc->strs, ",");
@@ -87,29 +109,38 @@ static int push_adjectives(struct describe *desc)
return 1;
}
-static int push_made_of(struct describe *desc)
+static int find_attr(struct cursor *attrs, struct cell *cell,
+ enum attribute_type type, struct attribute **attr)
{
- struct attribute *attr;
- int i, ok;
-
- for (i = 0; i < desc->cell->n_attributes; i++) {
- attr = get_attr(desc->parsed->attributes,
- desc->cell->attributes[i]);
- assert(attr);
+ int i;
- if (attr->type == A_MATERIAL) {
- ok = push_str(desc->strs, " made of ");
- if (!ok) return 0;
+ for (i = 0; i < cell->n_attributes; i++) {
+ *attr = get_attr(attrs, cell->attributes[i]);
+ assert(*attr);
- ok = push_sized_str(desc->strs,
- attr->data.str.ptr,
- attr->data.str.len);
- if (!ok) return 0;
+ if ((*attr)->type == type)
return 1;
- }
}
- return 2;
+ return 0;
+}
+
+static int push_made_of(struct describe *desc)
+{
+ struct attribute *attr;
+ int ok;
+
+ ok = find_attr(desc->parsed->attributes, desc->cell,
+ A_MATERIAL, &attr);
+ if (!ok) return 2;
+
+ ok = push_word(desc->strs, "made of");
+ if (!ok) return 0;
+
+ ok = push_sized_word(desc->strs, attr->data.str.ptr,
+ attr->data.str.len);
+ if (!ok) return 0;
+ return 1;
}
static int push_named(struct describe *desc)
@@ -123,15 +154,38 @@ static int push_named(struct describe *desc)
if (name_len == 0)
return 1;
- ok = push_str(desc->strs, " named ");
+ ok = push_word(desc->strs, "named");
if (!ok) return 0;
- ok = push_sized_str(desc->strs, name, name_len);
+ ok = push_sized_word(desc->strs, name, name_len);
if (!ok) return 0;
return 1;
}
+static int push_shape(struct describe *desc)
+{
+ struct attribute *attr;
+ int ok;
+
+ ok = find_attr(desc->parsed->attributes, desc->cell, A_SHAPE, &attr);
+ if (!ok) return 2;
+
+ switch (attr->data.shape) {
+ case SHAPE_RECTANGLE:
+ push_word(desc->strs, "rectangular");
+ break;
+ case SHAPE_CIRCLE:
+ push_word(desc->strs, "circular");
+ break;
+ case SHAPE_SQUARE:
+ push_word(desc->strs, "square");
+ break;
+ }
+
+ return 1;
+}
+
static int describe_room(struct describe *desc)
{
int ok;
@@ -143,7 +197,10 @@ static int describe_room(struct describe *desc)
ok = push_adjectives(desc);
if (!ok) return 0;
- ok = push_str(desc->strs, " room");
+ ok = push_shape(desc);
+ if (!ok) return 0;
+
+ ok = push_word(desc->strs, "room");
if (!ok) return 0;
ok = push_made_of(desc);