rewrite to union type, much better
[ccc.git] / util.c
1 #include <stdarg.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5
6 #include "util.h"
7
8 struct list *list_cons(void *el, struct list *tail)
9 {
10 struct list *res = safe_malloc(sizeof(struct list));
11 res->el = el;
12 res->tail = tail;
13 return res;
14 }
15
16 void list_free(struct list *head, void (*freefun)(void *))
17 {
18 while (head != NULL) {
19 freefun(head->el);
20 head = head->tail;
21 }
22 }
23
24 void **list_to_array(struct list *list, int *num, bool reverse)
25 {
26 int i = list_length(list);
27 *num = i;
28 void **ptr = safe_malloc(i*sizeof(void *));
29
30 struct list *r = list;
31 while(i > 0) {
32 if (reverse)
33 ptr[--i] = r->el;
34 else
35 ptr[*num-(--i)] = r->el;
36 struct list *t = r;
37 r = r->tail;
38 free(t);
39 }
40 return ptr;
41 }
42
43 int list_length(struct list *r)
44 {
45 int i = 0;
46 while(r != NULL) {
47 i++;
48 r = r->tail;
49 }
50 return i;
51 }
52
53 void pdie(const char *msg)
54 {
55 perror(msg);
56 exit(1);
57 }
58
59 void die(const char *msg, ...)
60 {
61 va_list ap;
62 va_start(ap, msg);
63 vfprintf(stderr, msg, ap);
64 va_end(ap);
65 exit(1);
66 }
67
68 void pindent(int indent, FILE *out)
69 {
70 for (int i = 0; i<indent; i++)
71 if (fputc('\t', out) == EOF)
72 pdie("fputc");
73 }
74
75 void safe_fprintf(FILE *out, const char *msg, ...)
76 {
77 va_list ap;
78 va_start(ap, msg);
79 int r = vfprintf(out, msg, ap);
80 va_end(ap);
81 if (r < 0)
82 pdie("fprintf");
83 }
84
85 void *safe_malloc(size_t size)
86 {
87 void *res = malloc(size);
88 if (res == NULL)
89 pdie("malloc");
90 return res;
91 }
92
93 void *safe_strdup(const char *c)
94 {
95 char *res = strdup(c);
96 if (res == NULL)
97 pdie("strdup");
98 return res;
99 }