summaryrefslogtreecommitdiffstats
path: root/src/types.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/types.c b/src/types.c
new file mode 100644
index 0000000..d9253af
--- /dev/null
+++ b/src/types.c
@@ -0,0 +1,299 @@
+#include <stdlib.h>
+
+#include "types.h"
+#include "util.h"
+
+recipe *
+new_recipe()
+{
+ recipe * r;
+ r = (recipe *) malloc(sizeof(recipe));
+ if (!r)
+ die("Couldn't allocate memory for recipe");
+
+ r->n = 1;
+ r->i = NULL;
+ r->in = 0;
+ r->s = NULL;
+ r->sn = 0;
+ r->r = NULL;
+ r->rn = 0;
+ r->filename = NULL;
+ r->path = NULL;
+ r->title = NULL;
+ return r;
+}
+
+void
+new_subrecipe(recipe * r, recipe * src)
+{
+ r->r = (recipe **)realloc(r->r, (r->rn + 1) * sizeof(recipe *));
+ if (!r->r)
+ die("Couldn't allocate memory for subricepie");
+
+ r->r[r->rn] = src;
+ r->rn++;
+}
+
+void
+new_item(recipe * r)
+{
+ r->i = (item **)realloc(r->i, (r->in + 1) * sizeof(item *));
+ if (!r->i)
+ die("Couldn't allocate memory for item");
+
+ r->i[r->in] = (item *)malloc(sizeof(item));
+ if (!r->i[r->in])
+ die("Couldn't allocate memory for item");
+ r->i[r->in]->name = NULL;
+ r->i[r->in]->qty = NULL;
+ r->in++;
+}
+
+void
+free_item(item * i)
+{
+ if (!i)
+ return;
+ if (i->name)
+ free(i->name);
+ if (i->qty)
+ free(i->qty);
+ free(i);
+}
+
+void
+new_step(recipe * r)
+{
+ r->s = (step **)realloc(r->s, (r->sn + 1) * sizeof(step *));
+ if (!r->s)
+ die("Couldn't allocate memory for step");
+
+ r->s[r->sn] = (step *)malloc(sizeof(step));
+ if (!r->s[r->sn])
+ die("Couldn't allocate memory for item");
+ r->s[r->sn]->inst = NULL;
+ r->s[r->sn]->duration = NULL;
+ r->s[r->sn]->result = NULL;
+ r->s[r->sn]->type = 0;
+ r->sn++;
+}
+
+void
+free_step(step * s)
+{
+ if (!s)
+ return;
+ if (s->inst)
+ free(s->inst);
+ if (s->duration)
+ free(s->duration);
+ if (s->result)
+ free(s->result);
+ free(s);
+}
+
+void
+free_recipe(recipe * r)
+{
+ if (!r)
+ return;
+
+ if (r->i) {
+ for (int i = 0; i < r->in; i++)
+ free_item(r->i[i]);
+ free(r->i);
+ }
+
+ if (r->s) {
+ for (int i = 0; i < r->sn; i++)
+ free_step(r->s[i]);
+ free(r->s);
+ }
+
+ if (r->r) {
+ for (int i = 0; i < r->rn; i++)
+ free_recipe(r->r[i]);
+ free(r->r);
+ }
+
+ if (r->filename)
+ free(r->filename);
+ if (r->path)
+ free(r->path);
+ if (r->title)
+ free(r->title);
+
+ free(r);
+}
+
+void
+pprint_items(recipe * r)
+{
+ printf("Ingredients for %s:\n", r->title);
+ for (int i = 0; i < r->in; i++)
+ printf("%s: %s\n", r->i[i]->name, r->i[i]->qty);
+ printf("\n");
+}
+
+void
+show(recipe * r)
+{
+ printf("Filename\t%s\n", r->filename);
+ printf("Dirname\t\t%s\n", r->path);
+ printf("Title\t\t%s\n\n", r->title);
+
+ for (int i = 0; i < r->in; i++)
+ printf("I:%s\t%s\n", r->i[i]->name, r->i[i]->qty);
+ if (r->sn) {
+ printf("\nSteps:\n~~~~~~\n\n");
+ for (int i = 0; i < r->sn; i++)
+ printf("%s: %s\n", r->s[i]->type == PREP ? "PREP" : "COOK", r->s[i]->inst);
+ }
+}
+
+void
+tojson(recipe * r)
+{
+ printf("{\"filename\":\"%s\",", r->filename);
+ printf("\"dirname\":\"%s\",", r->path);
+ printf("\"title\":\"%s\",", r->title);
+ printf("\"n\":\"%d\"", r->n);
+ if (r->rn) {
+ printf(",\"subrecipes\":[");
+ int i = 0;
+ for (; i < r->rn - 1; i++) {
+ tojson(r->r[i]);
+ printf(",");
+ }
+ tojson(r->r[i]);
+ printf("]");
+ }
+ if (r->in) {
+ printf(",\"ingredients\":{");
+ int i = 0;
+ for (; i < r->in - 1; i++)
+ printf("\"%s\":\"%s\",", r->i[i]->name, r->i[i]->qty);
+ printf("\"%s\":\"%s\"}", r->i[i]->name, r->i[i]->qty);
+ }
+ if (r->sn) {
+ printf(",\"steps\":[");
+ int i = 0;
+ for (; i < r->sn - 1; i++)
+ printf("\"%s\",", r->s[i]->inst);
+ printf("\"%s\"]", r->s[i]->inst);
+ }
+ printf("}");
+}
+
+void
+tohtml(recipe * r)
+{
+ printf("todo\n");
+}
+
+void
+torcp(recipe * r)
+{
+ printf("# %s/%s\n\n", r->path, r->filename);
+ printf("@%s\n\n", r->title);
+ for (int i = 0; i < r->rn; i++) {
+ printf("!%s/%s\n", r->r[i]->path, r->r[i]->filename);
+ }
+ for (int i = 0; i < r->in; i++)
+ printf("%s = %s\n", r->i[i]->name, r->i[i]->qty);
+ if (r->sn) {
+ printf("\n---\n\n");
+ for (int i = 0; i < r->sn; i++) {
+ char c;
+ if (r->s[i]->type == PREP)
+ c = '-';
+ else if (r->s[i]->type == COOK)
+ c = '>';
+ else
+ c = '+';
+ printf("%c %s\n", c, r->s[i]->inst);
+ }
+ }
+}
+
+void
+copy_metadata(recipe * dst, recipe * src)
+{
+ if (!dst || !src) return;
+ dst->filename = strdup(src->filename);
+ dst->path = strdup(src->path);
+ dst->title = strdup(src->title);
+}
+
+void
+copy_items(recipe * dst, recipe * src)
+{
+ if (!dst || !src) return;
+ for (int i = 0; i < src->in; i++) {
+ new_item(dst);
+ dst->i[dst->in - 1]->name = strdup(src->i[i]->name);
+ dst->i[dst->in - 1]->qty = strdup(src->i[i]->qty);
+ }
+}
+
+static void
+join_subrecipe_items(recipe * dst, recipe * src)
+{
+ if (!src || !dst) return;
+ for (int i = 0; i < src->rn; i++) {
+ join_subrecipe_items(dst, src->r[i]);
+ for (int j = 0; j < src->r[i]->in; j++) {
+ new_item(dst);
+ dst->i[dst->in - 1]->name = strdup(src->r[i]->i[j]->name);
+ if (src->r[i]->n > 1) {
+ char tmp[2048] = "";
+ sprintf(tmp, "%d X ( %s )", src->r[i]->n, src->r[i]->i[j]->qty);
+ dst->i[dst->in - 1]->qty = strdup(tmp);
+ }
+ else {
+ dst->i[dst->in - 1]->qty = strdup(src->r[i]->i[j]->qty);
+ }
+ }
+ }
+}
+
+void
+merge_items(recipe * dst, recipe * src)
+{
+ /* Join all items in src's subrecipes to dst */
+ join_subrecipe_items(dst, src);
+ /* Copy src items as well to dst */
+ copy_items(dst, src);
+}
+
+static int
+item_exists(const char * name, const recipe * r)
+{
+ for (int i = 0; i < r->in; i++)
+ if (!strcmp(r->i[i]->name, name))
+ return i;
+ return -1;
+}
+
+void
+distinct_sum_items(recipe * dst, recipe * src)
+{
+ if (!dst || !src) return;
+ for (int i = 0; i < src->in; i++) {
+ int n = item_exists(src->i[i]->name, dst);
+ if (n != -1) {
+ char tmp[2048] = "";
+ strcat(tmp, dst->i[n]->qty);
+ strcat(tmp, " + ");
+ strcat(tmp, src->i[i]->qty);
+ free(dst->i[n]->qty);
+ dst->i[n]->qty = strdup(tmp);
+ }
+ else {
+ new_item(dst);
+ dst->i[dst->in - 1]->name = strdup(src->i[i]->name);
+ dst->i[dst->in - 1]->qty = strdup(src->i[i]->qty);
+ }
+ }
+}