]> git.wh0rd.org - fontconfig.git/blob - src/fcformat.c
Implement FcPatternFormat and use it in cmdline tools (bug #17107)
[fontconfig.git] / src / fcformat.c
1 /*
2 * Copyright © 2008 Red Hat, Inc.
3 *
4 * Red Hat Author(s): Behdad Esfahbod
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
15 *
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 #include "fcint.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29
30
31 static void
32 message (const char *fmt, ...)
33 {
34 va_list args;
35 va_start (args, fmt);
36 fprintf (stderr, "Fontconfig: ");
37 vfprintf (stderr, fmt, args);
38 fprintf (stderr, "\n");
39 va_end (args);
40 }
41
42
43 static FcChar8 *scratch1;
44 static FcChar8 *scratch2;
45 static const FcChar8 *format_orig;
46
47 static const FcChar8 *
48 interpret_percent (FcPattern *pat,
49 FcStrBuf *buf,
50 const FcChar8 *format)
51 {
52 switch (*format) {
53 case '{':
54 {
55 FcChar8 *p;
56 FcPatternElt *e;
57
58 format++; /* skip over '{' */
59
60 p = (FcChar8 *) strpbrk ((const char *) format, "}");
61 if (!p)
62 {
63 message ("Pattern format missing closing brace");
64 return format;
65 }
66 /* extract the element name */
67 memcpy (scratch1, format, p - format);
68 scratch1[p - format] = '\0';
69
70 e = FcPatternObjectFindElt (pat, FcObjectFromName ((const char *) scratch1));
71 if (e)
72 {
73 FcValueListPtr l;
74 l = FcPatternEltValues(e);
75 FcNameUnparseValueList (buf, l, '\0');
76 }
77
78 p++; /* skip over '}' */
79 return p;
80 }
81 default:
82 message ("Pattern format has invalid character after '%%' at %d",
83 format - format_orig);
84 return format;
85 }
86 }
87
88 static char escaped_char(const char ch)
89 {
90 switch (ch) {
91 case 'a': return '\a';
92 case 'b': return '\b';
93 case 'f': return '\f';
94 case 'n': return '\n';
95 case 'r': return '\r';
96 case 't': return '\t';
97 case 'v': return '\v';
98 default: return ch;
99 }
100 }
101
102 static const FcChar8 *
103 interpret (FcPattern *pat,
104 FcStrBuf *buf,
105 const FcChar8 *format,
106 FcChar8 term)
107 {
108 const FcChar8 *end;
109
110 for (end = format; *end && *end != term;)
111 {
112 switch (*end)
113 {
114 case '\\':
115 end++; /* skip over '\\' */
116 FcStrBufChar (buf, escaped_char (*end++));
117 continue;
118 case '%':
119 end++; /* skip over '%' */
120 if (*end == '%')
121 break;
122 end = interpret_percent (pat, buf, end);
123 continue;
124 }
125 FcStrBufChar (buf, *end);
126 end++;
127 }
128 if (*end != term)
129 message ("Pattern format ended while looking for '%c'", term);
130
131 return end;
132 }
133
134 FcChar8 *
135 FcPatternFormat (FcPattern *pat, const FcChar8 *format)
136 {
137 int len;
138 FcStrBuf buf;
139
140 FcStrBufInit (&buf, 0, 0);
141 len = strlen ((const char *) format);
142 scratch1 = malloc (len);
143 scratch2 = malloc (len);
144 format_orig = format;
145
146 interpret (pat, &buf, format, '\0');
147
148 free (scratch1);
149 free (scratch2);
150 return FcStrBufDone (&buf);
151 }
152
153 #define __fcformat__
154 #include "fcaliastail.h"
155 #undef __fcformat__