PATCH: widl: implement move-if-changed logic

Marcus Meissner meissner at suse.de
Thu Sep 3 06:07:16 CDT 2015


>From d8df64a7261bc0febcdd48d4ed818dc1f36f3471 Mon Sep 17 00:00:00 2001
From: Marcus Meissner <meissner at suse.de>
Date: Thu, 3 Sep 2015 12:11:13 +0200
Subject: [PATCH] widl: implement a move-if-changed logic

This avoids unnecessary rebuilds if the generated code by widl
does not change.
---
 tools/widl/client.c   |  4 ++--
 tools/widl/header.c   |  8 +++----
 tools/widl/proxy.c    |  4 ++--
 tools/widl/register.c |  4 ++--
 tools/widl/server.c   |  4 ++--
 tools/widl/utils.c    | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/widl/utils.h    |  3 +++
 tools/widl/widl.c     |  8 +++----
 8 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 739dba9..63b989d 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -416,7 +416,7 @@ static void write_implicithandledecl(type_t *iface)
 static void init_client(void)
 {
     if (client) return;
-    if (!(client = fopen(client_name, "w")))
+    if (!(client = my_fopen(client_name, "w")))
         error("Could not open %s for output\n", client_name);
 
     print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
@@ -549,5 +549,5 @@ void write_client(const statement_list_t *stmts)
         write_client_routines( stmts );
     }
 
-    fclose(client);
+    my_fclose(client, client_name);
 }
diff --git a/tools/widl/header.c b/tools/widl/header.c
index cb4601e..e57ec4b 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1254,7 +1254,7 @@ void write_local_stubs(const statement_list_t *stmts)
 
   if (!local_stubs_name) return;
 
-  local_stubs = fopen(local_stubs_name, "w");
+  local_stubs = my_fopen(local_stubs_name, "w");
   if (!local_stubs) {
     error("Could not open %s for output\n", local_stubs_name);
     return;
@@ -1265,7 +1265,7 @@ void write_local_stubs(const statement_list_t *stmts)
 
   write_local_stubs_stmts(local_stubs, stmts);
 
-  fclose(local_stubs);
+  my_fclose(local_stubs, local_stubs_name);
 }
 
 static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
@@ -1630,7 +1630,7 @@ void write_header(const statement_list_t *stmts)
 
   if (!do_header) return;
 
-  if(!(header = fopen(header_name, "w"))) {
+  if(!(header = my_fopen(header_name, "w"))) {
     error("Could not open %s for output\n", header_name);
     return;
   }
@@ -1673,5 +1673,5 @@ void write_header(const statement_list_t *stmts)
   end_cplusplus_guard(header);
   fprintf(header, "#endif /* __%s__ */\n", header_token);
 
-  fclose(header);
+  my_fclose(header, header_name);
 }
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 71a8baa..f8ba398 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -83,7 +83,7 @@ static void write_stubdesc(int expr_eval_routines)
 static void init_proxy(const statement_list_t *stmts)
 {
   if (proxy) return;
-  if(!(proxy = fopen(proxy_name, "w")))
+  if(!(proxy = my_fopen(proxy_name, "w")))
     error("Could not open %s for output\n", proxy_name);
   print_proxy( "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
   print_proxy( "\n");
@@ -1033,5 +1033,5 @@ void write_proxies(const statement_list_t *stmts)
       write_proxy_routines( stmts );
   }
 
-  fclose(proxy);
+  my_fclose(proxy, proxy_name);
 }
diff --git a/tools/widl/register.c b/tools/widl/register.c
index 9a4f219..e351b1d 100644
--- a/tools/widl/register.c
+++ b/tools/widl/register.c
@@ -264,11 +264,11 @@ void write_regscript( const statement_list_t *stmts )
     }
     else
     {
-        FILE *f = fopen( regscript_name, "w" );
+        FILE *f = my_fopen( regscript_name, "w" );
         if (!f) error( "Could not open %s for output\n", regscript_name );
         if (fwrite( output_buffer, 1, output_buffer_pos, f ) != output_buffer_pos)
             error( "Failed to write to %s\n", regscript_name );
-        if (fclose( f ))
+        if (my_fclose( f, regscript_name ))
             error( "Failed to write to %s\n", regscript_name );
     }
 }
diff --git a/tools/widl/server.c b/tools/widl/server.c
index 29b5bec..b14d4ce 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -442,7 +442,7 @@ static void init_server(void)
 {
     if (server)
         return;
-    if (!(server = fopen(server_name, "w")))
+    if (!(server = my_fopen(server_name, "w")))
         error("Could not open %s for output\n", server_name);
 
     print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
@@ -565,5 +565,5 @@ void write_server(const statement_list_t *stmts)
         write_server_routines( stmts );
     }
 
-    fclose(server);
+    my_fclose(server, server_name);
 }
diff --git a/tools/widl/utils.c b/tools/widl/utils.c
index 9066887..ee063c0 100644
--- a/tools/widl/utils.c
+++ b/tools/widl/utils.c
@@ -455,3 +455,69 @@ void align_output( unsigned int align )
     memset( output_buffer + output_buffer_pos, 0, size );
     output_buffer_pos += size;
 }
+
+FILE* my_fopen( const char*fn, const char*mode )
+{
+    FILE *f;
+    char *newfn = malloc( strlen( fn ) + strlen( ".new" ) + 1 );
+
+    strcpy( newfn, fn );
+    strcat( newfn, ".new" );
+
+    f = fopen( newfn, mode );
+    free( newfn );
+    return f;
+}
+
+int my_fclose( FILE *f, const char*fn )
+{
+    FILE *f1;
+    struct stat stbuf1,stbuf2;
+    char *newfn = malloc( strlen( fn ) + strlen( ".new" ) + 1 );
+    char buf1[1000], buf2[1000];
+    int ret;
+
+    strcpy( newfn, fn );
+    strcat( newfn, ".new" );
+    ret = fclose( f );
+    if ((stat( fn, &stbuf1 ) == -1) || (stat( newfn, &stbuf2 ) == -1))
+	goto changed;
+
+    if (stbuf1.st_size != stbuf2.st_size)
+        goto changed;
+
+    f = fopen( newfn , "r" );
+    if (!f) goto changed;
+    f1 = fopen( fn, "r" );
+    if (!f1)
+    {
+        fclose( f );
+        goto changed;
+    }
+    while (!feof( f ))
+    {
+	int x;
+	fread( buf1, sizeof( buf1 ), 1, f);
+	fread( buf2, sizeof( buf2 ), 1, f1);
+        if ((x = memcmp( buf1, buf2, sizeof( buf1 ))))
+        {
+            fclose( f1 );
+            fclose( f );
+            goto changed;
+        }
+    }
+    fprintf( stderr, "%s is unchanged, removing.\n", fn);
+    fclose( f1 );
+    fclose( f );
+    unlink( newfn );
+    free( newfn );
+    return ret;
+
+changed:
+    fprintf( stderr,"%s was changed.\n", fn );
+    unlink( fn );
+    if (-1 == rename( newfn, fn ))
+	perror( "rename" );
+    free( newfn );
+    return ret;
+}
diff --git a/tools/widl/utils.h b/tools/widl/utils.h
index ec02fc7..058090a 100644
--- a/tools/widl/utils.h
+++ b/tools/widl/utils.h
@@ -69,6 +69,9 @@ 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 FILE* my_fopen(const char*fn, const char*mode);
+extern int my_fclose(FILE*f, const char*fn);
+
 /* typelibs expect the minor version to be stored in the higher bits and
  * major to be stored in the lower bits */
 #define MAKEVERSION(major, minor) ((((minor) & 0xffff) << 16) | ((major) & 0xffff))
diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index a38f917..6b369d3 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -356,7 +356,7 @@ static void write_dlldata_list(struct list *filenames, int define_proxy_delegati
   FILE *dlldata;
   filename_node_t *node;
 
-  dlldata = fopen(dlldata_name, "w");
+  dlldata = my_fopen(dlldata_name, "w");
   if (!dlldata)
     error("couldn't open %s: %s\n", dlldata_name, strerror(errno));
 
@@ -380,7 +380,7 @@ static void write_dlldata_list(struct list *filenames, int define_proxy_delegati
 
   fprintf(dlldata, "DLLDATA_ROUTINES(aProxyFileList, GET_DLL_CLSID)\n\n");
   end_cplusplus_guard(dlldata);
-  fclose(dlldata);
+  my_fclose(dlldata, dlldata_name);
 }
 
 static char *eat_space(char *s)
@@ -496,7 +496,7 @@ void write_id_data(const statement_list_t *stmts)
 {
   if (!do_idfile) return;
 
-  idfile = fopen(idfile_name, "w");
+  idfile = my_fopen(idfile_name, "w");
   if (! idfile) {
     error("Could not open %s for output\n", idfile_name);
     return;
@@ -534,7 +534,7 @@ void write_id_data(const statement_list_t *stmts)
   end_cplusplus_guard(idfile);
   fprintf(idfile, "#undef MIDL_DEFINE_GUID\n" );
 
-  fclose(idfile);
+  my_fclose(idfile, idfile_name);
 }
 
 int main(int argc,char *argv[])



More information about the wine-patches mailing list