THRIFT-3709 Comment syntax can produce broken code
Client: Compiler(general)
Patch: Jens Geyer
diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj
index 6f5396b..a2548d4 100644
--- a/compiler/cpp/compiler.vcxproj
+++ b/compiler/cpp/compiler.vcxproj
@@ -50,7 +50,7 @@
     <ClInclude Include="src\windows\version.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="src\audit\t_audit.cpp"/>
+    <ClCompile Include="src\audit\t_audit.cpp" />
     <ClCompile Include="src\generate\t_as3_generator.cc" />
     <ClCompile Include="src\generate\t_cocoa_generator.cc" />
     <ClCompile Include="src\generate\t_cpp_generator.cc" />
@@ -77,7 +77,7 @@
     <ClCompile Include="src\generate\t_py_generator.cc" />
     <ClCompile Include="src\generate\t_rb_generator.cc" />
     <ClCompile Include="src\generate\t_st_generator.cc" />
-	<ClCompile Include="src\generate\t_swift_generator.cc" />
+    <ClCompile Include="src\generate\t_swift_generator.cc" />
     <ClCompile Include="src\generate\t_xml_generator.cc" />
     <ClCompile Include="src\generate\t_xsd_generator.cc" />
     <ClCompile Include="src\main.cc" />
diff --git a/compiler/cpp/compiler.vcxproj.filters b/compiler/cpp/compiler.vcxproj.filters
index 6e41afb..9b14bbf 100644
--- a/compiler/cpp/compiler.vcxproj.filters
+++ b/compiler/cpp/compiler.vcxproj.filters
@@ -16,7 +16,6 @@
     </ClInclude>
     <ClInclude Include="src\globals.h" />
     <ClInclude Include="src\main.h" />
-    <ClInclude Include="src\md5.h" />
     <ClInclude Include="src\parse\t_base_type.h">
       <Filter>parse</Filter>
     </ClInclude>
@@ -171,8 +170,10 @@
     <ClCompile Include="src\generate\t_xsd_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
+    <ClCompile Include="src\generate\t_xml_generator.cc">
+      <Filter>generate</Filter>
+    </ClCompile>
     <ClCompile Include="src\main.cc" />
-    <ClCompile Include="src\md5.c" />
     <ClCompile Include="src\parse\parse.cc">
       <Filter>parse</Filter>
     </ClCompile>
diff --git a/compiler/cpp/src/thriftl.ll b/compiler/cpp/src/thriftl.ll
index 93ebc8e..5c3187d 100644
--- a/compiler/cpp/src/thriftl.ll
+++ b/compiler/cpp/src/thriftl.ll
@@ -111,8 +111,8 @@
 identifier    ([a-zA-Z_](\.[a-zA-Z_0-9]|[a-zA-Z_0-9])*)
 whitespace    ([ \t\r\n]*)
 sillycomm     ("/*""*"*"*/")
-multicomm     ("/*"[^*]([^*]|"*"[^/])*"*/")
-doctext       ("/**"([^*]|"*"[^/])*"*/")
+multicm_begin ("/*")
+doctext_begin ("/**")
 comment       ("//"[^\n]*)
 unixcomment   ("#"[^\n]*)
 symbol        ([:;\,\{\}\(\)\=<>\[\]])
@@ -122,7 +122,75 @@
 
 {whitespace}         { /* do nothing */                 }
 {sillycomm}          { /* do nothing */                 }
-{multicomm}          { /* do nothing */                 }
+
+{doctext_begin} {
+  std::string parsed("/**");
+  int state = 0;  // 0 = normal, 1 = "*" seen, "*/" seen
+  while(state < 2)
+  {
+    int ch = yyinput();
+    parsed.push_back(ch);
+    switch (ch) {
+      case EOF:
+        yyerror("Unexpected end of file in doc-comment at %d\n", yylineno);
+        exit(1);
+      case '*':
+        state = 1;
+        break;
+      case '/':
+        state = (state == 1) ? 2 : 0;
+        break;
+      default:
+        state = 0;
+        break;
+    }
+  }
+  pdebug("doctext = \"%s\"\n",parsed.c_str());
+
+ /* This does not show up in the parse tree. */
+ /* Rather, the parser will grab it out of the global. */
+  if (g_parse_mode == PROGRAM) {
+    clear_doctext();
+    g_doctext = strdup(parsed.c_str() + 3);
+    assert(strlen(g_doctext) >= 2);
+    g_doctext[strlen(g_doctext) - 2] = ' ';
+    g_doctext[strlen(g_doctext) - 1] = '\0';
+    g_doctext = clean_up_doctext(g_doctext);
+    g_doctext_lineno = yylineno;
+    if( (g_program_doctext_candidate == NULL) && (g_program_doctext_status == INVALID)){
+      g_program_doctext_candidate = strdup(g_doctext);
+      g_program_doctext_lineno = g_doctext_lineno;
+      g_program_doctext_status = STILL_CANDIDATE;
+      pdebug("%s","program doctext set to STILL_CANDIDATE");
+    }
+  }
+}
+
+{multicm_begin}  { /* parsed, but thrown away */
+  std::string parsed("/*");
+  int state = 0;  // 0 = normal, 1 = "*" seen, "*/" seen
+  while(state < 2)
+  {
+    int ch = yyinput();
+    parsed.push_back(ch);
+    switch (ch) {
+      case EOF:
+        yyerror("Unexpected end of file in multiline comment at %d\n", yylineno);
+        exit(1);
+      case '*':
+        state = 1;
+        break;
+      case '/':
+        state = (state == 1) ? 2 : 0;
+        break;
+      default:
+        state = 0;
+        break;
+    }
+  }
+  pdebug("multi_comm = \"%s\"\n",parsed.c_str());
+}
+
 {comment}            { /* do nothing */                 }
 {unixcomment}        { /* do nothing */                 }
 
@@ -384,26 +452,6 @@
 }
 
 
-{doctext} {
- /* This does not show up in the parse tree. */
- /* Rather, the parser will grab it out of the global. */
-  if (g_parse_mode == PROGRAM) {
-    clear_doctext();
-    g_doctext = strdup(yytext + 3);
-    assert(strlen(g_doctext) >= 2);
-    g_doctext[strlen(g_doctext) - 2] = ' ';
-    g_doctext[strlen(g_doctext) - 1] = '\0';
-    g_doctext = clean_up_doctext(g_doctext);
-    g_doctext_lineno = yylineno;
-    if( (g_program_doctext_candidate == NULL) && (g_program_doctext_status == INVALID)){
-      g_program_doctext_candidate = strdup(g_doctext);
-      g_program_doctext_lineno = g_doctext_lineno;
-      g_program_doctext_status = STILL_CANDIDATE;
-      pdebug("%s","program doctext set to STILL_CANDIDATE");
-    }
-  }
-}
-
 . {
   unexpected_token(yytext);
 }