We now use a hack on Win32 that redirects stderr to a GUI thread that
authorThomas Lopatic <thomas@lopatic.de>
Sun, 21 Nov 2004 17:10:28 +0000 (17:10 +0000)
committerThomas Lopatic <thomas@lopatic.de>
Sun, 21 Nov 2004 17:10:28 +0000 (17:10 +0000)
displays stderr line by line in dialog boxes. In this way the GUI is able
to display the parser's error messages. Moreover, the parser now does not
exit() on an error, but returns -1 or NULL instead. Otherwise the GUI
would simply go away on a parse error.

gui/win32/Frontend.ncb
gui/win32/Frontend.opt
gui/win32/Main/Frontend.cpp
gui/win32/Main/Frontend.h
gui/win32/Main/olsrd_cfgparser.lib
src/cfgparser/Makefile
src/cfgparser/link.def
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/version-script.txt

index 13f2b0a..edf10ee 100644 (file)
Binary files a/gui/win32/Frontend.ncb and b/gui/win32/Frontend.ncb differ
index 7ce4063..5f18f49 100644 (file)
Binary files a/gui/win32/Frontend.opt and b/gui/win32/Frontend.opt differ
index b8bb74b..29eacb7 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact\r
  * the copyright holders.\r
  *\r
- * $Id: Frontend.cpp,v 1.5 2004/11/21 02:06:56 tlopatic Exp $\r
+ * $Id: Frontend.cpp,v 1.6 2004/11/21 17:10:27 tlopatic Exp $\r
  */\r
 \r
 #include "stdafx.h"\r
@@ -183,7 +183,115 @@ BOOL CFrontendApp::InitInstance()
                }\r
        }\r
 \r
+       RedirectStdHandles();\r
+\r
        dlg.DoModal();\r
 \r
        return FALSE;\r
 }\r
+\r
+unsigned int CFrontendApp::RedirectThreadFunc(void)\r
+{\r
+       char Buff[1000];\r
+       int Len;\r
+       int Left, Right;\r
+       CString Line;\r
+       CString Int;\r
+\r
+       while (::ReadFile(OutRead, Buff, sizeof (Buff) - 1, (unsigned long *)&Len, NULL))\r
+       {\r
+               if (Len == 0)\r
+                       break;\r
+\r
+               Left = 0;\r
+\r
+               for (Right = 0; Right < Len; Right++)\r
+               {\r
+                       if (Buff[Right] != 13)\r
+                               Buff[Left++] = Buff[Right];\r
+               }\r
+\r
+               Len = Left;\r
+\r
+               Left = 0;\r
+\r
+               for (Right = 0; Right < Len; Right++)\r
+               {\r
+                       if (Buff[Right] == 10)\r
+                       {\r
+                               Buff[Right] = 0;\r
+                               Line += (Buff + Left);\r
+\r
+                               AfxMessageBox(Line);\r
+\r
+                               Line.Empty();\r
+\r
+                               Left = Right + 1;\r
+                       }\r
+               }\r
+\r
+               Buff[Right] = 0;\r
+               Line += (Buff + Left);\r
+       }\r
+\r
+       AfxEndThread(0);\r
+       return 0;\r
+}\r
+\r
+static unsigned int RedirectThreadStub(void *Arg)\r
+{\r
+       class CFrontendApp *This;\r
+\r
+       This = (class CFrontendApp *)Arg;\r
+\r
+       return This->RedirectThreadFunc();\r
+}\r
+\r
+struct IoInfo\r
+{\r
+       HANDLE Hand;\r
+       unsigned char Attr;\r
+       char Buff;\r
+#if defined _MT\r
+       int Flag;\r
+       CRITICAL_SECTION Lock;\r
+#endif\r
+};\r
+\r
+extern "C" struct IoInfo *__pioinfo[];\r
+\r
+extern "C" void win32_stdio_hack(unsigned int handle);\r
+\r
+int CFrontendApp::RedirectStdHandles(void)\r
+{\r
+       SECURITY_ATTRIBUTES SecAttr;\r
+       HANDLE OutWrite;\r
+       struct IoInfo *Info;\r
+\r
+       SecAttr.nLength = sizeof (SECURITY_ATTRIBUTES);\r
+       SecAttr.lpSecurityDescriptor = NULL;\r
+       SecAttr.bInheritHandle = TRUE;\r
+\r
+       if (!::CreatePipe(&OutRead, &OutWrite, &SecAttr, 0))\r
+       {\r
+               AfxMessageBox("Cannot create stdout pipe.");\r
+               return -1;\r
+       }\r
+\r
+       AfxBeginThread(RedirectThreadStub, (void *)this);\r
+\r
+       Info = __pioinfo[0];\r
+\r
+       // Info[1].Hand = OutWrite;\r
+       // Info[1].Attr = 0x89; // FOPEN | FTEXT | FPIPE;\r
+\r
+       Info[2].Hand = OutWrite;\r
+       Info[2].Attr = 0x89;\r
+\r
+       // stdout->_file = 1;\r
+       stderr->_file = 2;\r
+\r
+       win32_stdio_hack((unsigned int)OutWrite);\r
+\r
+       return 0;\r
+}\r
index 7290943..a67f751 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact\r
  * the copyright holders.\r
  *\r
- * $Id: Frontend.h,v 1.3 2004/11/21 01:21:10 tlopatic Exp $\r
+ * $Id: Frontend.h,v 1.4 2004/11/21 17:10:27 tlopatic Exp $\r
  */\r
 \r
 #if !defined(AFX_FRONTEND_H__8033A41F_6FDC_4054_A582_AB7B6AC5EEAE__INCLUDED_)\r
@@ -57,6 +57,11 @@ class CFrontendApp : public CWinApp
 public:\r
        CFrontendApp();\r
 \r
+       int RedirectStdHandles(void);\r
+       unsigned int RedirectThreadFunc(void);\r
+\r
+       HANDLE OutRead;\r
+\r
        //{{AFX_VIRTUAL(CFrontendApp)\r
        public:\r
        virtual BOOL InitInstance();\r
index b1900b9..612073e 100755 (executable)
Binary files a/gui/win32/Main/olsrd_cfgparser.lib and b/gui/win32/Main/olsrd_cfgparser.lib differ
index ad002bf..c05a7dd 100644 (file)
@@ -36,7 +36,7 @@
 # to the projcet. For more information see the website or contact
 # the copyright holders.
 #
-# $Id: Makefile,v 1.8 2004/11/20 23:57:32 kattemat Exp $
+# $Id: Makefile,v 1.9 2004/11/21 17:10:27 tlopatic Exp $
 
 
 
@@ -51,7 +51,7 @@ ifeq ($(OS), win32)
 LIBNAME ?=     olsrd_cfgparser.dll
 BINNAME ?=     olsrd_cfgparser.exe
 
-PORT_CFLAGS =  -mno-cygwin -I../win32
+PORT_CFLAGS =  -mno-cygwin -I../win32 -DWIN32_STDIO_HACK
 PORT_LDFLAGS = -mno-cygwin
 PORT_OBJS =    ../win32/compat.o
 PORT_LIBS =    -lws2_32
index 59583df..a19a967 100644 (file)
@@ -8,3 +8,4 @@ EXPORTS
        olsrd_cnf_malloc
        olsrd_cnf_free
         olsrd_sanity_check_cnf
+       win32_stdio_hack
index 0ae26b8..bf9c8bc 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: olsrd_conf.c,v 1.27 2004/11/21 10:52:16 kattemat Exp $
+ * $Id: olsrd_conf.c,v 1.28 2004/11/21 17:10:28 tlopatic Exp $
  */
 
 
@@ -169,7 +169,7 @@ olsrd_parse_cnf(const char *filename)
     {
       fclose(yyin);
       olsrd_free_cnf(cnf);
-      exit(0);
+      return NULL;
     }
   
   fclose(yyin);
@@ -470,14 +470,14 @@ get_default_if_config()
   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_SITE_LOCAL, &in6) < 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_SITE_LOCAL);
-      exit(EXIT_FAILURE);
+      return NULL;
     }
   memcpy(&io->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
 
   if(inet_pton(AF_INET6, OLSR_IPV6_MCAST_GLOBAL, &in6) < 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", OLSR_IPV6_MCAST_GLOBAL);
-      exit(EXIT_FAILURE);
+      return NULL;
     }
   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
 
@@ -916,3 +916,38 @@ void olsrd_cnf_free(void *addr)
 {
   free(addr);
 }
+
+#if defined WIN32_STDIO_HACK
+struct ioinfo
+{
+       unsigned int handle;
+       unsigned char attr;
+       char buff;
+       int flag;
+       CRITICAL_SECTION lock;
+};
+
+void win32_stdio_hack(unsigned int handle)
+{
+  HMODULE lib;
+  struct ioinfo **info;
+
+  lib = LoadLibrary("msvcrt.dll");
+
+  info = (struct ioinfo **)GetProcAddress(lib, "__pioinfo");
+
+  // (*info)[1].handle = handle;
+  // (*info)[1].attr = 0x89; // FOPEN | FTEXT | FPIPE;
+
+  (*info)[2].handle = handle;
+  (*info)[2].attr = 0x89;
+
+  // stdout->_file = 1;
+  stderr->_file = 2;
+
+  // setbuf(stdout, NULL);
+  setbuf(stderr, NULL);
+}
+#else
+void win32_stdio_hack(unsigned int handle) {}
+#endif
index 8f9dec2..c16bc70 100644 (file)
@@ -38,7 +38,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: oparse.y,v 1.20 2004/11/21 10:52:16 kattemat Exp $
+ * $Id: oparse.y,v 1.21 2004/11/21 17:10:28 tlopatic Exp $
  */
 
 
@@ -239,7 +239,7 @@ ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
   if(inet_aton($2->string, &in) == 0)
     {
       fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
 
   ipch = malloc(sizeof(struct ipc_host));
@@ -264,13 +264,13 @@ ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
   if(inet_aton($2->string, &in1) == 0)
     {
       fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
 
   if(inet_aton($3->string, &in2) == 0)
     {
       fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
 
   ipcn = malloc(sizeof(struct ipc_net));
@@ -297,7 +297,7 @@ isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
   if(inet_aton($2->string, &in) == 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
 
   cnf->interfaces->cnf->ipv4_broadcast.v4 = in.s_addr;
@@ -327,7 +327,7 @@ isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
   memcpy(&cnf->interfaces->cnf->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
 
@@ -347,7 +347,7 @@ isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
   memcpy(&cnf->interfaces->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
 
@@ -458,13 +458,13 @@ ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
   if(inet_aton($1->string, &in) == 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
   h->net.v4 = in.s_addr;
   if(inet_aton($2->string, &in) == 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
   h->netmask.v4 = in.s_addr;
   /* Queue */
@@ -494,14 +494,14 @@ ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
     {
       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
-      exit(EXIT_FAILURE);
+      return -1;
     }
   memcpy(&h->net, &in6, sizeof(struct in6_addr));
 
   if(($2->integer < 0) || ($2->integer > 128))
     {
       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
-      exit(EXIT_FAILURE);
+      return -1;
     }
 
   h->prefix_len = $2->integer;
index 0c4aac1..04f1cbc 100644 (file)
@@ -10,6 +10,7 @@ VERS_1.0
     olsrd_cnf_malloc;
     olsrd_cnf_free;
     olsrd_sanity_check_cnf;
+    win32_stdio_hack;
   local:
     *;
 };