@@ -564,6 +564,7 @@ static this()
564564
565565string createModuleName (string filename)
566566{
567+ string ext = extension(filename);
567568 filename = stripExtension(filename);
568569 filename = replace(filename, " \\ " , " /" );
569570 string [] names = split(filename, " /" );
@@ -586,6 +587,8 @@ string createModuleName(string filename)
586587 modname ~= ' .' ;
587588 modname ~= safename;
588589 }
590+ if (ext != " .h" && ext != " " )
591+ modname ~= " _" ~ ext[1 .. $];
589592 return modname;
590593}
591594
@@ -606,13 +609,21 @@ string mapTokenText(Token tok)
606609 return tok.text;
607610}
608611
609- string createMappedTokenListText (TokenList tokList)
612+ string createMappedTokenListText (TokenList tokList, bool map )
610613{
611- string text;
614+ string text, prevtext ;
612615 for (TokenIterator tokIt = tokList.begin(); ! tokIt.atEnd(); ++ tokIt)
613616 {
614617 Token tok = * tokIt;
615- string mapped = mapTokenText(tok);
618+ string mapped = map ? mapTokenText(tok) : tok.text;
619+ if (mapped.length && prevtext.length)
620+ {
621+ char prevch = prevtext[$- 1 ];
622+ char ch = mapped[0 ];
623+ if ((isAlphaNum(ch) || ch == ' _' ) && (isAlphaNum(prevch) || prevch == ' _' ))
624+ mapped = " " ~ mapped;
625+ }
626+ prevtext = mapped;
616627 text ~= tok.pretext ~ mapped;
617628 }
618629 return text;
@@ -1606,6 +1617,40 @@ void patchClassVarInit(Statement stmt)
16061617 }
16071618}
16081619
1620+ void patchSwitchStatement (Statement swstmt)
1621+ {
1622+ ASTIterator swit = swstmt.children.begin() + 1 ; // skip expression
1623+ if (swit.atEnd())
1624+ return ;
1625+ auto stmt = * swit; // compound statement
1626+ bool hasDefault = false ;
1627+ if (stmt.children)
1628+ for (ASTIterator it = stmt.children.begin(); ! it.atEnd(); ++ it)
1629+ if (auto s = cast (Statement)(* it))
1630+ if (s._toktype == Token .Default)
1631+ {
1632+ hasDefault = true ;
1633+ break ;
1634+ }
1635+
1636+ if (! hasDefault)
1637+ {
1638+ auto insertPos = stmt.end - 1 ; // before "}"
1639+ TokenList tokList = new TokenList;
1640+ tokList.append(createToken(insertPos.pretext, " default" , Token .Default, stmt.end.lineno));
1641+ tokList.append(createToken(" " , " :" , Token .Colon, stmt.end.lineno));
1642+ tokList.append(createToken(" " , " break" , Token .Break, stmt.end.lineno));
1643+ tokList.append(createToken(" " , " ;" , Token .Semicolon, stmt.end.lineno));
1644+ auto defstmt = new Statement(Token .Default);
1645+ defstmt.start = tokList.begin();
1646+ defstmt.end = tokList.end();
1647+
1648+ stmt.insertChildBefore(stmt.children.end(), defstmt, tokList, &insertPos);
1649+
1650+ stmt.verify();
1651+ }
1652+ }
1653+
16091654void splitNonSimpleVarList (Declaration decl)
16101655{
16111656 if (decl.children && decl.children.count() > 2 )
@@ -1951,7 +1996,7 @@ void patchDeclType(DeclType dtype)
19511996 // simply add arguments to identifier
19521997 if (dvar2.start.type == Token .Identifier)
19531998 {
1954- string argtext = createMappedTokenListText(tl);
1999+ string argtext = createMappedTokenListText(tl, true );
19552000 dvar2.start.text ~= argtext;
19562001 }
19572002 // bad insert position:
@@ -2051,6 +2096,8 @@ void patchAST(AST ast)
20512096 patchAsm(stmt);
20522097 if (stmt._toktype == Token .Return)
20532098 patchReturnExpressionType(stmt);
2099+ if (stmt._toktype == Token .Switch)
2100+ patchSwitchStatement(stmt);
20542101
20552102 patchClassVarInit(stmt);
20562103 }
@@ -2247,13 +2294,7 @@ class Source
22472294
22482295 string createTokenListText (int pass)
22492296 {
2250- string text;
2251- for (TokenIterator tokIt = _tokenList.begin(); ! tokIt.atEnd(); ++ tokIt)
2252- {
2253- Token tok = * tokIt;
2254- string mapped = pass > 0 ? tok.text : mapTokenText(tok);
2255- text ~= tok.pretext ~ mapped;
2256- }
2297+ string text = createMappedTokenListText(_tokenList, pass <= 0 );
22572298 return text;
22582299 }
22592300
@@ -2678,7 +2719,7 @@ class Cpp2DConverter
26782719 // cannot remove decl immediately, because iterators in iterateTopLevelDeclarations will become invalid
26792720 declsToRemove ~= decl;
26802721
2681- currentSource._ast .verify();
2722+ decl._parent .verify();
26822723 }
26832724
26842725 void moveAllMethods ()
@@ -2795,8 +2836,6 @@ class Cpp2DConverter
27952836 string fname = replace(modname, " ." , " /" );
27962837 if (pass == 0 )
27972838 {
2798- if (ext != " .h" && ext != " " )
2799- fname ~= " _" ~ ext[1 .. $];
28002839 fname ~= " .d" ;
28012840 }
28022841 else
@@ -2996,7 +3035,7 @@ string testDmdGen(string txt, int countRemove = 1, int countNoImpl = 0, TokenLis
29963035
29973036 TokenList tokenList = scanText(txt);
29983037
2999- if (defines is null )
3038+ if (defines ! is null )
30003039 {
30013040 expandPPdefines(tokenList, defines, MixinMode.ExpandDefine);
30023041 rescanPP(tokenList);
@@ -3741,7 +3780,6 @@ unittest
37413780
37423781unittest
37433782{
3744- // force failure
37453783 string txt =
37463784 " #define A 1\n "
37473785 ~ " #define B A\n "
@@ -3750,7 +3788,7 @@ unittest
37503788 ;
37513789 string exp =
37523790 " enum A = 1;\n "
3753- ~ " alias B A ;\n "
3791+ ~ " alias A B ;\n "
37543792 ~ " auto C( )() { return B*B; }\n "
37553793 ~ " auto SQR( ARG1 )(ARG1 a) { return a*a; }\n "
37563794 ;
@@ -3771,13 +3809,77 @@ void cpp2d_test()
37713809 ;
37723810
37733811// PP.expandConditionals["EXP"] = true;
3774- TokenList[string ] defines = [ " EXP" : scanText(" 1" ) ];
37753812
3776- string res = testDmdGen(txt, 0 , 0 , defines );
3813+ string res = testDmdGen(txt, 0 , 0 , null );
37773814 assert (res == exp);
37783815
3816+ TokenList[string ] defines = [ " EXP" : scanText(" 1" ) ];
3817+ string exp2 = " enum WSL = 1; // comment\n " ;
3818+ string res2 = testDmdGen(txt, 0 , 0 , defines);
3819+ assert (res2 == exp2);
3820+
37793821 PP .expandConditionals = PP .expandConditionals.init;
37803822}
37813823
3824+ unittest
3825+ {
3826+ string txt =
3827+ " void foo(int x) {\n "
3828+ ~ " switch(x) {\n "
3829+ ~ " case 0: return;\n "
3830+ ~ " }\n "
3831+ ~ " }\n "
3832+ ;
3833+ string exp =
3834+ " void foo(int x) {\n "
3835+ ~ " switch(x) {\n "
3836+ ~ " case 0: return;\n "
3837+ ~ " default: break;\n "
3838+ ~ " }\n "
3839+ ~ " }\n "
3840+ ;
3841+
3842+ string res = testDmdGen(txt, 0 , 0 );
3843+ assert (res == exp);
3844+ }
3845+
3846+ unittest
3847+ {
3848+ string txt =
3849+ " void foo(int x) {\n "
3850+ ~ " switch(x) {\n "
3851+ ~ " default: break;\n "
3852+ ~ " case 1: return;\n "
3853+ ~ " }\n "
3854+ ~ " }\n "
3855+ ;
3856+ string exp =
3857+ " void foo(int x) {\n "
3858+ ~ " switch(x) {\n "
3859+ ~ " default: break;\n "
3860+ ~ " case 1: return;\n "
3861+ ~ " }\n "
3862+ ~ " }\n "
3863+ ;
3864+
3865+ string res = testDmdGen(txt, 0 , 0 );
3866+ assert (res == exp);
3867+ }
3868+
3869+ unittest
3870+ {
3871+ string rtxt = " case '0' => goto case; case '0'" ;
3872+ PatchRule rule;
3873+ bool rc = C2DIni.parsePatchRule(rule, rtxt);
3874+
3875+ string txt = " switch(x) { case '0': break; }" ;
3876+ auto tokenList = scanText(txt);
3877+ replaceTokenSequence(tokenList, rule.searchTokens, rule.replaceTokens, true );
3878+ string ntxt = tokenListToString(tokenList, true );
3879+
3880+ string exp = " switch(x) { goto case;case'0': break; }" ;
3881+ assert (exp == ntxt);
3882+ }
3883+
37823884version (MAIN)
37833885void main () {}
0 commit comments