Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/info.txt

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download)
Thu Apr 25 18:27:03 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver_0_60_1, ver0_59_13, ver0_59_14, ver0_60_2, ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.2: +0 -0 lines
File MIME type: text/plain
*** empty log message ***

1 Description of the -listinfo output
2 -----------------------------------
3
4 Grammar
5 -------
6 start -> ENTRY*
7 ENTRY -> ENTRYNAME ENTRYVALUE
8 ENTRYNAME -> SYMBOL
9 ENTRYVALUE -> SYMBOL | STRING | ENTRYLIST
10 ENTRYLIST -> '(' ENTRY* ')'
11 SYMBOL -> any char except separator, '"', '(', ')'
12 STRING -> default C string in double quote ""
13
14 Any space (specifically any char that the C function ispace() tells is a
15 space) is considered a separator and must be ignored.
16
17
18 Semantic
19 --------
20 game (...)
21 Definition of a game emulated.
22
23 resource (...)
24 Definition of a resource. For example the NeoGeo BIOS rom 'neogeo'.
25
26
27 Entries common for 'game' and 'resource'
28 ----------------------------------------
29 name NAME
30 Name of the game or resource. This is the only required item.
31 The specified NAME is unique in all file.
32
33 description DESCRIPTION
34 Generic description.
35
36 manufacturer MANUFACTURER
37 Manufacturer of the game or resource.
38
39 year YEAR
40 Year of the game or resource.
41
42 romof NAME
43 The game or resource use rom of another game or resource named NAME.
44 [Equal to cloneof entry in GameDriver specification.]
45
46 sampleof NAME
47 The game or resource use sample of another game or resource named NAME.
48 [Is the first element with starting * in the samplenames array.]
49
50 rom '(' name NAME size SIZE crc CRC ')'
51 Rom specification his name, size and crc.
52
53 sample NAME
54 Sample specification.
55
56
57 Entries specific for 'game'
58 ---------------------------
59 cloneof NAME
60 Clone-of relathionship. This is intended to express an abstract
61 clone-of relathionship. It's equal to the cloneof entry in gamedriver
62 specification with the exception of the special NOT_DRIVER games
63 (neogeo, cvs, decocass, playch10).
64
65 chip '(' ... ')'
66 List of hardware chips used by the game. A MAME cpu used ONLY for sound
67 has the 'flags audio'.
68
69 video '(' ... ')'
70 Informations of the game video hardware.
71
72 input '(' ... ')'
73 Informations of the game input hardware.
74
75 driver '(' status (preliminary | good) color (preliminary | imperfect | good)
76 hiscore (preliminary | good) ... ')'
77 Informations of the MAME driver status and requirements.
78
79 sound '(' ... ')'
80 Number of the sound channels.
81
82
83 How to read the file
84 --------------------
85 If you need to read the output of -listinfo option you must take care
86 of these issues:
87
88 1) You can't do any assumption of space indentation.
89 2) You can't do any assumption of max line length. All output can be
90 in a very long line.
91 3) You can't do any assumption of order of the entries.
92 4) You can't do any assumption of the presence of any entry except the
93 game.name and resource.name which are mandatory and unique.
94 5) You must ignore any entry unknow.
95 6) Spaces are required only for separing SYMBOLs.
96 7) Lists of entry empty are valid.
97
98 For example:
99
100 game(description"Pac Man (Midway)"unknowentry()name pacman rom(size 4096 name pacman.6e crc c1e6ab10))
101
102 is a valid output.
103
104 Example
105 -------
106 This is a complete module for reading info files.
107
108 info.h Library header
109 info.c Library module
110 test.c Example of use
111
112 -- info.h --------------------------------------------------------------------
113 #ifndef __INFO_H
114 #define __INFO_H
115
116 #ifdef __cplusplus
117 extern "C" {
118 #endif
119
120 #include <stdio.h>
121
122 enum info_t {
123 info_error, /* generic error in reading */
124 info_eof, /* end of file got at valid position */
125 info_symbol, /* symbol */
126 info_open, /* ( */
127 info_close, /* ) */
128 info_string /* c string automatically converted */
129 };
130
131 const char* info_text_get(void);
132 enum info_t info_token_get(FILE* f);
133 enum info_t info_skip_value(FILE* f);
134
135 void info_init(void);
136 void info_done(void);
137 unsigned info_row_get(void);
138 unsigned info_col_get(void);
139 unsigned info_pos_get(void);
140
141 #ifdef __cplusplus
142 }
143 #endif
144
145 #endif
146 ------------------------------------------------------------------------------
147
148 -- info.c --------------------------------------------------------------------
149 #include "info.h"
150
151 #include <ctype.h>
152 #include <string.h>
153 #include <malloc.h>
154 #include <assert.h>
155
156 /* Start size of buffer */
157 #define INFO_BUF_MIN 64
158
159 /* Buffer used for storing last token */
160 static unsigned info_buf_mac = 0;
161 static unsigned info_buf_max = 0;
162 static char* info_buf_map = 0;
163
164 /* Position in the stream */
165 static unsigned info_pos = 0; /* Char */
166 static unsigned info_row = 0; /* Row */
167 static unsigned info_col = 0; /* Column */
168
169 /* Init */
170 void info_init(void) {
171 assert(!info_buf_map);
172
173 info_buf_max = 0;
174 info_buf_map = 0;
175 info_pos = 0;
176 info_row = 0;
177 info_col = 0;
178 }
179
180 /* Done */
181 void info_done(void) {
182 free(info_buf_map);
183 info_buf_map = 0;
184 }
185
186 /* Get information of file position */
187 unsigned info_row_get(void) {
188 return info_row;
189 }
190
191 unsigned info_col_get(void) {
192 return info_col;
193 }
194
195 unsigned info_pos_get(void) {
196 return info_pos;
197 }
198
199 /* Resize the buffer */
200 static void info_buf_resize(unsigned size) {
201 if (!info_buf_max)
202 info_buf_max = INFO_BUF_MIN;
203 else
204 info_buf_max *= 2;
205 if (size > info_buf_max)
206 info_buf_max = size;
207 info_buf_map = realloc(info_buf_map, info_buf_max );
208 assert( info_buf_map );
209 }
210
211 /* Add a char to the buffer end */
212 static inline void info_buf_add(char c) {
213 if (info_buf_mac >= info_buf_max)
214 info_buf_resize(info_buf_mac + 1);
215 info_buf_map[info_buf_mac++] = c;
216 }
217
218 /* Reset the buffer */
219 static void info_buf_reset() {
220 info_buf_mac = 0;
221 }
222
223 /* Return last token text */
224 const char* info_text_get(void) {
225 /* ensure the buffer end with zero */
226 if (info_buf_mac==0 || info_buf_map[info_buf_mac-1]!=0)
227 info_buf_add(0);
228 return info_buf_map;
229 }
230
231 /* Read a char from file */
232 static int info_getc(FILE* f) {
233 int c = fgetc(f);
234 switch (c) {
235 case EOF:
236 break;
237 case '\n':
238 info_col = 0;
239 ++info_row;
240 ++info_pos;
241 break;
242 default:
243 ++info_col;
244 ++info_pos;
245 break;
246 }
247 return c;
248 }
249
250 /* Unget a char from file */
251 static void info_ungetc(int c, FILE* f) {
252 --info_pos;
253 --info_col;
254 ungetc(c,f);
255 }
256
257 static enum info_t get_symbol(FILE* f,int c) {
258 while (c!=EOF && !isspace(c) && c!='(' && c!=')' && c!='\"') {
259 info_buf_add(c);
260 c = info_getc(f);
261 }
262 /* no reason to unget space or EOF */
263 if (c!=EOF && !isspace(c))
264 info_ungetc(c,f);
265 return info_symbol;
266 }
267
268 static unsigned hexdigit(char c) {
269 if (isdigit(c))
270 return c - '0';
271 return toupper(c) - 'A' + 10;
272 }
273
274 static enum info_t get_string(FILE* f) {
275 int c = info_getc(f);
276 while (c!=EOF && c!='\"') {
277 if (c=='\\') {
278 c = info_getc(f);
279 switch (c) {
280 case 'a' : info_buf_add('\a'); break;
281 case 'b' : info_buf_add('\b'); break;
282 case 'f' : info_buf_add('\f'); break;
283 case 'n' : info_buf_add('\n'); break;
284 case 'r' : info_buf_add('\r'); break;
285 case 't' : info_buf_add('\t'); break;
286 case 'v' : info_buf_add('\v'); break;
287 case '\\' : info_buf_add('\\'); break;
288 case '?' : info_buf_add('\?'); break;
289 case '\'' : info_buf_add('\''); break;
290 case '\"' : info_buf_add('\"'); break;
291 case 'x' : {
292 int d0,d1;
293 unsigned char cc;
294 d0 = info_getc(f);
295 if (!isxdigit(d0))
296 return info_error;
297 d1 = info_getc(f);
298 if (!isxdigit(d1))
299 return info_error;
300 cc = hexdigit(d0) * 16 + hexdigit(d1);
301 info_buf_add(cc);
302 }
303 break;
304 default:
305 return info_error;
306 }
307 } else {
308 info_buf_add(c);
309 }
310 c = info_getc(f);
311 }
312 if (c!='\"')
313 return info_error;
314 return info_string;
315 }
316
317 /* Extract a token */
318 enum info_t info_token_get(FILE* f) {
319 int c = info_getc(f);
320 /* reset the buffer */
321 info_buf_reset();
322 /* skip space */
323 while (c!=EOF && isspace(c)) {
324 c = info_getc(f);
325 }
326 /* get token */
327 switch (c) {
328 case EOF:
329 return info_eof;
330 case '(':
331 return info_open;
332 case ')':
333 return info_close;
334 case '\"':
335 return get_string(f);
336 default:
337 return get_symbol(f,c);
338 }
339 }
340
341 /* Skip a value token
342 * note:
343 * Skip recusively any info_open and info_close
344 * return:
345 * info_error error
346 * otherwise last token skipped
347 */
348 enum info_t info_skip_value(FILE* f) {
349 /* read value token */
350 enum info_t t = info_token_get(f);
351 switch (t) {
352 case info_open:
353 t = info_token_get(f);
354 if (t==info_error)
355 return info_error;
356 while (t!=info_close) {
357 /* first read type as a symbol */
358 if (t!=info_symbol)
359 return info_error;
360 /* second skip the value */
361 t = info_skip_value(f);
362 /* two value required */
363 if (t==info_error)
364 return info_error;
365 /* read next token, a type or a info_close */
366 t = info_token_get(f);
367 if (t==info_error)
368 return info_error;
369 }
370 break;
371 case info_symbol:
372 case info_string:
373 break;
374 default:
375 return info_error;
376 }
377 return t;
378 }
379 ------------------------------------------------------------------------------
380
381 -- test.c --------------------------------------------------------------------
382 #include "info.h"
383
384 #include <stdio.h>
385 #include <stdlib.h>
386
387 #define true 1
388 #define false 0
389
390 int info_load(FILE* f) {
391 enum info_t token = info_token_get(f);
392 while (token!=info_eof) {
393 if (token != info_symbol) return false;
394 if (strcmp(info_text_get(),"game")==0) {
395 if (info_token_get(f) != info_open) return false;
396 token = info_token_get(f);
397 while (token != info_close) {
398 if (token != info_symbol)
399 return false;
400 if (strcmp(info_text_get(),"name")==0) {
401 if (info_token_get(f) != info_symbol) return false;
402 printf("name %s\n", info_text_get() );
403 } else if (strcmp(info_text_get(),"description")==0) {
404 if (info_token_get(f) != info_string) return false;
405 printf("description %s\n", info_text_get() );
406 } else if (strcmp(info_text_get(),"manufacturer")==0) {
407 if (info_token_get(f) != info_string) return false;
408 printf("manufacturer %s\n", info_text_get() );
409 } else if (strcmp(info_text_get(),"year")==0) {
410 if (info_token_get(f) != info_symbol) return false;
411 printf("year %s\n", info_text_get() );
412 } else if (strcmp(info_text_get(),"cloneof")==0) {
413 if (info_token_get(f) != info_symbol) return false;
414 printf("cloneof %s\n", info_text_get() );
415 } else if (strcmp(info_text_get(),"romof")==0) {
416 if (info_token_get(f) != info_symbol) return false;
417 printf("romof %s\n", info_text_get() );
418 } else if (strcmp(info_text_get(),"sampleof")==0) {
419 if (info_token_get(f) != info_symbol) return false;
420 printf("sampleof %s\n", info_text_get() );
421 } else if (strcmp(info_text_get(),"rom")==0) {
422 if (info_token_get(f) != info_open) return false;
423 token = info_token_get(f);
424 while (token != info_close) {
425 if (token != info_symbol) return false;
426 if (strcmp(info_text_get(),"name")==0) {
427 if (info_token_get(f) != info_symbol) return false;
428 printf("romname %s\n", info_text_get() );
429 } else if (strcmp(info_text_get(),"size")==0) {
430 if (info_token_get(f) != info_symbol) return false;
431 printf("romsize %s\n", info_text_get() );
432 } else if (strcmp(info_text_get(),"crc")==0) {
433 if (info_token_get(f) != info_symbol) return false;
434 printf("romcrc %s\n", info_text_get() );
435 } else {
436 if (info_skip_value(f) == info_error) return false;
437 }
438 token = info_token_get(f);
439 }
440 } else if (strcmp(info_text_get(),"driver")==0) {
441 if (info_token_get(f) != info_open) return false;
442 token = info_token_get(f);
443 while (token != info_close) {
444 if (token != info_symbol) return false;
445 if (strcmp(info_text_get(),"status")==0) {
446 if (info_token_get(f) != info_symbol) return false;
447 printf("driverstatus %s\n", info_text_get() );
448 } else {
449 if (info_skip_value(f) == info_error) return false;
450 }
451 token = info_token_get(f);
452 }
453 } else if (strcmp(info_text_get(),"sample")==0) {
454 if (info_token_get(f) != info_symbol) return false;
455 printf("samplenames %s\n", info_text_get() );
456 } else {
457 if (info_skip_value(f) == info_error) return false;
458 }
459 token = info_token_get(f);
460 }
461 } else {
462 if (info_skip_value(f) == info_error) return false;
463 }
464 token = info_token_get(f);
465 }
466
467 return true;
468 }
469
470 int main() {
471 info_init();
472
473 if (!info_load(stdin)) {
474 info_done();
475 fprintf(stderr,"Error reading at row %d column %d\n",info_row_get()+1,info_col_get()+1);
476 exit(EXIT_FAILURE);
477 }
478
479 info_done();
480
481 return EXIT_SUCCESS;
482 }
483 ------------------------------------------------------------------------------
484

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26