fix error when a comment is on the last line of the file
[kugel-rb.git] / utils / skinupdater / skinupdater.c
blob9329b9a9f0c79064b584485983cc0ce2779620d9
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 "tag_table.h"
28 #define PUTCH(out, c) fprintf(out, "%c", c)
29 extern struct tag_info legal_tags[];
32 /** Command line setting **/
33 bool is_mono_display = false;
38 /* dump "count" args to output replacing '|' with ',' except after the last count.
39 * return the amount of chars read. (start+return will be after the last | )
41 int dump_arg(FILE* out, const char* start, int count, bool close)
43 int l = 0;
44 while (count)
46 if (start[l] == '|')
48 if (count > 1)
50 PUTCH(out, ',');
51 } else if (close) {
52 PUTCH(out, ')');
54 count--;
55 } else {
56 PUTCH(out, start[l]);
58 l++;
60 return l;
63 #define MATCH(s) (!strcmp(tag->name, s))
64 int parse_tag(FILE* out, const char* start, bool in_conditional)
66 struct tag_info *tag;
67 int len = 0;
68 for(tag = legal_tags;
69 tag->name[0] && strncmp(start, tag->name, strlen(tag->name)) != 0;
70 tag++) ;
71 if (!tag->name[0])
72 return -1;
73 if (tag->params[0] == '\0')
75 fprintf(out, "%s", tag->name);
76 return strlen(tag->name);
78 fprintf(out, "%s", tag->name);
79 len += strlen(tag->name);
80 start += len;
81 /* handle individual tags which accept params */
82 if ((MATCH("bl") || MATCH("pb") || MATCH("pv")) && !in_conditional)
84 if (*start == '|')
86 len++; start++;
87 PUTCH(out, '(');
88 /* TODO: need to verify that we are actually using the long form... */
89 len += dump_arg(out, start, 5, true);
92 else if (MATCH("d") || MATCH("D") || MATCH("mv") || MATCH("pS") || MATCH("pE") || MATCH("t") || MATCH("Tl"))
94 char temp[8] = {'\0'};
95 int i = 0;
96 /* tags which maybe have a number after them */
97 while ((*start >= '0' && *start <= '9') || *start == '.')
99 temp[i++] = *start++;
101 if (i!= 0)
103 fprintf(out, "(%s)", temp);
104 len += i;
107 else if (MATCH("xl"))
109 PUTCH(out, '(');
110 int read = 1+dump_arg(out, start+1, 4, false);
111 len += read;
112 start += read;
113 if (*start>= '0' && *start <= '9')
115 PUTCH(out, ',');
116 len += dump_arg(out, start, 1, false);
118 PUTCH(out, ')');
120 else if (MATCH("xd"))
122 /* NOTE: almost certainly needs work */
123 PUTCH(out, '(');
124 PUTCH(out, *start++); len++;
125 if ((*start >= 'a' && *start <= 'z') ||
126 (*start >= 'A' && *start <= 'Z'))
128 PUTCH(out, *start); len++;
130 PUTCH(out, ')');
132 else if (MATCH("x"))
134 PUTCH(out, '(');
135 len += 1+dump_arg(out, start+1, 4, true);
137 else if (MATCH("Fl"))
139 PUTCH(out, '(');
140 len += 1+dump_arg(out, start+1, 2, true);
142 else if (MATCH("Cl"))
144 PUTCH(out, '(');
145 len += 1+dump_arg(out, start+1, 4, true);
147 else if (MATCH("Vd") || MATCH("VI"))
149 PUTCH(out, '(');
150 PUTCH(out, *start); len++;
151 PUTCH(out, ')');
153 else if (MATCH("Vp"))
155 /* NOTE: almost certainly needs work */
156 PUTCH(out, '(');
157 len += 1+dump_arg(out, start+1, 3, true);
159 else if (MATCH("Vl") || MATCH("Vi"))
161 PUTCH(out, '(');
162 len += 1+dump_arg(out, start+1, is_mono_display?6:8, true);
164 else if (MATCH("V"))
166 PUTCH(out, '(');
167 len += 1+dump_arg(out, start+1, is_mono_display?5:7, true);
169 else if (MATCH("X"))
171 if (*start+1 == 'd')
173 fprintf(out, "(d)");
174 len ++;
176 else
178 PUTCH(out, '(');
179 len += 1+dump_arg(out, start+1, 1, true);
182 else if (MATCH("St") || MATCH("Sx"))
184 PUTCH(out, '(');
185 len += 1+dump_arg(out, start+1, 1, true);
188 else if (MATCH("T"))
190 PUTCH(out, '(');
191 len += 1+dump_arg(out, start+1, 5, true);
193 return len;
196 void parse_text(const char* in, FILE* out)
198 const char* end = in+strlen(in);
199 int level = 0;
200 int len;
201 top:
202 while (in < end && *in)
204 if (*in == '%')
206 PUTCH(out, *in++);
207 switch(*in)
210 case '%':
211 case '<':
212 case '|':
213 case '>':
214 case ';':
215 case '#':
216 PUTCH(out, *in++);
217 goto top;
218 break;
219 case '?':
220 PUTCH(out, *in++);
221 break;
223 len = parse_tag(out, in, level>0);
224 if (len < 0)
226 PUTCH(out, *in++);
228 else
230 in += len;
233 else if (*in == '<')
235 level++;
236 PUTCH(out, *in++);
238 else if (*in == '>')
240 level--;
241 PUTCH(out, *in++);
243 else if (*in == '#')
245 while (*in && *in != '\n')
247 PUTCH(out, *in++);
250 else
252 PUTCH(out, *in++);
257 int main(int argc, char* argv[])
259 char buffer[10*1024], temp[512];
260 FILE *in, *out = stdout;
261 int filearg = 1, i=0;
262 if( (argc < 2) ||
263 strcmp(argv[1],"-h") == 0 ||
264 strcmp(argv[1],"--help") == 0 )
266 printf("Usage: %s [OPTIONS] infile [outfile]\n", argv[0]);
267 printf("\nOPTIONS:\n");
268 printf("\t-m\tSkin is for a mono display (different viewport tags)\n");
269 return 0;
272 while ((argc > filearg) && argv[filearg][0] == '-')
274 i=1;
275 while (argv[filearg][i])
277 switch(argv[filearg][i])
279 case 'm': /* skin is for a mono display */
280 is_mono_display = true;
281 break;
283 i++;
285 filearg++;
287 if (argc == filearg)
289 printf("Missing input filename\n");
290 return 1;
293 in = fopen(argv[filearg], "r");
294 if (!in)
295 return 1;
296 while (fgets(temp, 512, in))
297 strcat(buffer, temp);
298 fclose(in);
299 filearg++;
301 if (argc > filearg)
303 out = fopen(argv[filearg], "w");
304 if (!out)
306 printf("Couldn't open %s\n", argv[filearg]);
307 return 1;
311 parse_text(buffer, out);
312 if (out != stdout)
313 fclose(out);
314 return 0;