1/4 patches for compilation of ATL & MFC

Boaz Harrosh boaz at electrozaur.com
Thu Mar 11 11:10:26 CST 2004


I'll send 4 patches here for review.
Once the comments stop I'll send them to patches.
Do I send patches to .h files or the .idl is enough?

PATCH 1
uuidof.diff - enable use of some ms extensions

- include/wine/uuidof.h (new)
    Lets GCC compiler use the uuidof MSVC++ extension used in ATL. See comments inside the file

- include wine/pretty_com.h (new)
    Lets any C++ compiler use the __decelspec( property () ) MSVC++ extension. See comments inside the file

- tools/pretty_com.pl
    A Perl script that changes __decelspec( property () ) declarations to the proper macros from pretty_com.h. see comments inside the file

- include/unknwn.idl (updated)
    Adds a C++ only extension to the IUnknown Interface. This is to let ATL compile (use of uuidof.h)


-------------- next part --------------
Index: include/unknwn.idl
===================================================================
RCS file: /home/wine/wine/include/unknwn.idl,v
retrieving revision 1.4
diff -u -r1.4 unknwn.idl
--- include/unknwn.idl	12 Apr 2003 00:09:14 -0000	1.4
+++ include/unknwn.idl	10 Mar 2004 08:36:47 -0000
@@ -30,7 +30,6 @@
 cpp_quote("#endif")

 /* Interfaces */
-
 [
   local,
   object,
@@ -46,7 +45,58 @@
     [out, iid_is(riid)] void **ppvObject);
   ULONG AddRef();
   ULONG Release();
+
+cpp_quote("/*This is so we can add the Template QueryInterface for use by ATL*/")
+cpp_quote("/*do a -D_WINE_NO_UUIDOF_ if your cplusplus compiler breaks on it*/")
+cpp_quote("#if defined(__cplusplus) && !defined(_WINE_NO_UUIDOF_)")
+cpp_quote("")
+cpp_quote("#include <wine/uuidof.h>")
+cpp_quote("#ifndef __IUnknown_INTERFACE_DEFINED__")
+cpp_quote("#define __IUnknown_INTERFACE_DEFINED__")
+cpp_quote("")
+cpp_quote("DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);")
+cpp_quote("")
+cpp_quote("extern \"C++\" {")
+cpp_quote("")
+cpp_quote("#ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE")
+cpp_quote("struct __attribute__((com_interface)) IUnknown")
+cpp_quote("#else")
+cpp_quote("struct IUnknown")
+cpp_quote("#endif")
+cpp_quote("{")
+cpp_quote("    virtual HRESULT STDMETHODCALLTYPE QueryInterface(")
+cpp_quote("        REFIID riid,")
+cpp_quote("        void** ppvObject) = 0;")
+cpp_quote("")
+cpp_quote("    virtual ULONG STDMETHODCALLTYPE AddRef(")
+cpp_quote("        ) = 0;")
+cpp_quote("")
+cpp_quote("    virtual ULONG STDMETHODCALLTYPE Release(")
+cpp_quote("        ) = 0;")
+cpp_quote("")
+cpp_quote("    template <class Q>")
+cpp_quote("    HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)")
+cpp_quote("    {")
+cpp_quote("        return QueryInterface(__uuidof(Q), (void**)pp);")
+cpp_quote("    }")
+cpp_quote("};")
+cpp_quote("")
+cpp_quote("} // extern \"C++\"")
+cpp_quote("")
+cpp_quote("#define IUnknown_METHODS \\")
+cpp_quote("    ICOM_MSVTABLE_COMPAT_FIELDS \\")
+cpp_quote("    /*** IUnknown methods ***/ \\")
+cpp_quote("    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \\")
+cpp_quote("    STDMETHOD_(ULONG,AddRef)(THIS) PURE; \\")
+cpp_quote("    STDMETHOD_(ULONG,Release)(THIS) PURE;")
+cpp_quote("")
+cpp_quote("#endif //__IUnknown_INTERFACE_DEFINED__")
+cpp_quote("#else /* defined(__cplusplus) && !defined(_WINE_NO_UUIDOF_) */")
 }
+
+cpp_quote("#endif /* defined(__cplusplus) && !defined(_WINE_NO_UUIDOF_) */")
+cpp_quote("")
+cpp_quote("")

 [
   object,

--- /dev/null	1970-01-01 02:00:00.000000000 +0200
+++ include/wine/pretty_com.h	2004-02-25 21:21:18.000000000 +0200
@@ -0,0 +1,218 @@
+/*
+ * Add support for Microsoft extention
+ *           __declspec( property (get= xxxx,put = yyyy) )
+ *
+ * Copyright 2004 Boaz Harrosh boaz at ElectroZaur.com
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __pretty_com_h__
+#define __pretty_com_h__
+
+#if !defined( __cplusplus )
+# error Use this file only for C++ compilation
+#endif
+
+/*
+explanation:
+  the ms-extention __declspec(property()) lets you associate a ?fake? variable name to
+  one or a pair of class member functions. So function calls will be made where in
+  code a variable assignment or access is made. This makes C++ syntax look more
+  like script or 4th generation language.
+
+For example:
+	class HasProperty{
+	public:
+		__declspec( property ( get=GetFoo ,put=PutFoo ) )
+		int Foo ;
+
+		int GetFoo() ;
+		void PutFoo(int newVal) ;
+	}
+will let you use code like:
+	HasProperty hp ;
+	int i = hp.Foo ;
+	hp.Foo = i * 17 ;
+
+In effect Line 2 above invokes GetFoo() (R-Value)
+and Line 3 will invoke PutFoo(..) (L-Value)
+Foo has no allocation in memory and HasProperty does not grow in any way
+by the presence of Foo.
+
+Below code will let such code usage to be used by any standard C++ compiler.
+ __declspec declarations must change but source code can stay the same.
+ Same new declarations can than be used by both MSVC or other compilers.
+
+Use:
+    ALL_P( type, PropertyName )
+    GET_P( type, PropertyName )
+    PUT_P( type, PropertyName )
+if the Foo name will have a GetFoo/PutFoo corresponding members.
+
+Use:
+    ALL_PROP( type,  PropertyName, GetFunction ,PutFunction )
+    GET_PROP( type,  PropertyName, GetFunction )
+    PUT_PROP( type,  PropertyName, PutFunction )
+if you need specific control on associated member function names
+
+Don't forget to use DECLARE_PROP_CLASS( classname ) anywhere in
+the class before the first property.
+
+Note:
+  the pretty_com.pl program was written for code generated by the MSVC
+  #import directive. It will assume the simple  GetFoo/PutFoo naming.
+  Feel free to submit fixes for a more general program
+*/
+
+#if defined( _GNUC_ )
+// original offsetof will warn on GCC so below will turn this warning off
+// 128 is to avoid alignment fix ups.
+#	undef offsetof
+#	define offsetof(s,m)   ( ((size_t)&( ((s*)128)->m )) - 128 )
+#endif
+
+#ifdef _MSC_EXTENSIONS
+/*compiled under msvc with extentions turned on (default for msvc)*/
+
+#define DECLARE_PROP_CLASS( aclass )
+
+#define ALL_P( type ,name )\
+__declspec(property(get=Get##name,put=Put##name))\
+type name ;
+
+#define GET_P( type ,name )\
+__declspec(property(get=Get##name))\
+type name ;
+
+#define PUT_P( type ,name )\
+__declspec(property(put=Put##name))\
+type name ;
+
+#define ALL_PROP( type ,name ,get_f ,put_f)\
+__declspec(property(get=get_f,put=put_f))\
+type name ;
+
+#define GET_PROP( type ,name ,get_f)\
+__declspec(property(get=get_f))\
+type name ;
+
+#define PUT_PROP( type ,name ,put_f)\
+__declspec(property(put=put_f))\
+type name ;
+
+#else //_MSC_EXTENSIONS
+/*compiled with other c++ (not msvc) compiler, or without extentions turned on */
+
+#define DECLARE_PROP_CLASS( aclass ) typedef aclass __this_class__ ;
+
+#define ALL_P( type ,name )\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		operator type(){return MyClass().Get##name();} \
+		type operator =(type val){MyClass().Put##name(val);return val;} \
+	} name ;
+
+#define GET_P( type ,name )\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		operator type(){return MyClass().Get##name();} \
+	} name ;
+
+#define PUT_P( type ,name )\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		type operator =(type val){MyClass().Put##name(val);return val;} \
+	} name ;
+
+#define ALL_PROP( type ,name ,get_f ,put_f)\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		operator type(){return MyClass().get_f();} \
+		type operator =(type val){MyClass().put_f(val);return val;} \
+	} name ;
+
+#define GET_PROP( type ,name ,get_f)\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		operator type(){return MyClass().get_f();} \
+	} name ;
+
+#define PUT_PROP( type ,name ,put_f)\
+	class prop_func_##name{public: \
+		__this_class__& MyClass() \
+		{   char* p = (char*)this - offsetof(__this_class__,name) ; \
+			return *((__this_class__*)p) ; \
+		} \
+		type operator =(type val){MyClass().put_f(val);return val;} \
+	} name ;
+
+#endif //_MSC_EXTENSIONS
+
+/*
+Implementation notes:
+1)
+  the trick is in the MyClass() member of each property. it will calculate
+  the containing class address from its own (this) address.
+  Since properties are size less - [Q] what will be the offset of such a property?
+
+  Yes you guest right! always 0. where ever it will be declared inside the class and
+  as many as there are. So in effect above can Just be: "return this;".
+  and the all offset-of warnings can be avoided. Now, not that I think that any compiler
+  on any imaginable machine will ever produce a different code. Its Just that I do
+  Imagine a long class hierarchy that have special properties with none zero size.
+  So I'll leave the code as is. It is clearer this way and the optimizer will always
+  remove the -0 operation. So it is only for us programmers.
+
+2)
+  Originally I have tried to keep the __declspec( property (get=xxx,put=yyy) ) syntax
+  but since I absolutely needed a macro, and macros can not be overloaded
+  the only close syntax I could achieve was
+  __declspec( property ((get=xxx,put=yyy)) ) with double brackets on the inside. And I do
+  need the type inside the macro - something like:
+  __declspec( property<type_name> ((get=xxx,put=yyy)) )
+  Since code had to be changed any way (and it is more complicated) I did it as above.
+
+[Q] Student exercise:
+    Original ms-extension will also let you define an Array of properties where the index
+    of the array is supplied as parameter to the function member.
+
+Example:
+       __declspec( property (get=GetArray) )
+       double Array[117] ;
+       double GetArray(size_t  index) ;
+       ...
+       double f = Foo.Array[17] ;
+How would you extend the above to support such syntax?
+(When I ever see such code used I'll supply a fix)
+*/
+
+#endif //__pretty_com_h__
--- /dev/null	1970-01-01 02:00:00.000000000 +0200
+++ include/wine/uuidof.h	2004-02-09 14:55:24.000000000 +0200
@@ -0,0 +1,145 @@
+/*
+ * Description:
+ *
+ * __decelspec(uuid()) and __uuidof are Microsoft extensions to the C++ compiler that lets you attach
+ * a GUID (128 bit number) to a class/struct and than retrieve it by the use of __uuidof
+ *
+ * below code tries to do that.
+ * any code using __uuidof does not change and expected run time is identical to MSVC.
+ * declareations of the uuid has to change. There are two alternatives.
+ * 1) Leave __declspec(uuid(...)) has is. Which is #defined to nothing in wine. Than
+      collect all uuid classes used in your project into one .CPP file
+      and use the MAKE_UUIDOF??? macros to define them.
+	  (other wise the linker will complain)
+ * 2) Use the pretty_com.pl script to change all __declspec(uuid(...)) to the __decelspec_uuid2(...,InterfaceName)
+      macro. That will do a similar thing to the above but can survive in an header.
+	  (or change these declarations manually)
+
+ * Copyright (C) the Wine project
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef WINE_UUIDOF_H_
+#define WINE_UUIDOF_H_
+
+#if defined( __cplusplus ) && \
+	!defined ( _WINE_NO_UUIDOF_ ) && \
+	!defined (_MSC_VER) && \
+	defined (__GNUC__)
+
+extern "C++" {
+
+/*
+	at first I tried to use macros but ATL, who all this work was for,
+	uses __uuidof in template parametrization, which forces me to use template too.
+	Any way with templates the solution becomes trivial, much simpler
+	than macros. (the ones I had) please send comments to boaz at hishome.net
+	I would love to talk about it.
+*/
+template< class T>
+struct hold_uuidof
+{
+	static GUID __IID ;
+};
+
+} /*extern C++*/
+
+/*
+	this is a nice one. In MSVC++ u can do:
+	__uuidof(Foo) __uuidof(pointer2Foo) __uuidof(refranceofFoo)
+	and __uuidof(classAFoo). The GCC typeof() will take care of that
+	(get it: use one's extension to implement another)
+*/
+#define __uuidof( Q ) hold_uuidof< typeof(Q) >::__IID
+
+/*
+	use this macro to assosiate a guid to a class/struct.
+*/
+#define MAKE_UUIDOF_ID( class ,IID ) \
+	template<> \
+	GUID hold_uuidof<class>::__IID = IID;
+
+/*
+	This one is the same as above but:
+	presupposes an IID_Interface was already defined
+*/
+#define MAKE_UUIDOF( class ) \
+	MAKE_UUIDOF_ID(class, IID_##class)
+
+
+/*
+	[Q] why add more macros to the mess?
+
+	uuid uses a registry notation of the form:
+	"12345678-1234-1234-1234-123456789ABC"
+
+	the classic DEFINE_GUID will use
+(IID_NAME ,0x12345678, 0x1234, 0x1234, 0x12,0x34, 0x12,0x34,0x56,0x78,0x9A,0xBC);
+
+	it was easier for me to write a pearl script (see pretty_com.pl) and is more readable
+	if it was of the form:
+	( 0x12345678, 0x1234, 0x1234, 0x1234, 0x123456789ABCLL, class )
+
+	to add to all the mess Microsoft MIDL compiler will use 2 other macros
+	DECLSPEC_UUID(x) MIDL_INTERFACE(x) which are the same only the later imposes
+	a struct definition. They expect a registry notation as uuid above.
+	Wine steers away from these macros by defining them to nothing.
+
+	pretty_com.pl will translate all __declspec( uuid(X) ) instances to __declspec_uuid2(x,InterfaceName)
+	defined below.
+
+	An alternative to __declspec_uuid2 and pretty_com.pl can be to use below MAKE_XXX macros
+
+	What is MinGW-gcc position on all this?
+
+*/
+
+#include <pshpack1.h>
+struct betterguid{
+    unsigned long  Data1;
+    unsigned short Data2;
+    unsigned short Data3;
+    unsigned short Data4;
+    unsigned short Data5;
+    unsigned long  Data6;
+} ;
+#include <poppack.h>
+
+#define INSTANTIATE_BETTER_GUID(ld1 ,sd2 ,sd3 ,sd4 ,ll5) \
+			{ ld1,sd2,sd3,sd4,ll5>>32, ll5&0xffffffff }
+
+#define DEFINE_IID( ld1 ,sd2 ,sd3 ,sd4 ,ll5 ,class ) \
+__attribute__((weak)) betterguid a##class = INSTANTIATE_BETTER_GUID(ld1 ,sd2 ,sd3 ,sd4 ,ll5) ;\
+EXTERN_C const GUID IID_##class = *((GUID*)&a##class) ;
+
+#define DEFINE_CLSID( ld1 ,sd2 ,sd3 ,sd4 ,sd5 ,ld6 ,class ) \
+ __attribute__((weak)) betterguid a##class = INSTANTIATE_BETTER_GUID(ld1 ,sd2 ,sd3 ,sd4 ,ll5) ;\
+EXTERN_C const GUID CLSID_##class = *((GUID*)&a##class) ;
+
+// make uuidof and IID_ in one shot
+#define MAKE_IID( ld1 ,sd2 ,sd3 ,sd4 ,ll5 ,class ) \
+DEFINE_IID( ld1 ,sd2 ,sd3 ,sd4 ,ll5 ,class ) \
+MAKE_UUIDOF(class) ;
+
+#define __declspec_uuid2(ld1 ,sd2 ,sd3 ,sd4 ,ll5 ,class) 
+
+// below is used by pretty_com.pl
+#define __info_uuid( uuid_string )
+
+
+#endif /*defined( __cplusplus ) && !defined ( _WINE_NO_UUIDOF_ ) && !defined (_MSC_VER)*/
+
+#endif /*ndef WINE_UUIDOF_H_*/
--- /dev/null	1970-01-01 02:00:00.000000000 +0200
+++ tools/pretty_com.pl	2004-02-10 15:47:21.000000000 +0200
@@ -0,0 +1,182 @@
+#!/usr/bin/perl -w
+
+#  pretty_com.pl will try to crudely parse Microsoft C++ COM header files and fix them for compilation
+# under GCC and other standard C++ compilers.
+
+# pretty_com.pl will change any occurrence of _declspec( property (get=,put=) )
+# to the proper macro invocation. An #include directive will be added to pretty_com.h where
+# these macros are defined.
+#
+# pretty_com.pl will also take care of __declspec( uuid(?hhh-hhh?)). It will distinguish between 2 cases:
+# 1) when it is a class declaration. -
+#        It will than change it to a __declspec_uuid2( 0xhhh,0xhhh ) macro compatible with uuidof.h header file.
+# 2) when it is just a forward declaration. -
+#        It will change it to a __info_uuid(?hhh-hhh?) which is declared to nothing.
+#
+# (see ?pretty_com.h? and ?uuidof.h? for details.)
+
+# Usage: all arguments are filenames to be processed.
+# Contents of "filename" will change. The old file will be saved in "filename.old"
+# any file parsed is reported to stdout with a comment "changed" or "nothing to do"
+# in the second case no .old file was created.
+# [example:]> perl -w pretty_com.pl header1 [header2] ..
+#
+
+# FIXME: Below code is made to cope with code generated by the #import directive of
+# MSVC. I am afraid my scripting skills are very limited and a more robust approach
+# should be used to cope with all variations of the declspec(property()) syntax.
+# mainly it will rely on exactly 1 new-line between the __declspec(property()) and the variable declaration.
+# Please some one with better scripting skills, check the code and remove this FIXME
+# Free Life boaz at electrozaur.com
+
+
+use warnings;
+
+$class_decl = "" ;
+$newuuid = "" ;
+
+# input is in $class_decl - it is the string from "struct" | "class" all the way up to the "{" or ";"
+# output is in $newuuid - comma delimited and 0x appended to each hive.
+# Example:
+#      __declspec(uuid("12345678-1234-1234-1234-123456789ABC")
+#           changes to
+#      0x12345678,0x1234,0x1234,0x1234,0x123456789ABCLL
+sub ExtractUuid
+{
+	$newuuid = $class_decl ;
+
+	if( $newuuid =~ s/^.*__declspec[\s]*\([\s]*uuid[\s]*\([\s]*\"(.*)\"[\s]*\)[\s]*\)[\s]*(\w*)[\s]*.*/0x$1LL,$2/ )
+	{
+		$newuuid =~ s/-/,0x/g ;
+		$newuuid =~ s/\n//g ;
+		$newuuid =~ s/{//g ;
+		$newuuid =~ s/;//g ;
+#		$newuuid = "0x" . $newuuid ;
+		print $newuuid . "\n";
+	}
+}
+
+# input  - reference to Input-File as first param, $_ contains the first line containing the keyword struct|class
+# output -
+#    return:
+#       true - A class declaration was found
+#       false - A forward declaration ending with ";"
+#    $class_decl:
+#       will contain all the class declaration from the key word class|struct up to including
+#       the "{" or ";"
+#    InFile: is positioned pass the "{" | ";"
+
+sub readUntilB
+{
+	$InFile = shift ;
+	$read_lines = "" ;
+	do {
+		if ( $_ =~ /{/ ) {
+			$pos_of_B = index($_ ,"{") ;
+			$offset_from_end =  $pos_of_B - length($_) + 1; # we need a negative number
+			seek( $InFile ,$offset_from_end ,1 ) ;
+			$read_lines .= substr $_ ,0 , ($pos_of_B) + 1;
+			$class_decl = $read_lines ;
+			return 1 ;
+		} elsif ( $_ =~ /;/ ) {
+			$class_decl = $read_lines . $_ ;
+			return 0 ;
+		} else {
+			$read_lines .= $_ ;
+		}
+	}while ( <$InFile> )
+}
+
+foreach $InFileName (@ARGV)
+{
+	open( InFile ,$InFileName) or die "Cant open $InFileName !";
+	print "Proccessing $InFileName - " ;
+
+	$LastInclude = 0 ;
+	$curLine = 0 ;
+	$Has_property = 0 ;
+	$Include_pretty_com = "#include <pretty_com.h>" ;
+
+	#first pass see if anything to do and find a good place for the #include statment
+	# which is after any include but before any uuid or property
+	while( <InFile> )
+	{
+		$curLine += 1 ;
+		if( ! $Has_property ) {
+			$LastInclude = $curLine if(/#include/) ;
+		}
+		$Has_property = 1 if( (/__declspec[\s]*\([\s]*property/) || (/__declspec[\s]*\([\s]*uuid/)) ;
+	}
+
+	if( $Has_property )
+	{
+		$OutFileName = "$InFileName.new" ;
+		open( OutFile,">$OutFileName") or die "Cant open $OutFileName !" ;
+
+		$curLine = 0 ;
+		seek( InFile ,0 ,0 ) ;
+		while( <InFile> )
+		{
+			# if we find class or struct fix that up
+			if( ($_ =~ /struct/) || ($_ =~ /class/) ) {
+    			if( readUntilB(\*InFile) ) {
+					ExtractUuid() ;
+					print OutFile "__declspec_uuid2" . "(" . $newuuid . ")\n" ;
+					$class_decl =~ s/__declspec[\s]*\([\s]*uuid[\s]*\([\s]*"(.*)"[\s]*\)[\s]*\)//;
+					@decl_ = split ':' , $class_decl ;
+					$BaseClassname = pop @decl_ ;
+					$Classpart = pop @decl_ ;
+					if( !$Classpart ) {
+						$Classpart = substr($BaseClassname ,0 ,length($BaseClassname) - 1);
+					}
+					@ClassNameToks = split ' ', $Classpart ;
+					$Classname = pop @ClassNameToks  ;
+
+					print OutFile $class_decl ;
+					print OutFile "\nDECLARE_PROP_CLASS($Classname)" ;
+				} else {
+					ExtractUuid() ;
+					$class_decl =~ s/__declspec[\s]*\([\s]*uuid\((.*)\)\)/__info_uuid($1)/;
+					print OutFile $class_decl ;
+				}
+			# if we find __declspec\(property fix that up
+			} elsif ($_ =~ /__declspec\(property/) {
+				chomp;
+				$decl = $_;
+				chop ($nextline = <InFile>);
+				$nextline =~ s/;//g;
+				@words = split ' ', $nextline;
+				$id = pop @words;
+				$type = join ' ', @words;
+				if (($decl =~ /get=/) and ($decl =~ /put=/)) {
+					print OutFile ("\tALL_P( $type\t, $id );\n");
+				}
+				elsif ($decl =~ /get=/) {
+					print OutFile ("\tGET_P( $type\t, $id );\n");
+				}
+				elsif ($decl =~ /put=/) {
+					print OutFile ("\tPUT_P( $type\t, $id );\n");
+				}
+			# default copy lines to new file - put include in place
+			} else {
+				print OutFile $_ ;
+				$curLine += 1 ;
+				if( $curLine == $LastInclude ){
+					print OutFile $Include_pretty_com ;
+				}
+			}
+		}
+		close(InFile) ;
+		close(OutFile) ;
+
+		# until now Output was done to FileName.new rename orignal file to .old and make new one the file
+#		rename( $InFileName ,"$InFileName.old" ) or print "Cant rename $InFileName to .old\n" ;
+#		rename( $OutFileName ,$InFileName ) or print "Cant rename $OutFileName to $InFileName\n" ;
+
+		print "changed!\n" ;
+	}
+	else {
+		print "nothing to do\n";
+	}
+
+}




More information about the wine-devel mailing list