CE Editor Parser.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. namespace Edit{
  5. /******************************************************************************/
  6. void CodeEditor::parseHeaderEx(Str h, C Str &parent_path, Bool try_system, Memc<Token> &dest, Memc<Macro> &macros, Memc<SymbolPtr> &usings, Bool ee, Memc<PrepCond> &prep_if)
  7. {
  8. Source *s=null;
  9. if(FullPath(h))s=getSource(h);else
  10. {
  11. if(try_system)
  12. // TODO: temporarily don't use system headers (too slow, not fully supported, and pollute the global namespace)
  13. if(0)
  14. {
  15. Str sdk_path=GetRegStr(RKG_LOCAL_MACHINE, "Software/Microsoft/Microsoft SDKs/Windows/v6.0A/InstallationFolder"); if(sdk_path.is())sdk_path.tailSlash(true)+="Include";
  16. Str vc_path=vs_path; if(vc_path.is())vc_path.tailSlash(true)+="VC\\include";
  17. if(!s && sdk_path.is()){Str t=sdk_path+'\\'+h; if(s=getSource(t))h=t;}
  18. if(!s && vc_path.is()){Str t= vc_path+'\\'+h; if(s=getSource(t))h=t;}
  19. }
  20. if(!s)
  21. {
  22. if(parent_path.is()){Str t=NormalizePath(parent_path+'\\'+h); if(s=getSource(t))h=t;}else // try relative to parent
  23. {
  24. // try relative to build
  25. Str build_path, build_project_name; if(getBuildPath(build_path, build_project_name)){Str t=NormalizePath(build_path+h); if(s=getSource(t))h=t;}
  26. }
  27. }
  28. }
  29. if(s)
  30. {
  31. if(s->recursive>16)
  32. {
  33. // TODO: display error for Header Recursiveness
  34. DEBUG_ASSERT(false, "Header Recursive too much");
  35. }else
  36. {
  37. s->recursive++;
  38. s->header=true;
  39. if(ee)
  40. {
  41. s->ee_header=s->Const=true;
  42. // replace STRUCT, STRUCT_PRIVATE
  43. FREPAD(l, s->lines)
  44. {
  45. Line &line=s->lines[l];
  46. if(!line.preproc)
  47. {
  48. Int base;
  49. if((base=TextPosI(line, "STRUCT(", true, true))>=0)
  50. {
  51. line.remove(base, 7).insert(base, "struct ");
  52. Int i=TextPosI(line()+base, ','); if(i>=0){i+=base; line.remove(i).insert(i, ":", TOKEN_OPERATOR);}
  53. i=TextPosI(line()+base, ')'); if(i>=0){i+=base; line.remove(i);}
  54. line.setType(line.starts_with_comment, line.starts_with_preproc);
  55. if(InRange(l+1, s->lines)){Line &line=s->lines[l+1]; line=Replace(line, "//{", "{"); line.setType(line.starts_with_comment, line.starts_with_preproc);}
  56. }else
  57. if((base=TextPosI(line, "STRUCT_PRIVATE(", true, true))>=0)
  58. {
  59. line.remove(base, 15).insert(base, "struct ");
  60. Int i=TextPosI(line()+base, ','); if(i>=0){i+=base; line.remove(i).insert(i, ":", TOKEN_OPERATOR).insert(i+1, " ", TOKEN_NONE).insert(i+2, "private", TOKEN_KEYWORD);}
  61. i=TextPosI(line()+base, ')'); if(i>=0){i+=base; line.remove(i);}
  62. line.setType(line.starts_with_comment, line.starts_with_preproc);
  63. if(InRange(l+1, s->lines)){Line &line=s->lines[l+1]; line=Replace(line, "//{", "{"); line.setType(line.starts_with_comment, line.starts_with_preproc);}
  64. }
  65. }else
  66. {
  67. if(Starts(_SkipWhiteChars(line), "#define const_mem_addr", true, true)) // for generation of the EE header we need to remove definition of 'const_mem_addr' as a macro, because in Code Editor it is used as a keyword
  68. {
  69. s->lines.removeValid(l, true);
  70. if(InRange(l, s->lines) && !Is(_SkipWhiteChars(s->lines[l])))s->lines.removeValid(l, true); // if the next line is empty then remove it
  71. l--;
  72. }
  73. }
  74. }
  75. }
  76. Int token_index=0; // will be invalid if source is included more than 1 time, but it's only for some extra auto-complete info, so not so important
  77. Memc<Token*> temp;
  78. FREPA(s->lines)
  79. {
  80. Int start=i; s->preprocess(macros, i, temp, true, prep_if);
  81. for(Int j=start; j<=i; j++)
  82. {
  83. Line &line=s->lines[j];
  84. Memc<Token> &src =line.Tokens(); FREPA(src){Token &token=dest.New(); token=src[i]; token.source_index=token_index++;}
  85. Memc<Token> &org =line.tokens ;
  86. if(line.preproc && !line.starts_with_preproc && !line.starts_with_macro_param && org.elms()>=3)
  87. if(!prep_if.elms() || prep_if.last().currently_valid)
  88. if(org[0]=='#' && org[1]=="include")
  89. {
  90. if(org[2]=='<')
  91. {
  92. Str file; for(Int i=3; i<org.elms() && org[i]!='>'; i++)file+=org[i];
  93. parseHeaderEx(file, GetPath(h), true , dest, macros, usings, ee, prep_if);
  94. }else
  95. {
  96. Str file=org[2]; file.removeLast().remove(0);
  97. parseHeaderEx(file, GetPath(h), false, dest, macros, usings, ee, prep_if);
  98. }
  99. }
  100. }
  101. }
  102. // after possible recursive modifying of the same file is finished
  103. s->tokens.clear();
  104. FREPA(s->lines)
  105. {
  106. Memc<Token> &src=s->lines[i].Tokens();
  107. FREPA(src)s->tokens.add(&src[i]);
  108. }
  109. s->recursive--;
  110. }
  111. s->parse_count++;
  112. }
  113. }
  114. /******************************************************************************/
  115. void CodeEditor::parseHeader(C Str &h, Memc<Macro> &macros, Memc<SymbolPtr> &usings, Bool ee)
  116. {
  117. CppMode=true;
  118. Memc<PrepCond > prep_if ;
  119. Memc<Token > tokens ; parseHeaderEx(h, S, ee ? false : true, tokens, macros, usings, ee, prep_if);
  120. Memc<Token* > token_ptrs; FREPA(tokens)token_ptrs.add(&tokens[i]);
  121. Memc<SymbolDef > symbols ;
  122. Memc<SymbolDecl> decls ; DetectDataTypes(symbols, decls, token_ptrs);
  123. LinkDataTypes(symbols, token_ptrs);
  124. DetectVarFuncs(symbols, token_ptrs);
  125. // adjust symbol token indexes (convert from 'tokens' list of all source tokens, to per-symbol tokens, this will work ok only if source was included only one time)
  126. REPA (symbols)FlagDisable(symbols[i]->helper, Symbol::HELPER_ADJUSTED_INDEXES);
  127. REPA (decls )FlagDisable(decls [i]->helper, Symbol::HELPER_ADJUSTED_INDEXES);
  128. REPAO(symbols)->adjustIndexes(tokens);
  129. REPAO(decls )->adjustIndexes(tokens);
  130. // adjust source tokens, since they were modified inside 'DetectDataTypes', 'LinkDataTypes', 'DetectVarFuncs'
  131. REPA(tokens)
  132. {
  133. Token &token =tokens[i];
  134. if(Source *source=token.line->source)
  135. if(InRange(token.source_index, source->tokens))Swap(*source->tokens[token.source_index], token);
  136. }
  137. // put SymbolDef's into proper sources
  138. REPA(symbols){SymbolDef &symbol=symbols[i]; if(symbol && symbol->source)Swap(symbol->source->symbols.New(), symbol);}
  139. REPA(decls ){SymbolDecl &decl =decls [i]; if(decl && decl ->source)Swap(decl ->source->decls .New(), decl );}
  140. CppMode=false;
  141. }
  142. /******************************************************************************/
  143. }}
  144. /******************************************************************************/