summaryrefslogblamecommitdiffstats
path: root/src/types.c
blob: d9253af657ff73e79d66366e6ff201257c36b18d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                               
           



              

              






                     










                                                                  










































































                                                              





                                   










                      








                                                    



















                                                                                 











                                        













                                                            
              












                                              


                                                         



                                                     









                                          


   










                                         








                                                        



























































                                                                        
#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);
    }
  }
}