]> git.ozlabs.org Git - ccan/blob - _info
fe66c24e597ff1db63bce473d070a8ac04d42a4e
[ccan] / _info
1 #include <stdio.h>
2 #include <string.h>
3 #include "config.h"
4
5 /**
6  * talloc_link - link helper for talloc
7  *
8  * Talloc references can be confusing and buggy.  In the cases where an object
9  * needs multiple parents, all parents need to be aware of the situation; thus
10  * talloc_link is a helper where all "parents" talloc_link an object they
11  * agree to share ownership of.
12  *
13  * Example:
14  *      // Silly program which keeps a cache of uppercased strings.
15  *      // The cache wants to keep strings around even after they may have
16  *      // been "freed" by the caller.
17  *      #include <stdio.h>
18  *      #include <err.h>
19  *      #include <string.h>
20  *      #include <ctype.h>
21  *      #include <ccan/talloc/talloc.h>
22  *      #include <ccan/talloc_link/talloc_link.h>
23  *
24  *      struct upcache {
25  *              const char *str;
26  *              const char *upstr;
27  *      };
28  *
29  *      static struct upcache *cache;
30  *      static unsigned int cache_hits = 0;
31  *      #define CACHE_SIZE 4
32  *      void init_upcase(void)
33  *      {
34  *              cache = talloc_zero_array(NULL, struct upcache, CACHE_SIZE);
35  *      }
36  *
37  *      static struct upcache *lookup_upcase(const char *str)
38  *      {
39  *              unsigned int i;
40  *              for (i = 0; i < CACHE_SIZE; i++)
41  *                      if (cache[i].str && !strcmp(cache[i].str, str)) {
42  *                              cache_hits++;
43  *                              return &cache[i];
44  *                      }
45  *              return NULL;
46  *      }
47  *
48  *      static struct upcache *new_upcase(const char *str)
49  *      {
50  *              unsigned int i;
51  *              char *upstr;
52  *
53  *              upstr = talloc_linked(cache, talloc_strdup(NULL, str));
54  *              if (!upstr)
55  *                      return NULL;
56  *
57  *              i = random() % CACHE_SIZE;
58  *
59  *              // Throw out old: works fine if cache[i].upstr is NULL.
60  *              talloc_delink(cache, cache[i].upstr);
61  *
62  *              // Replace with new.
63  *              cache[i].str = str;
64  *              cache[i].upstr = upstr;
65  *              while (*upstr) {
66  *                      *upstr = toupper(*upstr);
67  *                      upstr++;
68  *              }
69  *              return &cache[i];
70  *      }
71  *
72  *      // If you want to keep the result, talloc_link it.
73  *      const char *get_upcase(const char *str)
74  *      {
75  *              struct upcache *uc = lookup_upcase(str);
76  *              if (!uc)
77  *                      uc = new_upcase(str);
78  *              if (!uc)
79  *                      return NULL;
80  *              return uc->upstr;
81  *      }
82  *
83  *      void exit_upcase(void)
84  *      {
85  *              talloc_free(cache);
86  *              printf("Cache hits: %u\n", cache_hits);
87  *      }
88  *
89  *      int main(int argc, char *argv[])
90  *      {
91  *              unsigned int i;
92  *              const char **values;
93  *
94  *              // Will dump any memory leaks to stderr on exit.
95  *              talloc_enable_leak_report();
96  *
97  *              // Initialize cache.
98  *              init_upcase();
99  *
100  *              // Throw values in.
101  *              values = talloc_array(NULL, const char *, argc);
102  *              for (i = 1; i < argc; i++) {
103  *                      values[i-1] = talloc_link(values, get_upcase(argv[i]));
104  *                      if (!values[i-1])
105  *                              err(1, "Out of memory");
106  *              }
107  *              // This will free all the values, but cache will still work.
108  *              talloc_free(values);
109  *
110  *              // Repeat!
111  *              values = talloc_array(NULL, const char *, argc);
112  *              for (i = 1; i < argc; i++) {
113  *                      values[i-1] = talloc_link(values, get_upcase(argv[i]));
114  *                      if (!values[i-1])
115  *                              err(1, "Out of memory");
116  *              }
117  *
118  *              // This will remove cache links, but we still have a link.
119  *              exit_upcase();
120  *
121  *              // Show values, so we output something.
122  *              for (i = 0; i < argc - 1; i++)
123  *                      printf("%s ", values[i]);
124  *              printf("\n");
125  *
126  *              // This will finally free the upcase strings (last link).
127  *              talloc_free(values);
128  *
129  *              return 0;
130  *      }
131  *
132  * Licence: GPL (2 or any later version)
133  */
134 int main(int argc, char *argv[])
135 {
136         if (argc != 2)
137                 return 1;
138
139         if (strcmp(argv[1], "depends") == 0) {
140                 printf("ccan/talloc\n");
141                 printf("ccan/list\n");
142                 return 0;
143         }
144
145         return 1;
146 }