4 * Copyright 2008 Christian Costa
6 * This file contains the (internal) driver registration functions,
7 * driver enumeration APIs and DirectDraw creation functions.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/debug.h"
32 #include "d3dxof_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof_parsing
);
40 #define TOKEN_STRING 2
41 #define TOKEN_INTEGER 3
43 #define TOKEN_INTEGER_LIST 6
44 #define TOKEN_FLOAT_LIST 7
45 #define TOKEN_OBRACE 10
46 #define TOKEN_CBRACE 11
47 #define TOKEN_OPAREN 12
48 #define TOKEN_CPAREN 13
49 #define TOKEN_OBRACKET 14
50 #define TOKEN_CBRACKET 15
51 #define TOKEN_OANGLE 16
52 #define TOKEN_CANGLE 17
54 #define TOKEN_COMMA 19
55 #define TOKEN_SEMICOLON 20
56 #define TOKEN_TEMPLATE 31
58 #define TOKEN_DWORD 41
59 #define TOKEN_FLOAT 42
60 #define TOKEN_DOUBLE 43
62 #define TOKEN_UCHAR 45
63 #define TOKEN_SWORD 46
64 #define TOKEN_SDWORD 47
66 #define TOKEN_LPSTR 49
67 #define TOKEN_UNICODE 50
68 #define TOKEN_CSTRING 51
69 #define TOKEN_ARRAY 52
71 #define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
73 static const char* get_primitive_string(WORD token
)
107 void dump_template(xtemplate
* templates_array
, xtemplate
* ptemplate
)
112 clsid
= &ptemplate
->class_id
;
114 DPRINTF("template %s\n", ptemplate
->name
);
116 DPRINTF(CLSIDFMT
"\n", clsid
->Data1
, clsid
->Data2
, clsid
->Data3
, clsid
->Data4
[0],
117 clsid
->Data4
[1], clsid
->Data4
[2], clsid
->Data4
[3], clsid
->Data4
[4], clsid
->Data4
[5], clsid
->Data4
[6], clsid
->Data4
[7]);
118 for (j
= 0; j
< ptemplate
->nb_members
; j
++)
120 if (ptemplate
->members
[j
].nb_dims
)
122 if (ptemplate
->members
[j
].type
== TOKEN_NAME
)
123 DPRINTF("%s ", templates_array
[ptemplate
->members
[j
].idx_template
].name
);
125 DPRINTF("%s ", get_primitive_string(ptemplate
->members
[j
].type
));
126 DPRINTF("%s", ptemplate
->members
[j
].name
);
127 for (k
= 0; k
< ptemplate
->members
[j
].nb_dims
; k
++)
129 if (ptemplate
->members
[j
].dim_fixed
[k
])
130 DPRINTF("[%d]", ptemplate
->members
[j
].dim_value
[k
]);
132 DPRINTF("[%s]", ptemplate
->members
[ptemplate
->members
[j
].dim_value
[k
]].name
);
138 else if (ptemplate
->nb_childs
)
140 DPRINTF("[%s", ptemplate
->childs
[0]);
141 for (j
= 1; j
< ptemplate
->nb_childs
; j
++)
142 DPRINTF(",%s", ptemplate
->childs
[j
]);
148 BOOL
read_bytes(parse_buffer
* buf
, LPVOID data
, DWORD size
)
150 if (buf
->rem_bytes
< size
)
152 memcpy(data
, buf
->buffer
, size
);
154 buf
->rem_bytes
-= size
;
158 static void rewind_bytes(parse_buffer
* buf
, DWORD size
)
161 buf
->rem_bytes
+= size
;
164 static void dump_TOKEN(WORD token
)
166 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
169 DUMP_TOKEN(TOKEN_NAME
);
170 DUMP_TOKEN(TOKEN_STRING
);
171 DUMP_TOKEN(TOKEN_INTEGER
);
172 DUMP_TOKEN(TOKEN_GUID
);
173 DUMP_TOKEN(TOKEN_INTEGER_LIST
);
174 DUMP_TOKEN(TOKEN_FLOAT_LIST
);
175 DUMP_TOKEN(TOKEN_OBRACE
);
176 DUMP_TOKEN(TOKEN_CBRACE
);
177 DUMP_TOKEN(TOKEN_OPAREN
);
178 DUMP_TOKEN(TOKEN_CPAREN
);
179 DUMP_TOKEN(TOKEN_OBRACKET
);
180 DUMP_TOKEN(TOKEN_CBRACKET
);
181 DUMP_TOKEN(TOKEN_OANGLE
);
182 DUMP_TOKEN(TOKEN_CANGLE
);
183 DUMP_TOKEN(TOKEN_DOT
);
184 DUMP_TOKEN(TOKEN_COMMA
);
185 DUMP_TOKEN(TOKEN_SEMICOLON
);
186 DUMP_TOKEN(TOKEN_TEMPLATE
);
187 DUMP_TOKEN(TOKEN_WORD
);
188 DUMP_TOKEN(TOKEN_DWORD
);
189 DUMP_TOKEN(TOKEN_FLOAT
);
190 DUMP_TOKEN(TOKEN_DOUBLE
);
191 DUMP_TOKEN(TOKEN_CHAR
);
192 DUMP_TOKEN(TOKEN_UCHAR
);
193 DUMP_TOKEN(TOKEN_SWORD
);
194 DUMP_TOKEN(TOKEN_SDWORD
);
195 DUMP_TOKEN(TOKEN_VOID
);
196 DUMP_TOKEN(TOKEN_LPSTR
);
197 DUMP_TOKEN(TOKEN_UNICODE
);
198 DUMP_TOKEN(TOKEN_CSTRING
);
199 DUMP_TOKEN(TOKEN_ARRAY
);
202 TRACE("Unknown token %d\n", token
);
208 static BOOL
is_space(char c
)
222 static BOOL
is_operator(char c
)
241 static inline BOOL
is_separator(char c
)
243 return is_space(c
) || is_operator(c
);
246 static WORD
get_operator_token(char c
)
255 return TOKEN_OBRACKET
;
257 return TOKEN_CBRACKET
;
269 return TOKEN_SEMICOLON
;
274 static BOOL
is_keyword(parse_buffer
* buf
, const char* keyword
)
276 char tmp
[8]; /* longest keyword size (template) */
277 DWORD len
= strlen(keyword
);
279 if (!read_bytes(buf
, tmp
, len
))
281 if (strncasecmp(tmp
, keyword
, len
))
283 rewind_bytes(buf
, len
);
287 if (!read_bytes(buf
, tmp
, 1))
289 if (is_separator(tmp
[0]))
291 rewind_bytes(buf
, 1);
294 rewind_bytes(buf
, len
+1);
298 static WORD
get_keyword_token(parse_buffer
* buf
)
300 if (is_keyword(buf
, "template"))
301 return TOKEN_TEMPLATE
;
302 if (is_keyword(buf
, "WORD"))
304 if (is_keyword(buf
, "DWORD"))
306 if (is_keyword(buf
, "FLOAT"))
308 if (is_keyword(buf
, "DOUBLE"))
310 if (is_keyword(buf
, "CHAR"))
312 if (is_keyword(buf
, "UCHAR"))
314 if (is_keyword(buf
, "SWORD"))
316 if (is_keyword(buf
, "SDWORD"))
318 if (is_keyword(buf
, "VOID"))
320 if (is_keyword(buf
, "STRING"))
322 if (is_keyword(buf
, "UNICODE"))
323 return TOKEN_UNICODE
;
324 if (is_keyword(buf
, "CSTRING"))
325 return TOKEN_CSTRING
;
326 if (is_keyword(buf
, "array"))
332 static BOOL
is_guid(parse_buffer
* buf
)
340 if (*buf
->buffer
!= '<')
343 while (*(buf
->buffer
+pos
) != '>')
345 tmp
[pos
] = *(buf
->buffer
+pos
);
350 if (pos
!= 38 /* <+36+> */)
352 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
356 buf
->rem_bytes
-= pos
;
358 ret
= sscanf(tmp
, CLSIDFMT
, &class_id
.Data1
, tab
, tab
+1, tab
+2, tab
+3, tab
+4, tab
+5, tab
+6, tab
+7, tab
+8, tab
+9);
361 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
364 TRACE("Found guid %s (%d)\n", tmp
, pos
);
366 class_id
.Data2
= tab
[0];
367 class_id
.Data3
= tab
[1];
368 class_id
.Data4
[0] = tab
[2];
369 class_id
.Data4
[1] = tab
[3];
370 class_id
.Data4
[2] = tab
[4];
371 class_id
.Data4
[3] = tab
[5];
372 class_id
.Data4
[4] = tab
[6];
373 class_id
.Data4
[5] = tab
[7];
374 class_id
.Data4
[6] = tab
[8];
375 class_id
.Data4
[7] = tab
[9];
377 *(GUID
*)buf
->value
= class_id
;
382 static BOOL
is_name(parse_buffer
* buf
)
388 while (!is_separator(c
= *(buf
->buffer
+pos
)))
390 if (!(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')) || ((c
>= '0') && (c
<= '9')) || (c
== '_') || (c
== '-')))
398 TRACE("Wrong name %s\n", tmp
);
403 buf
->rem_bytes
-= pos
;
405 TRACE("Found name %s\n", tmp
);
406 strcpy((char*)buf
->value
, tmp
);
411 static BOOL
is_float(parse_buffer
* buf
)
419 while (!is_separator(c
= *(buf
->buffer
+pos
)))
421 if (!((!pos
&& (c
== '-')) || ((c
>= '0') && (c
<= '9')) || (!dot
&& (c
== '.'))))
430 buf
->rem_bytes
-= pos
;
432 sscanf(tmp
, "%f", &decimal
);
434 TRACE("Found float %s - %f\n", tmp
, decimal
);
436 *(float*)buf
->value
= decimal
;
441 static BOOL
is_integer(parse_buffer
* buf
)
448 while (!is_separator(c
= *(buf
->buffer
+pos
)))
450 if (!((c
>= '0') && (c
<= '9')))
457 buf
->rem_bytes
-= pos
;
459 sscanf(tmp
, "%d", &integer
);
461 TRACE("Found integer %s - %d\n", tmp
, integer
);
463 *(DWORD
*)buf
->value
= integer
;
468 static BOOL
is_string(parse_buffer
* buf
)
475 if (*buf
->buffer
!= '"')
478 while (!is_separator(c
= *(buf
->buffer
+pos
+1)) && (pos
< 99))
491 TRACE("Wrong string %s\n", tmp
);
495 buf
->buffer
+= pos
+ 2;
496 buf
->rem_bytes
-= pos
+ 2;
498 TRACE("Found string %s\n", tmp
);
499 strcpy((char*)buf
->value
, tmp
);
504 static WORD
parse_TOKEN(parse_buffer
* buf
)
513 if (!read_bytes(buf
, &c
, 1))
515 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
516 if ((c
== '#') || (c
== '/'))
518 /* Handle comment (# or //) */
521 if (!read_bytes(buf
, &c
, 1))
529 if (!read_bytes(buf
, &c
, 1))
536 if (is_operator(c
) && (c
!= '<'))
538 token
= get_operator_token(c
);
548 rewind_bytes(buf
, 1);
550 if ((token
= get_keyword_token(buf
)))
560 token
= TOKEN_INTEGER
;
579 FIXME("Unrecognize element\n");
591 if (!read_bytes(buf
, &token
, 2))
594 /* Convert integer and float list into separate elements */
595 if (token
== TOKEN_INTEGER_LIST
)
597 if (!read_bytes(buf
, &nb_elem
, 4))
599 token
= TOKEN_INTEGER
;
601 TRACE("Integer list (TOKEN_INTEGER_LIST) of size %d\n", nb_elem
);
603 else if (token
== TOKEN_FLOAT_LIST
)
605 if (!read_bytes(buf
, &nb_elem
, 4))
609 TRACE("Float list (TOKEN_FLOAT_LIST) of size %d\n", nb_elem
);
615 token
= is_float
? TOKEN_FLOAT
: TOKEN_INTEGER
;
620 if (!read_bytes(buf
, &integer
, 4))
623 *(DWORD
*)buf
->value
= integer
;
636 if (!read_bytes(buf
, &count
, 4))
638 if (!read_bytes(buf
, strname
, count
))
641 /*TRACE("name = %s\n", strname);*/
643 strcpy((char*)buf
->value
, strname
);
650 if (!read_bytes(buf
, &integer
, 4))
652 /*TRACE("integer = %ld\n", integer);*/
654 *(DWORD
*)buf
->value
= integer
;
662 if (!read_bytes(buf
, &class_id
, 16))
664 sprintf(strguid
, CLSIDFMT
, class_id
.Data1
, class_id
.Data2
, class_id
.Data3
, class_id
.Data4
[0],
665 class_id
.Data4
[1], class_id
.Data4
[2], class_id
.Data4
[3], class_id
.Data4
[4], class_id
.Data4
[5],
666 class_id
.Data4
[6], class_id
.Data4
[7]);
667 /*TRACE("guid = {%s}\n", strguid);*/
669 *(GUID
*)buf
->value
= class_id
;
677 if (!read_bytes(buf
, &count
, 4))
679 if (!read_bytes(buf
, strname
, count
))
682 if (!read_bytes(buf
, &tmp_token
, 2))
684 if ((tmp_token
!= TOKEN_COMMA
) && (tmp_token
!= TOKEN_SEMICOLON
))
685 ERR("No comma or semicolon (got %d)\n", tmp_token
);
686 /*TRACE("name = %s\n", strname);*/
688 strcpy((char*)buf
->value
, strname
);
702 case TOKEN_SEMICOLON
:
728 static WORD
get_TOKEN(parse_buffer
* buf
)
730 if (buf
->token_present
)
732 buf
->token_present
= FALSE
;
733 return buf
->current_token
;
736 buf
->current_token
= parse_TOKEN(buf
);
738 return buf
->current_token
;
741 static WORD
check_TOKEN(parse_buffer
* buf
)
743 if (buf
->token_present
)
744 return buf
->current_token
;
746 buf
->current_token
= parse_TOKEN(buf
);
747 buf
->token_present
= TRUE
;
749 return buf
->current_token
;
752 BOOL
is_template_available(parse_buffer
* buf
)
754 return check_TOKEN(buf
) == TOKEN_TEMPLATE
;
757 static inline BOOL
is_primitive_type(WORD token
)
782 static BOOL
parse_template_option_info(parse_buffer
* buf
)
784 xtemplate
* cur_template
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
];
786 if (check_TOKEN(buf
) == TOKEN_DOT
)
789 if (get_TOKEN(buf
) != TOKEN_DOT
)
791 if (get_TOKEN(buf
) != TOKEN_DOT
)
793 cur_template
->open
= TRUE
;
799 if (get_TOKEN(buf
) != TOKEN_NAME
)
801 strcpy(cur_template
->childs
[cur_template
->nb_childs
], (char*)buf
->value
);
802 if (check_TOKEN(buf
) == TOKEN_GUID
)
804 cur_template
->nb_childs
++;
805 if (check_TOKEN(buf
) != TOKEN_COMMA
)
809 cur_template
->open
= FALSE
;
815 static BOOL
parse_template_members_list(parse_buffer
* buf
)
824 cur_member
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[idx_member
];
826 if (check_TOKEN(buf
) == TOKEN_ARRAY
)
832 if (check_TOKEN(buf
) == TOKEN_NAME
)
834 cur_member
->type
= get_TOKEN(buf
);
835 cur_member
->idx_template
= 0;
836 while (cur_member
->idx_template
< buf
->pdxf
->nb_xtemplates
)
838 if (!strcasecmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[cur_member
->idx_template
].name
))
840 cur_member
->idx_template
++;
842 if (cur_member
->idx_template
== buf
->pdxf
->nb_xtemplates
)
844 ERR("Reference to a nonexistent template '%s'\n", (char*)buf
->value
);
848 else if (is_primitive_type(check_TOKEN(buf
)))
849 cur_member
->type
= get_TOKEN(buf
);
853 if (get_TOKEN(buf
) != TOKEN_NAME
)
855 strcpy(cur_member
->name
, (char*)buf
->value
);
859 while (check_TOKEN(buf
) == TOKEN_OBRACKET
)
861 if (nb_dims
>= MAX_ARRAY_DIM
)
863 FIXME("Too many dimensions (%d) for multi-dimensional array\n", nb_dims
+ 1);
867 if (check_TOKEN(buf
) == TOKEN_INTEGER
)
870 cur_member
->dim_fixed
[nb_dims
] = TRUE
;
871 cur_member
->dim_value
[nb_dims
] = *(DWORD
*)buf
->value
;
876 if (get_TOKEN(buf
) != TOKEN_NAME
)
878 for (i
= 0; i
< idx_member
; i
++)
880 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].name
))
882 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].nb_dims
)
884 ERR("Array cannot be used to specify variable array size\n");
887 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].type
!= TOKEN_DWORD
)
889 FIXME("Only DWORD supported to specify variable array size\n");
897 ERR("Reference to unknown member %s\n", (char*)buf
->value
);
900 cur_member
->dim_fixed
[nb_dims
] = FALSE
;
901 cur_member
->dim_value
[nb_dims
] = i
;
903 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
909 cur_member
->nb_dims
= nb_dims
;
911 if (get_TOKEN(buf
) != TOKEN_SEMICOLON
)
917 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].nb_members
= idx_member
;
922 static BOOL
parse_template_parts(parse_buffer
* buf
)
924 if (!parse_template_members_list(buf
))
926 if (check_TOKEN(buf
) == TOKEN_OBRACKET
)
929 if (!parse_template_option_info(buf
))
931 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
938 static void go_to_next_definition(parse_buffer
* buf
)
941 while (buf
->rem_bytes
)
943 read_bytes(buf
, &c
, 1);
944 if ((c
== '#') || (c
== '/'))
946 /* Handle comment (# or //) */
949 if (!read_bytes(buf
, &c
, 1))
957 if (!read_bytes(buf
, &c
, 1))
962 else if (!is_space(c
))
964 rewind_bytes(buf
, 1);
970 BOOL
parse_template(parse_buffer
* buf
)
972 if (get_TOKEN(buf
) != TOKEN_TEMPLATE
)
974 if (get_TOKEN(buf
) != TOKEN_NAME
)
976 strcpy(buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, (char*)buf
->value
);
977 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
979 if (get_TOKEN(buf
) != TOKEN_GUID
)
981 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
= *(GUID
*)buf
->value
;
982 if (!parse_template_parts(buf
))
984 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
988 /* Go to the next template */
989 go_to_next_definition(buf
);
992 TRACE("%d - %s - %s\n", buf
->pdxf
->nb_xtemplates
, buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, debugstr_guid(&buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
));
993 buf
->pdxf
->nb_xtemplates
++;
998 static BOOL
check_buffer(parse_buffer
* buf
, ULONG size
)
1000 if ((buf
->cur_pos_data
+ size
) > buf
->capacity
)
1003 ULONG new_capacity
= buf
->capacity
? 2 * buf
->capacity
: 100000;
1005 pdata
= HeapAlloc(GetProcessHeap(), 0, new_capacity
);
1008 memcpy(pdata
, buf
->pdata
, buf
->cur_pos_data
);
1009 HeapFree(GetProcessHeap(), 0, buf
->pdata
);
1010 buf
->capacity
= new_capacity
;
1012 buf
->pxo
->root
->pdata
= pdata
;
1017 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
);
1018 static BOOL
parse_object_members_list(parse_buffer
* buf
)
1022 xtemplate
* pt
= buf
->pxt
[buf
->level
];
1024 for (i
= 0; i
< pt
->nb_members
; i
++)
1029 buf
->pxo
->members
[i
].name
= pt
->members
[i
].name
;
1030 buf
->pxo
->members
[i
].start
= buf
->cur_pos_data
;
1032 for (k
= 0; k
< pt
->members
[i
].nb_dims
; k
++)
1034 if (pt
->members
[i
].dim_fixed
[k
])
1035 nb_elems
*= pt
->members
[i
].dim_value
[k
];
1037 nb_elems
*= *(DWORD
*)(buf
->pxo
->root
->pdata
+ buf
->pxo
->members
[pt
->members
[i
].dim_value
[k
]].start
);
1040 TRACE("Elements to consider: %d\n", nb_elems
);
1042 for (k
= 0; k
< nb_elems
; k
++)
1046 token
= check_TOKEN(buf
);
1047 if (token
== TOKEN_COMMA
)
1053 /* Allow comma omission */
1054 if (!((token
== TOKEN_FLOAT
) || (token
== TOKEN_INTEGER
)))
1059 if (pt
->members
[i
].type
== TOKEN_NAME
)
1063 TRACE("Found sub-object %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1065 /* To do template lookup */
1066 for (j
= 0; j
< buf
->pdxf
->nb_xtemplates
; j
++)
1068 if (!strcasecmp(buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
, buf
->pdxf
->xtemplates
[j
].name
))
1070 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[j
];
1074 if (j
== buf
->pdxf
->nb_xtemplates
)
1076 ERR("Unknown template %s\n", (char*)buf
->value
);
1080 TRACE("Enter %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1081 if (!parse_object_parts(buf
, FALSE
))
1090 token
= check_TOKEN(buf
);
1091 if (token
== TOKEN_INTEGER
)
1094 TRACE("%s = %d\n", pt
->members
[i
].name
, *(DWORD
*)buf
->value
);
1095 /* Assume larger size */
1096 if (!check_buffer(buf
, 4))
1098 if (pt
->members
[i
].type
== TOKEN_WORD
)
1100 *(((WORD
*)(buf
->cur_pos_data
+ buf
->pdata
))) = (WORD
)(*(DWORD
*)buf
->value
);
1101 buf
->cur_pos_data
+= 2;
1103 else if (pt
->members
[i
].type
== TOKEN_DWORD
)
1105 *(((DWORD
*)(buf
->cur_pos_data
+ buf
->pdata
))) = (DWORD
)(*(DWORD
*)buf
->value
);
1106 buf
->cur_pos_data
+= 4;
1110 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1114 else if (token
== TOKEN_FLOAT
)
1117 TRACE("%s = %f\n", pt
->members
[i
].name
, *(float*)buf
->value
);
1118 if (!check_buffer(buf
, 4))
1120 if (pt
->members
[i
].type
== TOKEN_FLOAT
)
1122 *(((float*)(buf
->cur_pos_data
+ buf
->pdata
))) = (float)(*(float*)buf
->value
);
1123 buf
->cur_pos_data
+= 4;
1127 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1131 else if (token
== TOKEN_LPSTR
)
1134 TRACE("%s = %s\n", pt
->members
[i
].name
, (char*)buf
->value
);
1135 if (!check_buffer(buf
, 4))
1137 if (pt
->members
[i
].type
== TOKEN_LPSTR
)
1139 int len
= strlen((char*)buf
->value
) + 1;
1140 if ((buf
->cur_pstrings
- buf
->pstrings
+ len
) > MAX_STRINGS_BUFFER
)
1142 FIXME("Buffer too small %p %p %d\n", buf
->cur_pstrings
, buf
->pstrings
, len
);
1145 strcpy((char*)buf
->cur_pstrings
, (char*)buf
->value
);
1146 *(((LPCSTR
*)(buf
->cur_pos_data
+ buf
->pdata
))) = (char*)buf
->cur_pstrings
;
1147 buf
->cur_pstrings
+= len
;
1148 buf
->cur_pos_data
+= 4;
1152 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1158 FIXME("Unexpected token %d\n", token
);
1164 if (nb_elems
&& buf
->txt
&& (check_TOKEN(buf
) != TOKEN_CBRACE
))
1166 token
= get_TOKEN(buf
);
1167 if ((token
!= TOKEN_SEMICOLON
) && (token
!= TOKEN_COMMA
))
1175 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
)
1177 buf
->pxo
->nb_childs
= 0;
1179 if (!parse_object_members_list(buf
))
1184 buf
->pxo
->size
= buf
->cur_pos_data
- buf
->pxo
->pos_data
;
1186 /* Skip trailing semicolon */
1187 while (check_TOKEN(buf
) == TOKEN_SEMICOLON
)
1192 if (check_TOKEN(buf
) == TOKEN_OBRACE
)
1196 if (get_TOKEN(buf
) != TOKEN_NAME
)
1198 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1200 TRACE("Found optional reference %s\n", (char*)buf
->value
);
1201 for (i
= 0; i
< (buf
->nb_pxo_globals
+1); i
++)
1203 for (j
= 0; j
< (buf
->pxo_globals
[i
])[0].nb_subobjects
; j
++)
1205 if (!strcmp((buf
->pxo_globals
[i
])[j
].name
, (char*)buf
->value
))
1210 if (i
== (buf
->nb_pxo_globals
+1))
1212 ERR("Reference to unknown object %s\n", (char*)buf
->value
);
1215 buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->pxo
->root
->nb_subobjects
++];
1216 buf
->pxo
->childs
[buf
->pxo
->nb_childs
]->ptarget
= &(buf
->pxo_globals
[i
])[j
];
1217 buf
->pxo
->nb_childs
++;
1219 else if (check_TOKEN(buf
) == TOKEN_NAME
)
1221 xobject
* pxo
= buf
->pxo
;
1222 buf
->pxo
= buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->pxo
->root
->nb_subobjects
++];
1224 TRACE("Enter optional %s\n", (char*)buf
->value
);
1226 if (!parse_object(buf
))
1233 buf
->pxo
->nb_childs
++;
1240 if (buf
->pxo
->nb_childs
> MAX_CHILDS
)
1242 FIXME("Too many childs %d\n", buf
->pxo
->nb_childs
);
1249 BOOL
parse_object(parse_buffer
* buf
)
1253 buf
->pxo
->pos_data
= buf
->cur_pos_data
;
1254 buf
->pxo
->ptarget
= NULL
;
1255 buf
->pxo
->root
= buf
->pxo_tab
;
1257 if (get_TOKEN(buf
) != TOKEN_NAME
)
1260 /* To do template lookup */
1261 for (i
= 0; i
< buf
->pdxf
->nb_xtemplates
; i
++)
1263 if (!strcasecmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[i
].name
))
1265 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[i
];
1266 memcpy(&buf
->pxo
->type
, &buf
->pdxf
->xtemplates
[i
].class_id
, 16);
1270 if (i
== buf
->pdxf
->nb_xtemplates
)
1272 ERR("Unknown template %s\n", (char*)buf
->value
);
1276 if (check_TOKEN(buf
) == TOKEN_NAME
)
1279 strcpy(buf
->pxo
->name
, (char*)buf
->value
);
1282 buf
->pxo
->name
[0] = 0;
1284 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
1286 if (check_TOKEN(buf
) == TOKEN_GUID
)
1289 memcpy(&buf
->pxo
->class_id
, buf
->value
, 16);
1292 memset(&buf
->pxo
->class_id
, 0, 16);
1294 if (!parse_object_parts(buf
, TRUE
))
1296 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1301 /* Go to the next object */
1302 go_to_next_definition(buf
);