wpp: Add I/O callbacks [try 2]

Matteo Bruni matteo.mystral at gmail.com
Sun Oct 11 10:07:49 CDT 2009


The same as try 1
[http://www.winehq.org/pipermail/wine-patches/2009-October/079610.html]
but now without the getter/setter functions and with currentfile
variable inside pp_status.
-------------- next part --------------
From d8e602170320f2cdfd5b346e2239d5b69d00cd2c Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Wed, 30 Sep 2009 20:15:38 +0200
Subject: wpp: Add I/O callbacks.

---
 include/wine/wpp.h     |   17 +++++
 libs/wpp/ppl.l         |   70 +++++++++++++++++--
 libs/wpp/ppy.y         |   14 ++--
 libs/wpp/preproc.c     |  182 ++++++++++++++++++++++++++++--------------------
 libs/wpp/wpp.c         |    8 +-
 libs/wpp/wpp_private.h |    4 +-
 6 files changed, 199 insertions(+), 96 deletions(-)

diff --git a/include/wine/wpp.h b/include/wine/wpp.h
index dd341bd..daba277 100644
--- a/include/wine/wpp.h
+++ b/include/wine/wpp.h
@@ -26,6 +26,23 @@
 
 struct wpp_callbacks
 {
+    /* I/O callbacks */
+
+    /* Looks for a file to include, returning the path where it is found */
+    /* parent_name is the directory of the parent source file (for local
+     * includes), includepath is an array of additional include paths */
+    char *(*lookup)( const char *filename, const char *parent_name,
+                     char **include_path, int include_path_count );
+    /* Opens an include file */
+    /* The type param is true if it is a local ("...") include */
+    void *(*open)( const char *filename, int type );
+    /* Closes a previously opened file */
+    void (*close)( void *file );
+    /* Reads buffer from the input */
+    int (*read)( void *file, char *buffer, unsigned int len );
+    /* Writes buffer to the output */
+    void (*write)( const char *buffer, unsigned int len );
+
     /* Error callbacks */
     void (*error)( const char *file, int line, int col, const char *near, const char *msg, va_list ap );
     void (*warning)( const char *file, int line, int col, const char *near, const char *msg, va_list ap );
diff --git a/libs/wpp/ppl.l b/libs/wpp/ppl.l
index 48a6959..05e7af2 100644
--- a/libs/wpp/ppl.l
+++ b/libs/wpp/ppl.l
@@ -178,6 +178,7 @@ ul	[uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
 #define YY_NO_UNISTD_H
 #endif
 
+#include "wine/wpp.h"
 #include "wpp_private.h"
 #include "ppy.tab.h"
 
@@ -205,6 +206,7 @@ ul	[uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
 
 typedef struct bufferstackentry {
 	YY_BUFFER_STATE	bufferstate;	/* Buffer to switch back to */
+	void		*filehandle;    /* Handle to be used with wpp_callbacks->read */
 	pp_entry_t	*define;	/* Points to expanding define or NULL if handling includes */
 	int		line_number;	/* Line that we were handling */
 	int		char_number;	/* The current position on that line */
@@ -298,6 +300,56 @@ include_state_t pp_incl_state =
 
 includelogicentry_t *pp_includelogiclist = NULL;
 
+#define YY_INPUT(buf,result,max_size)					     \
+	{								     \
+		result = wpp_callbacks->read(pp_status.file, buf, max_size); \
+	}
+
+#define BUFFERINITIALCAPACITY 256
+
+void pp_writestring(const char *format, ...)
+{
+	va_list valist;
+	int len;
+	static char *buffer;
+	static int buffercapacity;
+	char *new_buffer;
+
+	if(buffercapacity == 0)
+	{
+		buffer = pp_xmalloc(BUFFERINITIALCAPACITY);
+		if(buffer == NULL)
+			return;
+		buffercapacity = BUFFERINITIALCAPACITY;
+	}
+
+	va_start(valist, format);
+	len = vsnprintf(buffer, buffercapacity,
+			format, valist);
+        /* If the string is longer than buffersize, vsnprintf returns
+         * the string length with glibc >= 2.1, -1 with glibc < 2.1 */
+	while(len > buffercapacity || len < 0)
+	{
+		do
+		{
+			buffercapacity *= 2;
+		} while(len > buffercapacity);
+
+		new_buffer = pp_xrealloc(buffer, buffercapacity);
+		if(new_buffer == NULL)
+		{
+			va_end(valist);
+			return;
+		}
+		buffer = new_buffer;
+		len = vsnprintf(buffer, buffercapacity,
+				format, valist);
+	}
+	va_end(valist);
+
+	wpp_callbacks->write(buffer, len);
+}
+
 %}
 
 /*
@@ -1243,6 +1295,7 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop)
 
 	memset(&bufferstack[bufferstackidx], 0, sizeof(bufferstack[0]));
 	bufferstack[bufferstackidx].bufferstate	= YY_CURRENT_BUFFER;
+	bufferstack[bufferstackidx].filehandle  = pp_status.file;
 	bufferstack[bufferstackidx].define	= ppp;
 	bufferstack[bufferstackidx].line_number	= pp_status.line_number;
 	bufferstack[bufferstackidx].char_number	= pp_status.char_number;
@@ -1284,8 +1337,8 @@ static bufferstackentry_t *pop_buffer(void)
 	{
 		if(!bufferstack[bufferstackidx].should_pop)
 		{
-			fclose(ppy_in);
-			fprintf(ppy_out, "# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
+			wpp_callbacks->close(pp_status.file);
+			pp_writestring("# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
 
 			/* We have EOF, check the include logic */
 			if(pp_incl_state.state == 2 && !pp_incl_state.seen_junk && pp_incl_state.ppp)
@@ -1332,7 +1385,8 @@ static bufferstackentry_t *pop_buffer(void)
 			bufferstack[bufferstackidx].filename,
 			bufferstack[bufferstackidx].should_pop);
 
-        ppy__switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
+	pp_status.file = bufferstack[bufferstackidx].filehandle;
+	ppy__switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
 
 	if(bufferstack[bufferstackidx].should_pop)
 	{
@@ -1499,7 +1553,7 @@ static void put_buffer(const char *s, int len)
 	if(top_macro())
 		add_text_to_macro(s, len);
 	else
-           fwrite(s, 1, len, ppy_out);
+		wpp_callbacks->write(s, len);
 }
 
 
@@ -1513,6 +1567,7 @@ void pp_do_include(char *fname, int type)
 	char *newpath;
 	int n;
 	includelogicentry_t *iep;
+	void *fp;
 
 	if(!fname)
 		return;
@@ -1541,7 +1596,7 @@ void pp_do_include(char *fname, int type)
 	/* Undo the effect of the quotation */
 	fname[n-1] = '\0';
 
-	if((ppy_in = pp_open_include(fname+1, type ? pp_status.input : NULL, &newpath)) == NULL)
+	if((fp = pp_open_include(fname+1, type ? pp_status.input : NULL, &newpath)) == NULL)
 	{
 		ppy_error("Unable to open include file %s", fname+1);
 		return;
@@ -1556,9 +1611,10 @@ void pp_do_include(char *fname, int type)
 	if(pp_status.debug)
 		fprintf(stderr, "pp_do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
                         pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
-        ppy__switch_to_buffer(ppy__create_buffer(ppy_in, YY_BUF_SIZE));
+	pp_status.file = fp;
+	ppy__switch_to_buffer(ppy__create_buffer(NULL, YY_BUF_SIZE));
 
-	fprintf(ppy_out, "# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
+	pp_writestring("# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
 }
 
 /*
diff --git a/libs/wpp/ppy.y b/libs/wpp/ppy.y
index b525e2f..5a63494 100644
--- a/libs/wpp/ppy.y
+++ b/libs/wpp/ppy.y
@@ -279,20 +279,20 @@ preprocessor
 	| tMACRO res_arg allmargs tMACROEND opt_mtexts tNL	{
 		pp_add_macro($1, macro_args, nmacro_args, $5);
 		}
-	| tLINE tSINT tDQSTRING	tNL	{ if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
-	| tGCCLINE tSINT tDQSTRING tNL	{ if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
+	| tLINE tSINT tDQSTRING	tNL	{ if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
+	| tGCCLINE tSINT tDQSTRING tNL	{ if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
 	| tGCCLINE tSINT tDQSTRING tSINT tNL
-		{ if($3) fprintf(ppy_out, "# %d %s %d\n", $2, $3, $4); free($3); }
+		{ if($3) pp_writestring("# %d %s %d\n", $2, $3, $4); free($3); }
 	| tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
-		{ if($3) fprintf(ppy_out, "# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
+		{ if($3) pp_writestring("# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
 	| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT  tNL
-		{ if($3) fprintf(ppy_out, "# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
+		{ if($3) pp_writestring("# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
 	| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
-		{ if($3) fprintf(ppy_out, "# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
+		{ if($3) pp_writestring("# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
 	| tGCCLINE tNL		/* The null-token */
 	| tERROR opt_text tNL	{ ppy_error("#error directive: '%s'", $2); free($2); }
 	| tWARNING opt_text tNL	{ ppy_warning("#warning directive: '%s'", $2); free($2); }
-	| tPRAGMA opt_text tNL	{ fprintf(ppy_out, "#pragma %s\n", $2 ? $2 : ""); free($2); }
+	| tPRAGMA opt_text tNL	{ pp_writestring("#pragma %s\n", $2 ? $2 : ""); free($2); }
 	| tPPIDENT opt_text tNL	{ if(pp_status.pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
         | tRCINCLUDE tRCINCLUDEPATH {
                 if($2)
diff --git a/libs/wpp/preproc.c b/libs/wpp/preproc.c
index 874e54c..2eb3133 100644
--- a/libs/wpp/preproc.c
+++ b/libs/wpp/preproc.c
@@ -115,6 +115,100 @@ char *pp_xstrdup(const char *str)
 	return memcpy(s, str, len);
 }
 
+static char *wpp_default_lookup(const char *name, const char *parent_name,
+                                char **include_path, int include_path_count)
+{
+    char *cpy;
+    char *cptr;
+    char *path;
+    const char *ccptr;
+    int i, fd;
+
+    cpy = pp_xmalloc(strlen(name)+1);
+    if(!cpy)
+        return NULL;
+    cptr = cpy;
+
+    for(ccptr = name; *ccptr; ccptr++)
+    {
+        /* Convert to forward slash */
+        if(*ccptr == '\\') {
+            /* kill double backslash */
+            if(ccptr[1] == '\\')
+                ccptr++;
+            *cptr = '/';
+        }else {
+            *cptr = *ccptr;
+        }
+        cptr++;
+    }
+    *cptr = '\0';
+
+    if(parent_name)
+    {
+        /* Search directory of parent include and then -I path */
+        const char *p;
+
+        if ((p = strrchr( parent_name, '/' ))) p++;
+        else p = parent_name;
+        path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 );
+        if(!path)
+        {
+            free(cpy);
+            return NULL;
+        }
+        memcpy( path, parent_name, p - parent_name );
+        strcpy( path + (p - parent_name), cpy );
+        fd = open( path, O_RDONLY );
+        if (fd != -1)
+        {
+            close( fd );
+            free( cpy );
+            return path;
+        }
+        free( path );
+    }
+    /* Search -I path */
+    for(i = 0; i < include_path_count; i++)
+    {
+        path = pp_xmalloc(strlen(include_path[i]) + strlen(cpy) + 2);
+        if(!path)
+        {
+            free(cpy);
+            return NULL;
+        }
+        strcpy(path, include_path[i]);
+        strcat(path, "/");
+        strcat(path, cpy);
+        fd = open( path, O_RDONLY );
+        if (fd != -1)
+        {
+            close( fd );
+            free( cpy );
+            return path;
+        }
+        free( path );
+    }
+    free( cpy );
+    return NULL;
+}
+
+static void *wpp_default_open(const char *filename, int type) {
+    return fopen(filename,"rt");
+}
+
+static void wpp_default_close(void *file) {
+    fclose(file);
+}
+
+static int wpp_default_read(void *file, char *buffer, unsigned int len){
+    return fread(buffer, 1, len, file);
+}
+
+static void wpp_default_write( const char *buffer, unsigned int len ) {
+    fwrite(buffer, 1, len, ppy_out);
+}
+
 /* Don't comment on the hash, its primitive but functional... */
 static int pphash(const char *str)
 {
@@ -403,88 +497,17 @@ int wpp_add_include_path(const char *path)
 
 char *wpp_find_include(const char *name, const char *parent_name)
 {
-    char *cpy;
-    char *cptr;
-    char *path;
-    const char *ccptr;
-    int i, fd;
-
-    cpy = pp_xmalloc(strlen(name)+1);
-    if(!cpy)
-        return NULL;
-    cptr = cpy;
-
-    for(ccptr = name; *ccptr; ccptr++)
-    {
-        /* Convert to forward slash */
-        if(*ccptr == '\\') {
-            /* kill double backslash */
-            if(ccptr[1] == '\\')
-                ccptr++;
-            *cptr = '/';
-        }else {
-            *cptr = *ccptr;
-        }
-        cptr++;
-    }
-    *cptr = '\0';
-
-    if(parent_name)
-    {
-        /* Search directory of parent include and then -I path */
-        const char *p;
-
-        if ((p = strrchr( parent_name, '/' ))) p++;
-        else p = parent_name;
-        path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 );
-        if(!path)
-        {
-            free(cpy);
-            return NULL;
-        }
-        memcpy( path, parent_name, p - parent_name );
-        strcpy( path + (p - parent_name), cpy );
-        fd = open( path, O_RDONLY );
-        if (fd != -1)
-        {
-            close( fd );
-            free( cpy );
-            return path;
-        }
-        free( path );
-    }
-    /* Search -I path */
-    for(i = 0; i < nincludepath; i++)
-    {
-        path = pp_xmalloc(strlen(includepath[i]) + strlen(cpy) + 2);
-        if(!path)
-        {
-            free(cpy);
-            return NULL;
-        }
-        strcpy(path, includepath[i]);
-        strcat(path, "/");
-        strcat(path, cpy);
-        fd = open( path, O_RDONLY );
-        if (fd != -1)
-        {
-            close( fd );
-            free( cpy );
-            return path;
-        }
-        free( path );
-    }
-    free( cpy );
-    return NULL;
+    return wpp_default_lookup(name, parent_name, includepath, nincludepath);
 }
 
-FILE *pp_open_include(const char *name, const char *parent_name, char **newpath)
+void *pp_open_include(const char *name, const char *parent_name, char **newpath)
 {
     char *path;
-    FILE *fp;
+    void *fp;
 
-    if (!(path = wpp_find_include( name, parent_name ))) return NULL;
-    fp = fopen(path, "rt");
+    if (!(path = wpp_callbacks->lookup(name, parent_name, includepath,
+                                       nincludepath))) return NULL;
+    fp = wpp_callbacks->open(path, parent_name == NULL ? 1 : 0);
 
     if (fp)
     {
@@ -687,6 +710,11 @@ static void wpp_default_warning(const char *file, int line, int col, const char
 
 static const struct wpp_callbacks default_callbacks =
 {
+	wpp_default_lookup,
+	wpp_default_open,
+	wpp_default_close,
+	wpp_default_read,
+	wpp_default_write,
 	wpp_default_error,
 	wpp_default_warning,
 };
diff --git a/libs/wpp/wpp.c b/libs/wpp/wpp.c
index afca1bb..935bd49 100644
--- a/libs/wpp/wpp.c
+++ b/libs/wpp/wpp.c
@@ -176,8 +176,8 @@ int wpp_parse( const char *input, FILE *output )
     add_cmdline_defines();
     add_special_defines();
 
-    if (!input) ppy_in = stdin;
-    else if (!(ppy_in = fopen(input, "rt")))
+    if (!input) pp_status.file = stdin;
+    else if (!(pp_status.file = wpp_callbacks->open(input, 1)))
     {
         ppy_error("Could not open %s\n", input);
         return 2;
@@ -186,13 +186,13 @@ int wpp_parse( const char *input, FILE *output )
     pp_status.input = input;
 
     ppy_out = output;
-    fprintf(ppy_out, "# 1 \"%s\" 1\n", input ? input : "");
+    pp_writestring("# 1 \"%s\" 1\n", input ? input : "");
 
     ret = ppy_parse();
     /* If there were errors during processing, return an error code */
     if(!ret && pp_status.state) ret = pp_status.state;
 
-    if (input) fclose(ppy_in);
+    if (input) wpp_callbacks->close(pp_status.file);
     pp_pop_define_state();
     return ret;
 }
diff --git a/libs/wpp/wpp_private.h b/libs/wpp/wpp_private.h
index e082213..d737495 100644
--- a/libs/wpp/wpp_private.h
+++ b/libs/wpp/wpp_private.h
@@ -207,7 +207,7 @@ void pp_pop_define_state(void);
 pp_entry_t *pp_add_define(char *def, char *text);
 pp_entry_t *pp_add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp);
 void pp_del_define(const char *name);
-FILE *pp_open_include(const char *name, const char *parent_name, char **newpath);
+void *pp_open_include(const char *name, const char *parent_name, char **newpath);
 void pp_push_if(pp_if_state_t s);
 void pp_next_if_state(int);
 pp_if_state_t pp_pop_if(void);
@@ -229,6 +229,7 @@ void pp_internal_error(const char *file, int line, const char *s, ...) __attribu
 struct pp_status
 {
     const char *input;  /* current input file name */
+    void *file;         /* current input file descriptor */
     int line_number;    /* current line number */
     int char_number;    /* current char number in line */
     int state;          /* current error state */
@@ -253,6 +254,7 @@ void pp_do_include(char *fname, int type);
 void pp_push_ignore_state(void);
 void pp_pop_ignore_state(void);
 
+void pp_writestring(const char *format, ...);
 
 /*
  * From ppy.y
-- 
1.6.3.3


More information about the wine-patches mailing list