-
Notifications
You must be signed in to change notification settings - Fork 10
/
fruit.c
111 lines (100 loc) · 2.28 KB
/
fruit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Example application data structure.
*
* Define some simple structures to convert to and from yaml, and some helper
* functions for our example program.
*
* You'll want to handle ENOMEM errors more gracefully in a real program, but
* to keep our example simple, we just bail if we cannot allocate memory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fruit.h"
/* Helper to bail on error. */
void
bail(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
/* Helper to allocate memory or bail. */
void *
bail_alloc(size_t size)
{
void *p = calloc(1, size);
if (!p) {
bail("out of memory");
}
return p;
}
/* Helper to copy a string or bail. */
char *
bail_strdup(const char *s)
{
char *c = strdup(s ? s : "");
if (!c) {
bail("out of memory");
}
return c;
}
void
add_fruit(struct fruit **fruits, char *name, char *color, int count, struct variety *varieties)
{
/* Create fruit object. */
struct fruit *f = bail_alloc(sizeof(*f));
f->name = bail_strdup(name);
f->color = bail_strdup(color);
f->count = count;
f->varieties = varieties;
/* Append to list. */
if (!*fruits) {
*fruits = f;
} else {
struct fruit *tail = *fruits;
while (tail->next) {
tail = tail->next;
}
tail->next = f;
}
}
void
add_variety(struct variety **varieties, char *name, char *color, bool seedless)
{
/* Create variety object. */
struct variety *v = bail_alloc(sizeof(*v));
v->name = bail_strdup(name);
v->color = bail_strdup(color);
v->seedless = seedless;
/* Append to list. */
if (!*varieties) {
*varieties = v;
} else {
struct variety *tail = *varieties;
while (tail->next) {
tail = tail->next;
}
tail->next = v;
}
}
void
destroy_fruits(struct fruit **fruits)
{
for (struct fruit *f = *fruits; f; f = *fruits) {
*fruits = f->next;
free(f->name);
free(f->color);
destroy_varieties(&f->varieties);
free(f);
}
}
void
destroy_varieties(struct variety **varieties)
{
for (struct variety *v = *varieties; v; v = *varieties) {
*varieties = v->next;
free(v->name);
free(v->color);
free(v);
}
}