widl: Add support for generating a .rgs registration script for the defined interfaces.
This commit is contained in:
parent
233814c21e
commit
ce3abe8c0c
|
@ -9,6 +9,7 @@ C_SRCS = \
|
||||||
hash.c \
|
hash.c \
|
||||||
header.c \
|
header.c \
|
||||||
proxy.c \
|
proxy.c \
|
||||||
|
register.c \
|
||||||
server.c \
|
server.c \
|
||||||
typegen.c \
|
typegen.c \
|
||||||
typelib.c \
|
typelib.c \
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern void write_type_decl_left(FILE *f, type_t *t);
|
||||||
extern int needs_space_after(type_t *t);
|
extern int needs_space_after(type_t *t);
|
||||||
extern int is_object(const type_t *iface);
|
extern int is_object(const type_t *iface);
|
||||||
extern int is_local(const attr_list_t *list);
|
extern int is_local(const attr_list_t *list);
|
||||||
|
extern int count_methods(const type_t *iface);
|
||||||
extern int need_stub(const type_t *iface);
|
extern int need_stub(const type_t *iface);
|
||||||
extern int need_proxy(const type_t *iface);
|
extern int need_proxy(const type_t *iface);
|
||||||
extern int need_stub_files(const statement_list_t *stmts);
|
extern int need_stub_files(const statement_list_t *stmts);
|
||||||
|
|
|
@ -332,6 +332,7 @@ input: gbl_statements { fix_incomplete();
|
||||||
write_proxies($1);
|
write_proxies($1);
|
||||||
write_client($1);
|
write_client($1);
|
||||||
write_server($1);
|
write_server($1);
|
||||||
|
write_regscript($1);
|
||||||
write_dlldata($1);
|
write_dlldata($1);
|
||||||
write_local_stubs($1);
|
write_local_stubs($1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -490,7 +490,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||||
print_proxy("\n");
|
print_proxy("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count_methods(type_t *iface)
|
int count_methods(const type_t *iface)
|
||||||
{
|
{
|
||||||
const statement_t *stmt;
|
const statement_t *stmt;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Generation of dll registration scripts
|
||||||
|
*
|
||||||
|
* Copyright 2010 Alexandre Julliard
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "widl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "header.h"
|
||||||
|
#include "typegen.h"
|
||||||
|
|
||||||
|
static int indent;
|
||||||
|
|
||||||
|
static const char *format_uuid( const UUID *uuid )
|
||||||
|
{
|
||||||
|
static char buffer[40];
|
||||||
|
sprintf( buffer, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||||
|
uuid->Data1, uuid->Data2, uuid->Data3,
|
||||||
|
uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
|
||||||
|
uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] );
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_interface( const type_t *iface )
|
||||||
|
{
|
||||||
|
const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
|
||||||
|
|
||||||
|
if (!type_iface_get_inherit( iface )) return 0;
|
||||||
|
if (!need_proxy( iface )) return 0;
|
||||||
|
if (!uuid) return 0;
|
||||||
|
put_str( indent, "ForceRemove '%s' = s '%s'\n", format_uuid( uuid ), iface->name );
|
||||||
|
put_str( indent, "{\n" );
|
||||||
|
indent++;
|
||||||
|
put_str( indent, "NumMethods = s %u\n", count_methods( iface ));
|
||||||
|
put_str( indent, "ProxyStubClsid32 = s '%%CLSID_PSFactoryBuffer%%'\n" );
|
||||||
|
indent--;
|
||||||
|
put_str( indent, "}\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_interfaces( const statement_list_t *stmts )
|
||||||
|
{
|
||||||
|
const statement_t *stmt;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||||
|
{
|
||||||
|
if (stmt->type == STMT_LIBRARY)
|
||||||
|
count += write_interfaces( stmt->u.lib->stmts );
|
||||||
|
else if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE)
|
||||||
|
count += write_interface( stmt->u.type );
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put a string into the resource file */
|
||||||
|
static inline void put_string( const char *str )
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
unsigned char ch = *str++;
|
||||||
|
put_word( toupper(ch) );
|
||||||
|
}
|
||||||
|
put_word( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_regscript( const statement_list_t *stmts )
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (!do_regscript) return;
|
||||||
|
if (do_everything && !need_proxy_file( stmts )) return;
|
||||||
|
|
||||||
|
init_output_buffer();
|
||||||
|
|
||||||
|
put_str( indent, "HKCR\n" );
|
||||||
|
put_str( indent++, "{\n" );
|
||||||
|
|
||||||
|
put_str( indent, "NoRemove Interface\n" );
|
||||||
|
put_str( indent++, "{\n" );
|
||||||
|
count = write_interfaces( stmts );
|
||||||
|
put_str( --indent, "}\n" );
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
{
|
||||||
|
put_str( indent, "NoRemove CLSID\n" );
|
||||||
|
put_str( indent++, "{\n" );
|
||||||
|
put_str( indent, "ForceRemove '%%CLSID_PSFactoryBuffer%%' = s 'PSFactoryBuffer'\n" );
|
||||||
|
put_str( indent++, "{\n" );
|
||||||
|
put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s 'Both' }\n" );
|
||||||
|
put_str( --indent, "}\n" );
|
||||||
|
put_str( --indent, "}\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
put_str( --indent, "}\n" );
|
||||||
|
|
||||||
|
if (strendswith( regscript_name, ".res" )) /* create a binary resource file */
|
||||||
|
{
|
||||||
|
unsigned char *data = output_buffer;
|
||||||
|
size_t data_size = output_buffer_pos;
|
||||||
|
size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
|
||||||
|
|
||||||
|
header_size += (strlen(regscript_token) + strlen("WINE_REGISTRY") + 2) * sizeof(unsigned short);
|
||||||
|
|
||||||
|
init_output_buffer();
|
||||||
|
|
||||||
|
put_dword( 0 ); /* ResSize */
|
||||||
|
put_dword( 32 ); /* HeaderSize */
|
||||||
|
put_word( 0xffff ); /* ResType */
|
||||||
|
put_word( 0x0000 );
|
||||||
|
put_word( 0xffff ); /* ResName */
|
||||||
|
put_word( 0x0000 );
|
||||||
|
put_dword( 0 ); /* DataVersion */
|
||||||
|
put_word( 0 ); /* Memory options */
|
||||||
|
put_word( 0 ); /* Language */
|
||||||
|
put_dword( 0 ); /* Version */
|
||||||
|
put_dword( 0 ); /* Characteristics */
|
||||||
|
|
||||||
|
put_dword( data_size ); /* ResSize */
|
||||||
|
put_dword( (header_size + 3) & ~3 ); /* HeaderSize */
|
||||||
|
put_string( "WINE_REGISTRY" ); /* ResType */
|
||||||
|
put_string( regscript_token ); /* ResName */
|
||||||
|
align_output( 4 );
|
||||||
|
put_dword( 0 ); /* DataVersion */
|
||||||
|
put_word( 0 ); /* Memory options */
|
||||||
|
put_word( 0 ); /* Language */
|
||||||
|
put_dword( 0 ); /* Version */
|
||||||
|
put_dword( 0 ); /* Characteristics */
|
||||||
|
|
||||||
|
put_data( data, data_size );
|
||||||
|
free( data );
|
||||||
|
align_output( 4 );
|
||||||
|
flush_output_buffer( regscript_name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FILE *f = fopen( regscript_name, "w" );
|
||||||
|
if (!f) error( "Could not open %s for output\n", regscript_name );
|
||||||
|
if (fwrite( output_buffer, output_buffer_pos, 1, f ) != output_buffer_pos)
|
||||||
|
error( "Failed to write to %s\n", regscript_name );
|
||||||
|
if (fclose( f ))
|
||||||
|
error( "Failed to write to %s\n", regscript_name );
|
||||||
|
}
|
||||||
|
}
|
|
@ -326,6 +326,32 @@ void put_pword( unsigned int val )
|
||||||
else put_dword( val );
|
else put_dword( val );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void put_str( int indent, const char *format, ... )
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
check_output_buffer_space( 4 * indent );
|
||||||
|
memset( output_buffer + output_buffer_pos, ' ', 4 * indent );
|
||||||
|
output_buffer_pos += 4 * indent;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t size = output_buffer_size - output_buffer_pos;
|
||||||
|
va_start( args, format );
|
||||||
|
n = vsnprintf( (char *)output_buffer + output_buffer_pos, size, format, args );
|
||||||
|
va_end( args );
|
||||||
|
if (n == -1) size *= 2;
|
||||||
|
else if ((size_t)n >= size) size = n + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output_buffer_pos += n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
check_output_buffer_space( size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void align_output( unsigned int align )
|
void align_output( unsigned int align )
|
||||||
{
|
{
|
||||||
size_t size = align - (output_buffer_pos % align);
|
size_t size = align - (output_buffer_pos % align);
|
||||||
|
|
|
@ -64,6 +64,7 @@ extern void put_word( unsigned short val );
|
||||||
extern void put_dword( unsigned int val );
|
extern void put_dword( unsigned int val );
|
||||||
extern void put_qword( unsigned int val );
|
extern void put_qword( unsigned int val );
|
||||||
extern void put_pword( unsigned int val );
|
extern void put_pword( unsigned int val );
|
||||||
|
extern void put_str( int indent, const char *format, ... ) __attribute__((format (printf, 2, 3)));
|
||||||
extern void align_output( unsigned int align );
|
extern void align_output( unsigned int align );
|
||||||
|
|
||||||
/* typelibs expect the minor version to be stored in the higher bits and
|
/* typelibs expect the minor version to be stored in the higher bits and
|
||||||
|
|
|
@ -69,6 +69,7 @@ static const char usage[] =
|
||||||
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
|
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
|
||||||
" --prefix-client=p Prefix names of client stubs with 'p'\n"
|
" --prefix-client=p Prefix names of client stubs with 'p'\n"
|
||||||
" --prefix-server=p Prefix names of server functions with 'p'\n"
|
" --prefix-server=p Prefix names of server functions with 'p'\n"
|
||||||
|
" -r Generate registration script\n"
|
||||||
" -s Generate server stub\n"
|
" -s Generate server stub\n"
|
||||||
" -t Generate typelib\n"
|
" -t Generate typelib\n"
|
||||||
" -u Generate interface identifiers file\n"
|
" -u Generate interface identifiers file\n"
|
||||||
|
@ -101,6 +102,7 @@ int do_typelib = 0;
|
||||||
int do_proxies = 0;
|
int do_proxies = 0;
|
||||||
int do_client = 0;
|
int do_client = 0;
|
||||||
int do_server = 0;
|
int do_server = 0;
|
||||||
|
int do_regscript = 0;
|
||||||
int do_idfile = 0;
|
int do_idfile = 0;
|
||||||
int do_dlldata = 0;
|
int do_dlldata = 0;
|
||||||
static int no_preprocess = 0;
|
static int no_preprocess = 0;
|
||||||
|
@ -122,6 +124,8 @@ char *client_name;
|
||||||
char *client_token;
|
char *client_token;
|
||||||
char *server_name;
|
char *server_name;
|
||||||
char *server_token;
|
char *server_token;
|
||||||
|
char *regscript_name;
|
||||||
|
char *regscript_token;
|
||||||
static char *idfile_name;
|
static char *idfile_name;
|
||||||
static char *idfile_token;
|
static char *idfile_token;
|
||||||
char *temp_name;
|
char *temp_name;
|
||||||
|
@ -152,7 +156,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char short_options[] =
|
static const char short_options[] =
|
||||||
"b:cC:d:D:EhH:I:m:No:pP:sS:tT:uU:VW";
|
"b:cC:d:D:EhH:I:m:No:pP:rsS:tT:uU:VW";
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{ "dlldata", 1, NULL, DLLDATA_OPTION },
|
{ "dlldata", 1, NULL, DLLDATA_OPTION },
|
||||||
{ "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
|
{ "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
|
||||||
|
@ -284,6 +288,7 @@ static void set_everything(int x)
|
||||||
do_proxies = x;
|
do_proxies = x;
|
||||||
do_client = x;
|
do_client = x;
|
||||||
do_server = x;
|
do_server = x;
|
||||||
|
do_regscript = x;
|
||||||
do_idfile = x;
|
do_idfile = x;
|
||||||
do_dlldata = x;
|
do_dlldata = x;
|
||||||
}
|
}
|
||||||
|
@ -584,6 +589,10 @@ int main(int argc,char *argv[])
|
||||||
case 'P':
|
case 'P':
|
||||||
proxy_name = xstrdup(optarg);
|
proxy_name = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
do_everything = 0;
|
||||||
|
do_regscript = 1;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
do_everything = 0;
|
do_everything = 0;
|
||||||
do_server = 1;
|
do_server = 1;
|
||||||
|
@ -624,13 +633,15 @@ int main(int argc,char *argv[])
|
||||||
if (!output_name) output_name = dup_basename(input_name, ".idl");
|
if (!output_name) output_name = dup_basename(input_name, ".idl");
|
||||||
|
|
||||||
if (!do_everything &&
|
if (!do_everything &&
|
||||||
do_header + do_typelib + do_proxies + do_client + do_server + do_idfile + do_dlldata == 1)
|
do_header + do_typelib + do_proxies + do_client +
|
||||||
|
do_server + do_regscript + do_idfile + do_dlldata == 1)
|
||||||
{
|
{
|
||||||
if (do_header) header_name = output_name;
|
if (do_header) header_name = output_name;
|
||||||
else if (do_typelib) typelib_name = output_name;
|
else if (do_typelib) typelib_name = output_name;
|
||||||
else if (do_proxies) proxy_name = output_name;
|
else if (do_proxies) proxy_name = output_name;
|
||||||
else if (do_client) client_name = output_name;
|
else if (do_client) client_name = output_name;
|
||||||
else if (do_server) server_name = output_name;
|
else if (do_server) server_name = output_name;
|
||||||
|
else if (do_regscript) regscript_name = output_name;
|
||||||
else if (do_idfile) idfile_name = output_name;
|
else if (do_idfile) idfile_name = output_name;
|
||||||
else if (do_dlldata) dlldata_name = output_name;
|
else if (do_dlldata) dlldata_name = output_name;
|
||||||
}
|
}
|
||||||
|
@ -698,6 +709,11 @@ int main(int argc,char *argv[])
|
||||||
strcat(server_name, "_s.c");
|
strcat(server_name, "_s.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!regscript_name && do_regscript) {
|
||||||
|
regscript_name = dup_basename(input_name, ".idl");
|
||||||
|
strcat(regscript_name, "_r.rgs");
|
||||||
|
}
|
||||||
|
|
||||||
if (!idfile_name && do_idfile) {
|
if (!idfile_name && do_idfile) {
|
||||||
idfile_name = dup_basename(input_name, ".idl");
|
idfile_name = dup_basename(input_name, ".idl");
|
||||||
strcat(idfile_name, "_i.c");
|
strcat(idfile_name, "_i.c");
|
||||||
|
@ -706,6 +722,7 @@ int main(int argc,char *argv[])
|
||||||
if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
|
if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
|
||||||
if (do_client) client_token = dup_basename_token(client_name,"_c.c");
|
if (do_client) client_token = dup_basename_token(client_name,"_c.c");
|
||||||
if (do_server) server_token = dup_basename_token(server_name,"_s.c");
|
if (do_server) server_token = dup_basename_token(server_name,"_s.c");
|
||||||
|
if (do_regscript) regscript_token = dup_basename_token(regscript_name,"_r.rgs");
|
||||||
|
|
||||||
add_widl_version_define();
|
add_widl_version_define();
|
||||||
wpp_add_define("_WIN32", NULL);
|
wpp_add_define("_WIN32", NULL);
|
||||||
|
@ -784,6 +801,8 @@ static void rm_tempfile(void)
|
||||||
unlink(client_name);
|
unlink(client_name);
|
||||||
if (do_server)
|
if (do_server)
|
||||||
unlink(server_name);
|
unlink(server_name);
|
||||||
|
if (do_regscript)
|
||||||
|
unlink(regscript_name);
|
||||||
if (do_idfile)
|
if (do_idfile)
|
||||||
unlink(idfile_name);
|
unlink(idfile_name);
|
||||||
if (do_proxies)
|
if (do_proxies)
|
||||||
|
|
|
@ -41,6 +41,7 @@ extern int do_typelib;
|
||||||
extern int do_proxies;
|
extern int do_proxies;
|
||||||
extern int do_client;
|
extern int do_client;
|
||||||
extern int do_server;
|
extern int do_server;
|
||||||
|
extern int do_regscript;
|
||||||
extern int do_idfile;
|
extern int do_idfile;
|
||||||
extern int do_dlldata;
|
extern int do_dlldata;
|
||||||
extern int old_names;
|
extern int old_names;
|
||||||
|
@ -61,6 +62,8 @@ extern char *client_name;
|
||||||
extern char *client_token;
|
extern char *client_token;
|
||||||
extern char *server_name;
|
extern char *server_name;
|
||||||
extern char *server_token;
|
extern char *server_token;
|
||||||
|
extern char *regscript_name;
|
||||||
|
extern char *regscript_token;
|
||||||
extern const char *prefix_client;
|
extern const char *prefix_client;
|
||||||
extern const char *prefix_server;
|
extern const char *prefix_server;
|
||||||
extern size_t pointer_size;
|
extern size_t pointer_size;
|
||||||
|
@ -74,6 +77,7 @@ extern void write_id_data(const statement_list_t *stmts);
|
||||||
extern void write_proxies(const statement_list_t *stmts);
|
extern void write_proxies(const statement_list_t *stmts);
|
||||||
extern void write_client(const statement_list_t *stmts);
|
extern void write_client(const statement_list_t *stmts);
|
||||||
extern void write_server(const statement_list_t *stmts);
|
extern void write_server(const statement_list_t *stmts);
|
||||||
|
extern void write_regscript(const statement_list_t *stmts);
|
||||||
extern void write_local_stubs(const statement_list_t *stmts);
|
extern void write_local_stubs(const statement_list_t *stmts);
|
||||||
extern void write_dlldata(const statement_list_t *stmts);
|
extern void write_dlldata(const statement_list_t *stmts);
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,12 @@ Only generate 32-bit, respectively 64-bit code (the default is to
|
||||||
generate both 32-bit and 64-bit versions into the same destination
|
generate both 32-bit and 64-bit versions into the same destination
|
||||||
file).
|
file).
|
||||||
.PP
|
.PP
|
||||||
|
.B Registration script options:
|
||||||
|
.IP "\fB-r\fR"
|
||||||
|
Generate a registration script. The default output filename is
|
||||||
|
\fIinfile\fB_r.rgs\fR. If the output file name ends in \fB.res\fR, a
|
||||||
|
binary resource file containing the script is generated instead.
|
||||||
|
.PP
|
||||||
.B Dlldata file options:
|
.B Dlldata file options:
|
||||||
.IP "\fB--dlldata-only\fI name1 [name2...]"
|
.IP "\fB--dlldata-only\fI name1 [name2...]"
|
||||||
Regenerate the dlldata file from scratch using the specified proxy
|
Regenerate the dlldata file from scratch using the specified proxy
|
||||||
|
|
Loading…
Reference in New Issue