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
);
39 static const char* get_primitive_string(WORD token
);
40 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
);
41 static WORD
check_TOKEN(parse_buffer
* buf
);
44 #define TOKEN_STRING 2
45 #define TOKEN_INTEGER 3
47 #define TOKEN_INTEGER_LIST 6
48 #define TOKEN_FLOAT_LIST 7
49 #define TOKEN_OBRACE 10
50 #define TOKEN_CBRACE 11
51 #define TOKEN_OPAREN 12
52 #define TOKEN_CPAREN 13
53 #define TOKEN_OBRACKET 14
54 #define TOKEN_CBRACKET 15
55 #define TOKEN_OANGLE 16
56 #define TOKEN_CANGLE 17
58 #define TOKEN_COMMA 19
59 #define TOKEN_SEMICOLON 20
60 #define TOKEN_TEMPLATE 31
62 #define TOKEN_DWORD 41
63 #define TOKEN_FLOAT 42
64 #define TOKEN_DOUBLE 43
66 #define TOKEN_UCHAR 45
67 #define TOKEN_SWORD 46
68 #define TOKEN_SDWORD 47
70 #define TOKEN_LPSTR 49
71 #define TOKEN_UNICODE 50
72 #define TOKEN_CSTRING 51
73 #define TOKEN_ARRAY 52
75 #define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
77 void dump_template(xtemplate
* templates_array
, xtemplate
* ptemplate
)
82 clsid
= &ptemplate
->class_id
;
84 DPRINTF("template %s\n", ptemplate
->name
);
86 DPRINTF(CLSIDFMT
"\n", clsid
->Data1
, clsid
->Data2
, clsid
->Data3
, clsid
->Data4
[0],
87 clsid
->Data4
[1], clsid
->Data4
[2], clsid
->Data4
[3], clsid
->Data4
[4], clsid
->Data4
[5], clsid
->Data4
[6], clsid
->Data4
[7]);
88 for (j
= 0; j
< ptemplate
->nb_members
; j
++)
90 if (ptemplate
->members
[j
].nb_dims
)
92 if (ptemplate
->members
[j
].type
== TOKEN_NAME
)
93 DPRINTF("%s ", templates_array
[ptemplate
->members
[j
].idx_template
].name
);
95 DPRINTF("%s ", get_primitive_string(ptemplate
->members
[j
].type
));
96 DPRINTF("%s", ptemplate
->members
[j
].name
);
97 for (k
= 0; k
< ptemplate
->members
[j
].nb_dims
; k
++)
99 if (ptemplate
->members
[j
].dim_fixed
[k
])
100 DPRINTF("[%d]", ptemplate
->members
[j
].dim_value
[k
]);
102 DPRINTF("[%s]", ptemplate
->members
[ptemplate
->members
[j
].dim_value
[k
]].name
);
108 else if (ptemplate
->nb_childs
)
110 DPRINTF("[%s", ptemplate
->childs
[0]);
111 for (j
= 1; j
< ptemplate
->nb_childs
; j
++)
112 DPRINTF(",%s", ptemplate
->childs
[j
]);
118 BOOL
is_template_available(parse_buffer
* buf
)
120 return check_TOKEN(buf
) == TOKEN_TEMPLATE
;
123 BOOL
read_bytes(parse_buffer
* buf
, LPVOID data
, DWORD size
)
125 if (buf
->rem_bytes
< size
)
127 memcpy(data
, buf
->buffer
, size
);
129 buf
->rem_bytes
-= size
;
133 static void dump_TOKEN(WORD token
)
135 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
138 DUMP_TOKEN(TOKEN_NAME
);
139 DUMP_TOKEN(TOKEN_STRING
);
140 DUMP_TOKEN(TOKEN_INTEGER
);
141 DUMP_TOKEN(TOKEN_GUID
);
142 DUMP_TOKEN(TOKEN_INTEGER_LIST
);
143 DUMP_TOKEN(TOKEN_FLOAT_LIST
);
144 DUMP_TOKEN(TOKEN_OBRACE
);
145 DUMP_TOKEN(TOKEN_CBRACE
);
146 DUMP_TOKEN(TOKEN_OPAREN
);
147 DUMP_TOKEN(TOKEN_CPAREN
);
148 DUMP_TOKEN(TOKEN_OBRACKET
);
149 DUMP_TOKEN(TOKEN_CBRACKET
);
150 DUMP_TOKEN(TOKEN_OANGLE
);
151 DUMP_TOKEN(TOKEN_CANGLE
);
152 DUMP_TOKEN(TOKEN_DOT
);
153 DUMP_TOKEN(TOKEN_COMMA
);
154 DUMP_TOKEN(TOKEN_SEMICOLON
);
155 DUMP_TOKEN(TOKEN_TEMPLATE
);
156 DUMP_TOKEN(TOKEN_WORD
);
157 DUMP_TOKEN(TOKEN_DWORD
);
158 DUMP_TOKEN(TOKEN_FLOAT
);
159 DUMP_TOKEN(TOKEN_DOUBLE
);
160 DUMP_TOKEN(TOKEN_CHAR
);
161 DUMP_TOKEN(TOKEN_UCHAR
);
162 DUMP_TOKEN(TOKEN_SWORD
);
163 DUMP_TOKEN(TOKEN_SDWORD
);
164 DUMP_TOKEN(TOKEN_VOID
);
165 DUMP_TOKEN(TOKEN_LPSTR
);
166 DUMP_TOKEN(TOKEN_UNICODE
);
167 DUMP_TOKEN(TOKEN_CSTRING
);
168 DUMP_TOKEN(TOKEN_ARRAY
);
171 TRACE("Unknown token %d\n", token
);
177 static BOOL
is_space(char c
)
191 static BOOL
is_operator(char c
)
210 static inline BOOL
is_separator(char c
)
212 return is_space(c
) || is_operator(c
);
215 static WORD
get_operator_token(char c
)
224 return TOKEN_OBRACKET
;
226 return TOKEN_CBRACKET
;
238 return TOKEN_SEMICOLON
;
243 static BOOL
is_keyword(parse_buffer
* buf
, const char* keyword
)
245 DWORD len
= strlen(keyword
);
246 if (!strncasecmp((char*)buf
->buffer
, keyword
,len
) && is_separator(*(buf
->buffer
+len
)))
249 buf
->rem_bytes
-= len
;
255 static WORD
get_keyword_token(parse_buffer
* buf
)
257 if (is_keyword(buf
, "template"))
258 return TOKEN_TEMPLATE
;
259 if (is_keyword(buf
, "WORD"))
261 if (is_keyword(buf
, "DWORD"))
263 if (is_keyword(buf
, "FLOAT"))
265 if (is_keyword(buf
, "DOUBLE"))
267 if (is_keyword(buf
, "CHAR"))
269 if (is_keyword(buf
, "UCHAR"))
271 if (is_keyword(buf
, "SWORD"))
273 if (is_keyword(buf
, "SDWORD"))
275 if (is_keyword(buf
, "VOID"))
277 if (is_keyword(buf
, "STRING"))
279 if (is_keyword(buf
, "UNICODE"))
280 return TOKEN_UNICODE
;
281 if (is_keyword(buf
, "CSTRING"))
282 return TOKEN_CSTRING
;
283 if (is_keyword(buf
, "array"))
289 static BOOL
is_guid(parse_buffer
* buf
)
297 if (*buf
->buffer
!= '<')
300 while (*(buf
->buffer
+pos
) != '>')
302 tmp
[pos
] = *(buf
->buffer
+pos
);
307 if (pos
!= 38 /* <+36+> */)
309 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
313 buf
->rem_bytes
-= pos
;
315 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);
318 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
321 TRACE("Found guid %s (%d)\n", tmp
, pos
);
323 class_id
.Data2
= tab
[0];
324 class_id
.Data3
= tab
[1];
325 class_id
.Data4
[0] = tab
[2];
326 class_id
.Data4
[1] = tab
[3];
327 class_id
.Data4
[2] = tab
[4];
328 class_id
.Data4
[3] = tab
[5];
329 class_id
.Data4
[4] = tab
[6];
330 class_id
.Data4
[5] = tab
[7];
331 class_id
.Data4
[6] = tab
[8];
332 class_id
.Data4
[7] = tab
[9];
334 *(GUID
*)buf
->value
= class_id
;
339 static BOOL
is_name(parse_buffer
* buf
)
345 while (!is_separator(c
= *(buf
->buffer
+pos
)))
347 if (!(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')) || ((c
>= '0') && (c
<= '9')) || (c
== '_') || (c
== '-')))
355 TRACE("Wrong name %s\n", tmp
);
360 buf
->rem_bytes
-= pos
;
362 TRACE("Found name %s\n", tmp
);
363 strcpy((char*)buf
->value
, tmp
);
368 static BOOL
is_float(parse_buffer
* buf
)
376 while (!is_separator(c
= *(buf
->buffer
+pos
)))
378 if (!((!pos
&& (c
== '-')) || ((c
>= '0') && (c
<= '9')) || (!dot
&& (c
== '.'))))
387 buf
->rem_bytes
-= pos
;
389 sscanf(tmp
, "%f", &decimal
);
391 TRACE("Found float %s - %f\n", tmp
, decimal
);
393 *(float*)buf
->value
= decimal
;
398 static BOOL
is_integer(parse_buffer
* buf
)
405 while (!is_separator(c
= *(buf
->buffer
+pos
)))
407 if (!((c
>= '0') && (c
<= '9')))
414 buf
->rem_bytes
-= pos
;
416 sscanf(tmp
, "%d", &integer
);
418 TRACE("Found integer %s - %d\n", tmp
, integer
);
420 *(DWORD
*)buf
->value
= integer
;
425 static BOOL
is_string(parse_buffer
* buf
)
432 if (*buf
->buffer
!= '"')
435 while (!is_separator(c
= *(buf
->buffer
+pos
+1)) && (pos
< 31))
448 TRACE("Wrong string %s\n", tmp
);
452 buf
->buffer
+= pos
+ 2;
453 buf
->rem_bytes
-= pos
+ 2;
455 TRACE("Found string %s\n", tmp
);
456 strcpy((char*)buf
->value
, tmp
);
461 static WORD
parse_TOKEN(parse_buffer
* buf
)
470 if (!read_bytes(buf
, &c
, 1))
472 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
473 if ((c
== '#') || (c
== '/'))
475 /* Handle comment (# or //) */
478 if (!read_bytes(buf
, &c
, 1))
486 if (!read_bytes(buf
, &c
, 1))
493 if (is_operator(c
) && (c
!= '<'))
495 token
= get_operator_token(c
);
508 if ((token
= get_keyword_token(buf
)))
518 token
= TOKEN_INTEGER
;
537 FIXME("Unrecognize element\n");
549 if (!read_bytes(buf
, &token
, 2))
552 /* Convert integer and float list into separate elements */
553 if (token
== TOKEN_INTEGER_LIST
)
555 if (!read_bytes(buf
, &nb_elem
, 4))
557 token
= TOKEN_INTEGER
;
559 TRACE("Integer list (TOKEN_INTEGER_LIST) of size %d\n", nb_elem
);
561 else if (token
== TOKEN_FLOAT_LIST
)
563 if (!read_bytes(buf
, &nb_elem
, 4))
567 TRACE("Float list (TOKEN_FLOAT_LIST) of size %d\n", nb_elem
);
573 token
= is_float
? TOKEN_FLOAT
: TOKEN_INTEGER
;
578 if (!read_bytes(buf
, &integer
, 4))
581 *(DWORD
*)buf
->value
= integer
;
594 if (!read_bytes(buf
, &count
, 4))
596 if (!read_bytes(buf
, strname
, count
))
599 /*TRACE("name = %s\n", strname);*/
601 strcpy((char*)buf
->value
, strname
);
608 if (!read_bytes(buf
, &integer
, 4))
610 /*TRACE("integer = %ld\n", integer);*/
612 *(DWORD
*)buf
->value
= integer
;
620 if (!read_bytes(buf
, &class_id
, 16))
622 sprintf(strguid
, CLSIDFMT
, class_id
.Data1
, class_id
.Data2
, class_id
.Data3
, class_id
.Data4
[0],
623 class_id
.Data4
[1], class_id
.Data4
[2], class_id
.Data4
[3], class_id
.Data4
[4], class_id
.Data4
[5],
624 class_id
.Data4
[6], class_id
.Data4
[7]);
625 /*TRACE("guid = {%s}\n", strguid);*/
627 *(GUID
*)buf
->value
= class_id
;
635 if (!read_bytes(buf
, &count
, 4))
637 if (!read_bytes(buf
, strname
, count
))
640 if (!read_bytes(buf
, &tmp_token
, 2))
642 if ((tmp_token
!= TOKEN_COMMA
) && (tmp_token
!= TOKEN_SEMICOLON
))
643 ERR("No comma or semicolon (got %d)\n", tmp_token
);
644 /*TRACE("name = %s\n", strname);*/
646 strcpy((char*)buf
->value
, strname
);
660 case TOKEN_SEMICOLON
:
686 static const char* get_primitive_string(WORD token
)
720 static WORD
get_TOKEN(parse_buffer
* buf
)
722 if (buf
->token_present
)
724 buf
->token_present
= FALSE
;
725 return buf
->current_token
;
728 buf
->current_token
= parse_TOKEN(buf
);
730 return buf
->current_token
;
733 static WORD
check_TOKEN(parse_buffer
* buf
)
735 if (buf
->token_present
)
736 return buf
->current_token
;
738 buf
->current_token
= parse_TOKEN(buf
);
739 buf
->token_present
= TRUE
;
741 return buf
->current_token
;
744 static inline BOOL
is_primitive_type(WORD token
)
769 BOOL
parse_template_option_info(parse_buffer
* buf
)
771 xtemplate
* cur_template
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
];
773 if (check_TOKEN(buf
) == TOKEN_DOT
)
776 if (get_TOKEN(buf
) != TOKEN_DOT
)
778 if (get_TOKEN(buf
) != TOKEN_DOT
)
780 cur_template
->open
= TRUE
;
786 if (get_TOKEN(buf
) != TOKEN_NAME
)
788 strcpy(cur_template
->childs
[cur_template
->nb_childs
], (char*)buf
->value
);
789 if (check_TOKEN(buf
) == TOKEN_GUID
)
791 cur_template
->nb_childs
++;
792 if (check_TOKEN(buf
) != TOKEN_COMMA
)
796 cur_template
->open
= FALSE
;
802 static BOOL
parse_template_members_list(parse_buffer
* buf
)
811 cur_member
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[idx_member
];
813 if (check_TOKEN(buf
) == TOKEN_ARRAY
)
819 if (check_TOKEN(buf
) == TOKEN_NAME
)
821 cur_member
->type
= get_TOKEN(buf
);
822 cur_member
->idx_template
= 0;
823 while (cur_member
->idx_template
< buf
->pdxf
->nb_xtemplates
)
825 if (!strcasecmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[cur_member
->idx_template
].name
))
827 cur_member
->idx_template
++;
829 if (cur_member
->idx_template
== buf
->pdxf
->nb_xtemplates
)
831 ERR("Reference to a nonexistent template '%s'\n", (char*)buf
->value
);
835 else if (is_primitive_type(check_TOKEN(buf
)))
836 cur_member
->type
= get_TOKEN(buf
);
840 if (get_TOKEN(buf
) != TOKEN_NAME
)
842 strcpy(cur_member
->name
, (char*)buf
->value
);
846 while (check_TOKEN(buf
) == TOKEN_OBRACKET
)
848 if (nb_dims
>= MAX_ARRAY_DIM
)
850 FIXME("Too many dimensions (%d) for multi-dimensional array\n", nb_dims
+ 1);
854 if (check_TOKEN(buf
) == TOKEN_INTEGER
)
857 cur_member
->dim_fixed
[nb_dims
] = TRUE
;
858 cur_member
->dim_value
[nb_dims
] = *(DWORD
*)buf
->value
;
863 if (get_TOKEN(buf
) != TOKEN_NAME
)
865 for (i
= 0; i
< idx_member
; i
++)
867 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].name
))
869 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].nb_dims
)
871 ERR("Array cannot be used to specify variable array size\n");
874 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].type
!= TOKEN_DWORD
)
876 FIXME("Only DWORD supported to specify variable array size\n");
884 ERR("Reference to unknown member %s\n", (char*)buf
->value
);
887 cur_member
->dim_fixed
[nb_dims
] = FALSE
;
888 cur_member
->dim_value
[nb_dims
] = i
;
890 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
896 cur_member
->nb_dims
= nb_dims
;
898 if (get_TOKEN(buf
) != TOKEN_SEMICOLON
)
904 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].nb_members
= idx_member
;
909 static BOOL
parse_template_parts(parse_buffer
* buf
)
911 if (!parse_template_members_list(buf
))
913 if (check_TOKEN(buf
) == TOKEN_OBRACKET
)
916 if (!parse_template_option_info(buf
))
918 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
925 static void go_to_next_definition(parse_buffer
* buf
)
927 while (buf
->rem_bytes
)
929 char c
= *buf
->buffer
;
930 if ((c
== '#') || (c
== '/'))
932 read_bytes(buf
, &c
, 1);
933 /* Handle comment (# or //) */
936 if (!read_bytes(buf
, &c
, 1))
944 if (!read_bytes(buf
, &c
, 1))
949 else if (is_space(*buf
->buffer
))
959 BOOL
parse_template(parse_buffer
* buf
)
961 if (get_TOKEN(buf
) != TOKEN_TEMPLATE
)
963 if (get_TOKEN(buf
) != TOKEN_NAME
)
965 strcpy(buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, (char*)buf
->value
);
966 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
968 if (get_TOKEN(buf
) != TOKEN_GUID
)
970 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
= *(GUID
*)buf
->value
;
971 if (!parse_template_parts(buf
))
973 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
977 /* Go to the next template */
978 go_to_next_definition(buf
);
981 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
));
982 buf
->pdxf
->nb_xtemplates
++;
987 static BOOL
parse_object_members_list(parse_buffer
* buf
)
991 xtemplate
* pt
= buf
->pxt
[buf
->level
];
992 DWORD last_dword
= 0;
994 for (i
= 0; i
< pt
->nb_members
; i
++)
999 buf
->pxo
->members
[i
].name
= pt
->members
[i
].name
;
1000 buf
->pxo
->members
[i
].start
= buf
->cur_pdata
;
1002 for (k
= 0; k
< pt
->members
[i
].nb_dims
; k
++)
1004 if (pt
->members
[i
].dim_fixed
[k
])
1005 nb_elems
*= pt
->members
[i
].dim_value
[k
];
1007 nb_elems
*= *(DWORD
*)buf
->pxo
->members
[pt
->members
[i
].dim_value
[k
]].start
;
1010 TRACE("Elements to consider: %d\n", nb_elems
);
1012 for (k
= 0; k
< nb_elems
; k
++)
1016 token
= check_TOKEN(buf
);
1017 if (token
== TOKEN_COMMA
)
1023 /* Allow comma omission */
1024 if (!((token
== TOKEN_FLOAT
) || (token
== TOKEN_INTEGER
)))
1029 if (pt
->members
[i
].type
== TOKEN_NAME
)
1033 TRACE("Found sub-object %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1035 /* To do template lookup */
1036 for (j
= 0; j
< buf
->pdxf
->nb_xtemplates
; j
++)
1038 if (!strcasecmp(buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
, buf
->pdxf
->xtemplates
[j
].name
))
1040 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[j
];
1044 if (j
== buf
->pdxf
->nb_xtemplates
)
1046 ERR("Unknown template %s\n", (char*)buf
->value
);
1050 TRACE("Enter %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1051 if (!parse_object_parts(buf
, FALSE
))
1060 token
= check_TOKEN(buf
);
1061 if (token
== TOKEN_INTEGER
)
1064 last_dword
= *(DWORD
*)buf
->value
;
1065 TRACE("%s = %d\n", pt
->members
[i
].name
, *(DWORD
*)buf
->value
);
1066 /* Assume larger size */
1067 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
1069 FIXME("Buffer too small\n");
1072 if (pt
->members
[i
].type
== TOKEN_WORD
)
1074 *(((WORD
*)(buf
->cur_pdata
))) = (WORD
)(*(DWORD
*)buf
->value
);
1075 buf
->cur_pdata
+= 2;
1077 else if (pt
->members
[i
].type
== TOKEN_DWORD
)
1079 *(((DWORD
*)(buf
->cur_pdata
))) = (DWORD
)(*(DWORD
*)buf
->value
);
1080 buf
->cur_pdata
+= 4;
1084 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1088 else if (token
== TOKEN_FLOAT
)
1091 TRACE("%s = %f\n", pt
->members
[i
].name
, *(float*)buf
->value
);
1092 /* Assume larger size */
1093 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
1095 FIXME("Buffer too small\n");
1098 if (pt
->members
[i
].type
== TOKEN_FLOAT
)
1100 *(((float*)(buf
->cur_pdata
))) = (float)(*(float*)buf
->value
);
1101 buf
->cur_pdata
+= 4;
1105 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1109 else if (token
== TOKEN_LPSTR
)
1112 TRACE("%s = %s\n", pt
->members
[i
].name
, (char*)buf
->value
);
1113 /* Assume larger size */
1114 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
1116 FIXME("Buffer too small\n");
1119 if (pt
->members
[i
].type
== TOKEN_LPSTR
)
1121 int len
= strlen((char*)buf
->value
) + 1;
1122 if ((buf
->cur_pstrings
- buf
->pstrings
+ len
) > MAX_STRINGS_BUFFER
)
1124 FIXME("Buffer too small %p %p %d\n", buf
->cur_pstrings
, buf
->pstrings
, len
);
1127 strcpy((char*)buf
->cur_pstrings
, (char*)buf
->value
);
1128 *(((LPCSTR
*)(buf
->cur_pdata
))) = (char*)buf
->cur_pstrings
;
1129 buf
->cur_pstrings
+= len
;
1130 buf
->cur_pdata
+= 4;
1134 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1140 FIXME("Unexpected token %d\n", token
);
1146 if (buf
->txt
&& (check_TOKEN(buf
) != TOKEN_CBRACE
))
1148 token
= get_TOKEN(buf
);
1149 if ((token
!= TOKEN_SEMICOLON
) && (token
!= TOKEN_COMMA
))
1151 /* Allow comma instead of semicolon in some specific cases */
1152 if (!((token
== TOKEN_COMMA
) && ((i
+1) < pt
->nb_members
) && (pt
->members
[i
].type
== pt
->members
[i
+1].type
)
1153 && (!pt
->members
[i
].nb_dims
) && (!pt
->members
[i
+1].nb_dims
)))
1162 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
)
1164 if (!parse_object_members_list(buf
))
1169 buf
->pxo
->size
= buf
->cur_pdata
- buf
->pxo
->pdata
;
1171 /* Skip trailing semicolon */
1172 while (check_TOKEN(buf
) == TOKEN_SEMICOLON
)
1177 if (check_TOKEN(buf
) == TOKEN_OBRACE
)
1181 if (get_TOKEN(buf
) != TOKEN_NAME
)
1183 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1185 TRACE("Found optional reference %s\n", (char*)buf
->value
);
1186 for (i
= 0; i
< buf
->nb_pxo_globals
; i
++)
1188 for (j
= 0; j
< (buf
->pxo_globals
[i
])[0].nb_subobjects
; j
++)
1190 if (!strcmp((buf
->pxo_globals
[i
])[j
].name
, (char*)buf
->value
))
1195 if (i
== buf
->nb_pxo_globals
)
1197 ERR("Reference to unknown object %s\n", (char*)buf
->value
);
1200 buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
1201 buf
->pxo
->childs
[buf
->pxo
->nb_childs
]->ptarget
= &(buf
->pxo_globals
[i
])[j
];
1202 buf
->pxo
->nb_childs
++;
1204 else if (check_TOKEN(buf
) == TOKEN_NAME
)
1206 xobject
* pxo
= buf
->pxo
;
1207 buf
->pxo
= buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
1209 TRACE("Enter optional %s\n", (char*)buf
->value
);
1211 if (!parse_object(buf
))
1218 buf
->pxo
->nb_childs
++;
1225 if (buf
->pxo
->nb_childs
> MAX_CHILDS
)
1227 FIXME("Too many childs %d\n", buf
->pxo
->nb_childs
);
1234 BOOL
parse_object(parse_buffer
* buf
)
1238 buf
->pxo
->pdata
= buf
->cur_pdata
;
1239 buf
->pxo
->ptarget
= NULL
;
1241 if (get_TOKEN(buf
) != TOKEN_NAME
)
1244 /* To do template lookup */
1245 for (i
= 0; i
< buf
->pdxf
->nb_xtemplates
; i
++)
1247 if (!strcasecmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[i
].name
))
1249 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[i
];
1250 memcpy(&buf
->pxo
->type
, &buf
->pdxf
->xtemplates
[i
].class_id
, 16);
1254 if (i
== buf
->pdxf
->nb_xtemplates
)
1256 ERR("Unknown template %s\n", (char*)buf
->value
);
1260 if (check_TOKEN(buf
) == TOKEN_NAME
)
1263 strcpy(buf
->pxo
->name
, (char*)buf
->value
);
1266 buf
->pxo
->name
[0] = 0;
1268 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
1270 if (check_TOKEN(buf
) == TOKEN_GUID
)
1273 memcpy(&buf
->pxo
->class_id
, buf
->value
, 16);
1276 memset(&buf
->pxo
->class_id
, 0, 16);
1278 if (!parse_object_parts(buf
, TRUE
))
1280 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1285 /* Go to the next object */
1286 go_to_next_definition(buf
);