make cleanup and some bash-ism removal
[charfbuzz.git] / hb-shaper.c
blobd1c8f9740fec1b4d19e0967f60391f1c5b17d155
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
4 #include <string.h>
5 #include <stdlib.h>
7 #include "hb.h"
8 #include "hb-private.h"
9 #include "hb-atomic-private.h"
10 #include "hb-shaper-private.h"
12 static struct hb_shaper_pair_t all_shapers[] = {
13 #ifdef HAVE_GRAPHITE2
14 {"graphite2", hb_graphite2_shape},
15 #endif
16 #ifdef HAVE_OT
17 {"ot", hb_ot_shape},
18 #endif
19 {"fallback", hb_fallback_shape}
22 //Thread-safe, lock-free, shapers
24 static struct hb_shaper_pair_t *static_shapers = NULL;
26 struct hb_shaper_pair_t *
27 hb_shapers_get(void)
29 while (1) {
30 struct hb_shaper_pair_t *shapers = hb_atomic_ptr_get(&static_shapers);
31 if (shapers)
32 return shapers;
34 char *env = getenv("HB_SHAPER_LIST");
35 if (!env || !*env) {
36 void *expected = NULL;
37 void *desired = &all_shapers[0];
38 hb_atomic_ptr_cmpexch(&static_shapers, &expected, &desired);
39 return all_shapers;
42 //Not found; allocate one
43 shapers = malloc(sizeof(all_shapers));
44 if (!shapers) {
45 void *expected = NULL;
46 void *desired = &all_shapers[0];
47 hb_atomic_ptr_cmpexch(&static_shapers, &expected, &desired);
48 return all_shapers;
51 memcpy(shapers, all_shapers, sizeof(all_shapers));
53 //Reorder shaper list to prefer requested shapers.
54 unsigned i = 0;
55 char *end, *p = env;
56 for (;;) {
57 end = strchr(p, ',');
58 if (!end)
59 end = p + strlen(p);
61 for (unsigned j = i; j < ARRAY_LENGTH(all_shapers); ++j)
62 if (end - p == (int)strlen(shapers[j].name) &&
63 0 == strncmp(shapers[j].name, p, end - p)) {
64 //Reorder this shaper to position i
65 struct hb_shaper_pair_t t = shapers[j];
66 memmove(&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
67 shapers[i] = t;
68 i++;
71 if (!*end)
72 break;
73 else
74 p = end + 1;
77 void *expected = NULL;
78 if (hb_atomic_ptr_cmpexch(&static_shapers, &expected, &shapers)) {
79 return shapers;
81 free(shapers);