fix %Vi again
[kugel-rb.git] / utils / skinupdater / skinupdater.c
blobdd4d2f338b0930fc1916cf92713ba39eb03c67a5
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: tag_table.c 26346 2010-05-28 02:30:27Z jdgordon $
10 * Copyright (C) 2010 Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include "tag_table.h"
29 #define PUTCH(out, c) fprintf(out, "%c", c)
30 extern struct tag_info legal_tags[];
32 char images_with_subimages[100];
33 int image_count = 0;
35 /** Command line setting **/
36 bool is_mono_display = false;
37 bool use_new_vp_tags = true;
40 /* dump "count" args to output replacing '|' with ',' except after the last count.
41 * return the amount of chars read. (start+return will be after the last | )
43 int dump_arg(FILE* out, const char* start, int count, bool close)
45 int l = 0;
46 while (count)
48 if (start[l] == '|')
50 if (count > 1)
52 PUTCH(out, ',');
53 } else if (close) {
54 PUTCH(out, ')');
56 count--;
57 } else {
58 if (find_escape_character(start[l]))
60 PUTCH(out, '%');
62 PUTCH(out, start[l]);
64 l++;
66 return l;
69 int dump_viewport_tags(FILE* out, const char* start)
71 int len = 0;
72 if (is_mono_display)
74 return dump_arg(out, start, 5, true);
76 else
78 int arg_count = use_new_vp_tags?5:7;
79 len += dump_arg(out, start, arg_count, true);
80 if (!use_new_vp_tags)
81 return len;
82 if (start[len] != '-')
84 fprintf(out, "%%Vf(");
85 len += dump_arg(out, start+len, 1, true);
87 else
89 while (start[len++] != '|');
91 if (start[len] != '-')
93 fprintf(out, "%%Vb(");
94 len += dump_arg(out, start+len, 1, true);
96 else
98 while (start[len++] != '|');
101 return len;
104 #define MATCH(s) (!strcmp(tag->name, s))
105 int parse_tag(FILE* out, const char* start, bool in_conditional)
107 struct tag_info *tag;
108 int len = 0;
109 for(tag = legal_tags;
110 tag->name[0] && strncmp(start, tag->name, strlen(tag->name)) != 0;
111 tag++) ;
112 if (!tag->name[0])
113 return -1;
114 if (tag->params[0] == '\0')
116 fprintf(out, "%s", tag->name);
117 return strlen(tag->name);
119 fprintf(out, "%s", tag->name);
120 len += strlen(tag->name);
121 start += len;
122 /* handle individual tags which accept params */
123 if ((MATCH("bl") || MATCH("pb") || MATCH("pv")) && !in_conditional)
125 if (*start == '|')
127 len++; start++;
128 PUTCH(out, '(');
129 /* TODO: need to verify that we are actually using the long form... */
130 len += dump_arg(out, start, 5, true);
133 else if (MATCH("d") || MATCH("D") || MATCH("mv") || MATCH("pS") || MATCH("pE") || MATCH("t") || MATCH("Tl"))
135 char temp[8] = {'\0'};
136 int i = 0;
137 /* tags which maybe have a number after them */
138 while ((*start >= '0' && *start <= '9') || *start == '.')
140 temp[i++] = *start++;
142 if (i!= 0)
144 fprintf(out, "(%s)", temp);
145 len += i;
148 else if (MATCH("xl"))
150 char label = start[1];
151 PUTCH(out, '(');
152 int read = 1+dump_arg(out, start+1, 4, false);
153 len += read;
154 start += read;
155 if (*start>= '0' && *start <= '9')
157 images_with_subimages[image_count++] = label;
158 PUTCH(out, ',');
159 len += dump_arg(out, start, 1, false);
161 PUTCH(out, ')');
163 else if (MATCH("xd"))
165 char label = start[0];
166 int i=0;
167 while (i<image_count)
169 if (images_with_subimages[i] == label)
170 break;
171 i++;
173 PUTCH(out, '(');
174 PUTCH(out, *start++); len++;
175 if (i<image_count &&
176 ((*start >= 'a' && *start <= 'z') ||
177 (*start >= 'A' && *start <= 'Z')))
179 PUTCH(out, *start); len++;
181 PUTCH(out, ')');
183 else if (MATCH("x"))
185 PUTCH(out, '(');
186 len += 1+dump_arg(out, start+1, 4, true);
188 else if (MATCH("Fl"))
190 PUTCH(out, '(');
191 len += 1+dump_arg(out, start+1, 2, true);
193 else if (MATCH("C"))
195 fprintf(out, "%%Cd");
197 else if (MATCH("Cl"))
199 int read;
200 char xalign = '\0', yalign = '\0';
201 PUTCH(out, '(');
202 read = 1+dump_arg(out, start+1, 2, false);
203 len += read;
204 start += read;
205 switch (tolower(*start))
207 case 'l':
208 case 'c':
209 case 'r':
210 case '+':
211 case '-':
212 xalign = *start;
213 len++;
214 start++;
215 break;
216 case 'd':
217 case 'D':
218 case 'i':
219 case 'I':
220 case 's':
221 case 'S':
222 len++;
223 start++;
224 break;
226 PUTCH(out,',');
227 read = dump_arg(out, start, 1, false);
228 len += read;
229 start += read;
230 switch (tolower(*start))
232 case 't':
233 case 'c':
234 case 'b':
235 case '+':
236 case '-':
237 yalign = *start;
238 len++;
239 start++;
240 break;
241 case 'd':
242 case 'D':
243 case 'i':
244 case 'I':
245 case 's':
246 case 'S':
247 len++;
248 start++;
249 break;
251 PUTCH(out,',');
252 read = dump_arg(out, start, 1, false);
253 if (xalign)
255 if (xalign == '-')
256 xalign = 'l';
257 if (xalign == '+')
258 xalign = 'r';
259 fprintf(out, ",%c", xalign);
261 if (yalign)
263 if (yalign == '-')
264 yalign = 't';
265 if (yalign == '+')
266 yalign = 'b';
267 fprintf(out, ",%s%c", xalign?"":"-,", yalign);
269 PUTCH(out, ')');
270 len += read;
272 else if (MATCH("Vd") || MATCH("VI"))
274 PUTCH(out, '(');
275 PUTCH(out, *start); len++;
276 PUTCH(out, ')');
278 else if (MATCH("Vp"))
280 /* NOTE: almost certainly needs work */
281 PUTCH(out, '(');
282 len += 1+dump_arg(out, start+1, 3, true);
284 else if (MATCH("Vi"))
286 int read = 1;
288 PUTCH(out, '(');
289 if ((start[1] >= 'a' && start[1] <= 'z') ||
290 (start[1] >= 'A' && start[1] <= 'Z'))
292 read = 1+dump_arg(out, start+1, 1, false);
294 else
296 PUTCH(out, '-');
298 PUTCH(out, ',');
299 len += read + dump_viewport_tags(out, start+read);
301 else if (MATCH("Vl") || MATCH("Vi"))
303 int read;
304 PUTCH(out, '(');
305 read = 1+dump_arg(out, start+1, 1, false);
306 PUTCH(out, ',');
307 len += read + dump_viewport_tags(out, start+read);
309 else if (MATCH("V"))
311 PUTCH(out, '(');
312 len += 1+dump_viewport_tags(out, start+1);
314 else if (MATCH("X"))
316 if (*start == 'd')
318 fprintf(out, "(d)");
319 len ++;
321 else
323 PUTCH(out, '(');
324 len += 1+dump_arg(out, start+1, 1, true);
327 else if (MATCH("St") || MATCH("Sx"))
329 PUTCH(out, '(');
330 len += 1+dump_arg(out, start+1, 1, true);
333 else if (MATCH("T"))
335 PUTCH(out, '(');
336 len += 1+dump_arg(out, start+1, 5, true);
338 return len;
341 void parse_text(const char* in, FILE* out)
343 const char* end = in+strlen(in);
344 int level = 0;
345 int len;
346 top:
347 while (in < end && *in)
349 if (*in == '%')
351 PUTCH(out, *in++);
352 switch(*in)
355 case '%':
356 case '<':
357 case '|':
358 case '>':
359 case ';':
360 case '#':
361 case ')':
362 case '(':
363 case ',':
364 PUTCH(out, *in++);
365 goto top;
366 break;
367 case '?':
368 PUTCH(out, *in++);
369 break;
371 len = parse_tag(out, in, level>0);
372 if (len < 0)
374 PUTCH(out, *in++);
376 else
378 in += len;
381 else if (*in == '<')
383 level++;
384 PUTCH(out, *in++);
386 else if (*in == '>')
388 level--;
389 PUTCH(out, *in++);
391 else if (*in == '|')
393 if (level == 0)
395 PUTCH(out, '%');
397 PUTCH(out, *in++);
399 else if (*in == '#')
401 while (*in && *in != '\n')
403 PUTCH(out, *in++);
406 else if (*in == ';')
408 PUTCH(out, *in++);
410 else
412 if (find_escape_character(*in))
414 PUTCH(out, '%');
416 PUTCH(out, *in++);
421 int main(int argc, char* argv[])
423 char buffer[10*1024], temp[512];
424 FILE *in, *out = stdout;
425 int filearg = 1, i=0;
426 if( (argc < 2) ||
427 strcmp(argv[1],"-h") == 0 ||
428 strcmp(argv[1],"--help") == 0 )
430 printf("Usage: %s [OPTIONS] infile [outfile]\n", argv[0]);
431 printf("\nOPTIONS:\n");
432 printf("\t-c\tDon't use new viewport colour tags (non-mono displays only)\n");
433 printf("\t-m\tSkin is for a mono display (different viewport tags)\n");
434 return 0;
437 while ((argc > filearg) && argv[filearg][0] == '-')
439 i=1;
440 while (argv[filearg][i])
442 switch(argv[filearg][i])
444 case 'c': /* disable new colour tags */
445 use_new_vp_tags = false;
446 break;
447 case 'm': /* skin is for a mono display */
448 is_mono_display = true;
449 break;
451 i++;
453 filearg++;
455 if (argc == filearg)
457 printf("Missing input filename\n");
458 return 1;
461 in = fopen(argv[filearg], "r");
462 if (!in)
463 return 1;
464 while (fgets(temp, 512, in))
465 strcat(buffer, temp);
466 fclose(in);
467 filearg++;
469 if (argc > filearg)
471 out = fopen(argv[filearg], "w");
472 if (!out)
474 printf("Couldn't open %s\n", argv[filearg]);
475 return 1;
479 parse_text(buffer, out);
480 if (out != stdout)
481 fclose(out);
482 return 0;