cppPreprocessor.cxx 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313
  1. // Filename: cppPreprocessor.cxx
  2. // Created by: drose (22Oct99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "cppPreprocessor.h"
  19. #include "cppExpressionParser.h"
  20. #include "cppExpression.h"
  21. #include "cppScope.h"
  22. #include "cppIdentifier.h"
  23. #include "cppTemplateScope.h"
  24. #include "cppTemplateParameterList.h"
  25. #include "cppSimpleType.h"
  26. #include "cppGlobals.h"
  27. #include "cppCommentBlock.h"
  28. #include "cppBison.h"
  29. #include "indent.h"
  30. #include <assert.h>
  31. #include <ctype.h>
  32. // We manage our own visibility counter, in addition to that managed
  33. // by cppBison.y. We do this just so we can define manifests with the
  34. // correct visibility when they are declared. (Asking the parser for
  35. // the current visibility is prone to error, since the parser might be
  36. // several tokens behind the preprocessor.)
  37. static CPPVisibility preprocessor_vis = V_public;
  38. static int
  39. hex_val(int c) {
  40. switch (c) {
  41. case '0':
  42. case '1':
  43. case '2':
  44. case '3':
  45. case '4':
  46. case '5':
  47. case '6':
  48. case '7':
  49. case '8':
  50. case '9':
  51. return (c - '0');
  52. default:
  53. return (tolower(c) - 'a' + 10);
  54. }
  55. }
  56. static string
  57. trim_blanks(const string &str) {
  58. size_t first, last;
  59. if(str.empty())
  60. return str;
  61. first = 0;
  62. while (first < str.length() && isspace(str[first])) {
  63. first++;
  64. }
  65. last = str.length() - 1;
  66. while (last > first && isspace(str[last])) {
  67. last--;
  68. }
  69. return str.substr(first, last - first + 1);
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: CPPPreprocessor::InputFile::Constructor
  73. // Access: Public
  74. // Description:
  75. ////////////////////////////////////////////////////////////////////
  76. CPPPreprocessor::InputFile::
  77. InputFile() {
  78. _in = NULL;
  79. _ignore_manifest = NULL;
  80. _line_number = 1;
  81. _col_number = 1;
  82. _lock_position = false;
  83. }
  84. ////////////////////////////////////////////////////////////////////
  85. // Function: CPPPreprocessor::InputFile::Destructor
  86. // Access: Public
  87. // Description:
  88. ////////////////////////////////////////////////////////////////////
  89. CPPPreprocessor::InputFile::
  90. ~InputFile() {
  91. if (_in != NULL) {
  92. // For some reason--compiler bug in gcc 3.2?--explicitly deleting
  93. // the stream pointer does not call the appropriate global delete
  94. // function; instead apparently calling the system delete
  95. // function. So we call the delete function by hand instead.
  96. #ifndef USE_MEMORY_NOWRAPPERS
  97. _in->~istream();
  98. (*global_operator_delete)(_in);
  99. #else
  100. delete _in;
  101. #endif
  102. }
  103. }
  104. ////////////////////////////////////////////////////////////////////
  105. // Function: CPPPreprocessor::InputFile::open
  106. // Access: Public
  107. // Description:
  108. ////////////////////////////////////////////////////////////////////
  109. bool CPPPreprocessor::InputFile::
  110. open(const CPPFile &file) {
  111. assert(_in == NULL);
  112. _file = file;
  113. ifstream *in = new ifstream;
  114. _in = in;
  115. return _file._filename.open_read(*in);
  116. }
  117. ////////////////////////////////////////////////////////////////////
  118. // Function: CPPPreprocessor::InputFile::connect_input
  119. // Access: Public
  120. // Description:
  121. ////////////////////////////////////////////////////////////////////
  122. bool CPPPreprocessor::InputFile::
  123. connect_input(const string &input) {
  124. assert(_in == NULL);
  125. _input = input;
  126. _in = new istringstream(_input);
  127. return !_in->fail();
  128. }
  129. ////////////////////////////////////////////////////////////////////
  130. // Function: CPPPreprocessor::InputFile::get
  131. // Access: Public
  132. // Description:
  133. ////////////////////////////////////////////////////////////////////
  134. int CPPPreprocessor::InputFile::
  135. get() {
  136. assert(_in != NULL);
  137. int c = _in->get();
  138. // Quietly skip over embedded carriage-return characters. We
  139. // shouldn't see any of these unless there was some DOS-to-Unix file
  140. // conversion problem.
  141. while (c == '\r') {
  142. c = _in->get();
  143. }
  144. switch (c) {
  145. case EOF:
  146. break;
  147. case '\n':
  148. if (!_lock_position) {
  149. _line_number++;
  150. _col_number = 1;
  151. }
  152. break;
  153. default:
  154. if (!_lock_position) {
  155. _col_number++;
  156. }
  157. }
  158. return c;
  159. }
  160. ////////////////////////////////////////////////////////////////////
  161. // Function: CPPPreprocessor::Constructor
  162. // Access: Public
  163. // Description:
  164. ////////////////////////////////////////////////////////////////////
  165. CPPPreprocessor::
  166. CPPPreprocessor() {
  167. _state = S_eof;
  168. _paren_nesting = 0;
  169. _angle_bracket_found = false;
  170. _unget = '\0';
  171. _last_c = '\0';
  172. _start_of_line = true;
  173. _last_cpp_comment = false;
  174. _save_comments = true;
  175. _resolve_identifiers = true;
  176. _warning_count = 0;
  177. _error_count = 0;
  178. #ifdef CPP_VERBOSE_LEX
  179. _token_index = 0;
  180. #endif
  181. _verbose = 1;
  182. }
  183. ////////////////////////////////////////////////////////////////////
  184. // Function: CPPPreprocessor::set_verbose
  185. // Access: Public
  186. // Description: Sets the verbosity level of the parser. At 0, no
  187. // warnings will be reported; at 1 or higher, expect to
  188. // get spammed.
  189. ////////////////////////////////////////////////////////////////////
  190. void CPPPreprocessor::
  191. set_verbose(int verbose) {
  192. _verbose = verbose;
  193. }
  194. ////////////////////////////////////////////////////////////////////
  195. // Function: CPPPreprocessor::get_verbose
  196. // Access: Public
  197. // Description: Returns the verbosity level of the parser.
  198. ////////////////////////////////////////////////////////////////////
  199. int CPPPreprocessor::
  200. get_verbose() const {
  201. return _verbose;
  202. }
  203. ////////////////////////////////////////////////////////////////////
  204. // Function: CPPPreprocessor::copy_filepos
  205. // Access: Public
  206. // Description:
  207. ////////////////////////////////////////////////////////////////////
  208. void CPPPreprocessor::
  209. copy_filepos(const CPPPreprocessor &other) {
  210. assert(!_files.empty());
  211. _files.back()._file = other.get_file();
  212. _files.back()._line_number = other.get_line_number();
  213. _files.back()._col_number = other.get_col_number();
  214. }
  215. ////////////////////////////////////////////////////////////////////
  216. // Function: CPPPreprocessor::get_file
  217. // Access: Public
  218. // Description:
  219. ////////////////////////////////////////////////////////////////////
  220. CPPFile CPPPreprocessor::
  221. get_file() const {
  222. if (_files.empty()) {
  223. return CPPFile("");
  224. }
  225. return _files.back()._file;
  226. }
  227. ////////////////////////////////////////////////////////////////////
  228. // Function: CPPPreprocessor::get_line_number
  229. // Access: Public
  230. // Description:
  231. ////////////////////////////////////////////////////////////////////
  232. int CPPPreprocessor::
  233. get_line_number() const {
  234. if (_files.empty()) {
  235. return 0;
  236. }
  237. return _files.back()._line_number;
  238. }
  239. ////////////////////////////////////////////////////////////////////
  240. // Function: CPPPreprocessor::get_col_number
  241. // Access: Public
  242. // Description:
  243. ////////////////////////////////////////////////////////////////////
  244. int CPPPreprocessor::
  245. get_col_number() const {
  246. if (_files.empty()) {
  247. return 0;
  248. }
  249. return _files.back()._col_number;
  250. }
  251. ////////////////////////////////////////////////////////////////////
  252. // Function: CPPPreprocessor::get_next_token
  253. // Access: Public
  254. // Description:
  255. ////////////////////////////////////////////////////////////////////
  256. CPPToken CPPPreprocessor::
  257. get_next_token() {
  258. #ifdef CPP_VERBOSE_LEX
  259. CPPToken tok = get_next_token0();
  260. indent(cerr, _files.size() * 2)
  261. << _token_index++ << ". " << tok << "\n";
  262. return tok;
  263. }
  264. CPPToken CPPPreprocessor::
  265. get_next_token0() {
  266. #endif
  267. // We make a nested call to internal_get_next_token(), so we can
  268. // combine sequences of identifiers and scoping symbols into a
  269. // single identifier, for yacc's convenience.
  270. CPPToken token(0);
  271. if (!_saved_tokens.empty()) {
  272. token = _saved_tokens.back();
  273. _saved_tokens.pop_back();
  274. } else {
  275. token = internal_get_next_token();
  276. }
  277. int first_line = token._lloc.first_line;
  278. int first_col = token._lloc.first_column;
  279. CPPFile first_file = token._lloc.file;
  280. if (token._token == '#') {
  281. // Stringify.
  282. token = internal_get_next_token();
  283. if (token._token == SIMPLE_IDENTIFIER || token._token == STRING) {
  284. token._token = STRING;
  285. } else {
  286. // Stringify nothing.
  287. _saved_tokens.push_back(token);
  288. token._token = STRING;
  289. token._lval.str = "";
  290. }
  291. }
  292. if (_resolve_identifiers &&
  293. (token._token == SIMPLE_IDENTIFIER || token._token == SCOPE)) {
  294. // We will be returning a scoped identifier, or a scoping. Keep
  295. // pulling off tokens until we reach the end of the
  296. // scope/identifier sequence.
  297. string name;
  298. // If we started the ball with an identifier, use it and get the
  299. // next token. Otherwise, we started with :: (global scope), and
  300. // we indicate this with an empty string at the beginning of the
  301. // scoping sequence.
  302. if (token._token == SIMPLE_IDENTIFIER) {
  303. name = token._lval.str;
  304. token = internal_get_next_token();
  305. }
  306. CPPIdentifier *ident = new CPPIdentifier(name, token._lloc.file);
  307. YYSTYPE result;
  308. result.u.identifier = ident;
  309. if (token._token == '<') {
  310. // If the next token is an angle bracket and the current
  311. // identifier wants template instantiation, assume the angle
  312. // bracket begins the instantiation and call yacc recursively to
  313. // parse the template parameters.
  314. CPPDeclaration *decl = ident->find_template(current_scope, global_scope);
  315. if (decl != NULL) {
  316. ident->_names.back().set_templ
  317. (nested_parse_template_instantiation(decl->get_template_scope()));
  318. token = internal_get_next_token();
  319. }
  320. }
  321. while (token._token == SCOPE || token._token == TOKENPASTE) {
  322. if (token._token == TOKENPASTE) {
  323. // The token-pasting operator creates one continuous
  324. // identifier across whitespace.
  325. token = internal_get_next_token();
  326. if (token._token == SIMPLE_IDENTIFIER) {
  327. name += token._lval.str;
  328. ident->_names.back().append_name(token._lval.str);
  329. token = internal_get_next_token();
  330. } else {
  331. // Token-paste with nothing.
  332. }
  333. } else { // token._token == SCOPE
  334. name += "::";
  335. token = internal_get_next_token();
  336. string token_prefix;
  337. if (token._token == '~') {
  338. // A scoping operator followed by a tilde can only be the
  339. // start of a scoped destructor name. Make the tilde be part
  340. // of the name.
  341. name += "~";
  342. token_prefix = "~";
  343. token = internal_get_next_token();
  344. }
  345. if (token._token != SIMPLE_IDENTIFIER) {
  346. // The last useful token was a SCOPE, thus this is a scoping
  347. // token.
  348. if (token._token == KW_OPERATOR) {
  349. // Unless the last token we came across was the "operator"
  350. // keyword. We make a special case for this, because it's
  351. // occasionally scoped in normal use.
  352. token._lval = result;
  353. return token;
  354. }
  355. _saved_tokens.push_back(token);
  356. return CPPToken(SCOPING, first_line, first_col, first_file,
  357. name, result);
  358. }
  359. name += token._lval.str;
  360. ident->_names.push_back(token_prefix + token._lval.str);
  361. token = internal_get_next_token();
  362. }
  363. if (token._token == '<') {
  364. // If the next token is an angle bracket and the current
  365. // indentifier wants template instantiation, assume the angle
  366. // bracket begins the instantiation and call yacc recursively to
  367. // parse the template parameters.
  368. CPPDeclaration *decl =
  369. ident->find_template(current_scope, global_scope);
  370. if (decl != NULL) {
  371. ident->_names.back().set_templ
  372. (nested_parse_template_instantiation(decl->get_template_scope()));
  373. token = internal_get_next_token();
  374. }
  375. }
  376. }
  377. // The last useful token was a SIMPLE_IDENTIFIER, thus this is a
  378. // normal scoped identifier.
  379. _saved_tokens.push_back(token);
  380. int token_type = IDENTIFIER;
  381. CPPDeclaration *decl = ident->find_symbol(current_scope, global_scope);
  382. if (decl != NULL &&
  383. (decl->as_typedef() != NULL || decl->as_type() != NULL)) {
  384. token_type = TYPENAME_IDENTIFIER;
  385. }
  386. return CPPToken(token_type, first_line, first_col, first_file,
  387. name, result);
  388. }
  389. // This is the normal case: just pass through whatever token we got.
  390. return token;
  391. }
  392. ////////////////////////////////////////////////////////////////////
  393. // Function: CPPPreprocessor::warning
  394. // Access: Public
  395. // Description:
  396. ////////////////////////////////////////////////////////////////////
  397. void CPPPreprocessor::
  398. warning(const string &message, int line, int col, CPPFile file) {
  399. if (_verbose >= 2) {
  400. if (line == 0) {
  401. line = get_line_number();
  402. col = get_col_number();
  403. }
  404. if (file.empty()) {
  405. file = get_file();
  406. }
  407. indent(cerr, _files.size() * 2)
  408. << "*** Warning in " << file
  409. << " near line " << line << ", column " << col << ":\n";
  410. indent(cerr, _files.size() * 2)
  411. << message << "\n";
  412. }
  413. _warning_count++;
  414. }
  415. ////////////////////////////////////////////////////////////////////
  416. // Function: CPPPreprocessor::error
  417. // Access: Public
  418. // Description:
  419. ////////////////////////////////////////////////////////////////////
  420. void CPPPreprocessor::
  421. error(const string &message, int line, int col, CPPFile file) {
  422. if (_state == S_nested || _state == S_end_nested) {
  423. // Don't report or log errors in the nested state. These will be
  424. // reported when the nesting level collapses.
  425. return;
  426. };
  427. if (_verbose >= 1) {
  428. if (line == 0) {
  429. line = get_line_number();
  430. col = get_col_number();
  431. }
  432. if (file.empty()) {
  433. file = get_file();
  434. }
  435. indent(cerr, _files.size() * 2)
  436. << "*** Error in " << file
  437. << " near line " << line << ", column " << col << ":\n";
  438. indent(cerr, _files.size() * 2)
  439. << message << "\n";
  440. }
  441. _error_count++;
  442. }
  443. ////////////////////////////////////////////////////////////////////
  444. // Function: CPPPreprocessor::get_warning_count
  445. // Access: Public
  446. // Description:
  447. ////////////////////////////////////////////////////////////////////
  448. int CPPPreprocessor::
  449. get_warning_count() const {
  450. return _warning_count;
  451. }
  452. ////////////////////////////////////////////////////////////////////
  453. // Function: CPPPreprocessor::get_error_count
  454. // Access: Public
  455. // Description:
  456. ////////////////////////////////////////////////////////////////////
  457. int CPPPreprocessor::
  458. get_error_count() const {
  459. return _error_count;
  460. }
  461. ////////////////////////////////////////////////////////////////////
  462. // Function: CPPPreprocessor::get_comment_before
  463. // Access: Public
  464. // Description: Returns the CPPCommentBlock immediately preceding the
  465. // indicated line, if any. If there is no such comment,
  466. // returns NULL.
  467. ////////////////////////////////////////////////////////////////////
  468. CPPCommentBlock *CPPPreprocessor::
  469. get_comment_before(int line, CPPFile file) {
  470. CPPComments::reverse_iterator ci;
  471. ci = _comments.rbegin();
  472. int wrong_file_count = 0;
  473. while (ci != _comments.rend()) {
  474. CPPCommentBlock *comment = (*ci);
  475. if (comment->_file == file) {
  476. wrong_file_count = 0;
  477. if (comment->_last_line == line || comment->_last_line == line - 1) {
  478. return comment;
  479. }
  480. if (comment->_last_line < line) {
  481. return (CPPCommentBlock *)NULL;
  482. }
  483. } else {
  484. wrong_file_count++;
  485. if (wrong_file_count > 10) {
  486. return (CPPCommentBlock *)NULL;
  487. }
  488. }
  489. ++ci;
  490. }
  491. return (CPPCommentBlock *)NULL;
  492. }
  493. ////////////////////////////////////////////////////////////////////
  494. // Function: CPPPreprocessor::init_cpp
  495. // Access: Protected
  496. // Description:
  497. ////////////////////////////////////////////////////////////////////
  498. bool CPPPreprocessor::
  499. init_cpp(const CPPFile &file) {
  500. _state = S_normal;
  501. _saved_tokens.push_back(CPPToken(START_CPP));
  502. _last_c = '\0';
  503. return push_file(file);
  504. }
  505. ////////////////////////////////////////////////////////////////////
  506. // Function: CPPPreprocessor::init_const_expr
  507. // Access: Protected
  508. // Description:
  509. ////////////////////////////////////////////////////////////////////
  510. bool CPPPreprocessor::
  511. init_const_expr(const string &expr) {
  512. _state = S_normal;
  513. _saved_tokens.push_back(CPPToken(START_CONST_EXPR));
  514. return push_string(expr, false);
  515. }
  516. ////////////////////////////////////////////////////////////////////
  517. // Function: CPPPreprocessor::init_type
  518. // Access: Protected
  519. // Description:
  520. ////////////////////////////////////////////////////////////////////
  521. bool CPPPreprocessor::
  522. init_type(const string &type) {
  523. _state = S_normal;
  524. _saved_tokens.push_back(CPPToken(START_TYPE));
  525. return push_string(type, false);
  526. }
  527. ////////////////////////////////////////////////////////////////////
  528. // Function: CPPPreprocessor::push_file
  529. // Access: Protected
  530. // Description:
  531. ////////////////////////////////////////////////////////////////////
  532. bool CPPPreprocessor::
  533. push_file(const CPPFile &file) {
  534. if (_verbose >= 2) {
  535. indent(cerr, _files.size() * 2)
  536. << "Reading " << file << "\n";
  537. }
  538. _files.push_back(InputFile());
  539. InputFile &infile = _files.back();
  540. if (infile.open(file)) {
  541. // Record the fact that we opened the file for the benefit of user
  542. // code.
  543. _parsed_files.insert(file);
  544. infile._prev_last_c = _last_c;
  545. _last_c = '\0';
  546. _start_of_line = true;
  547. return true;
  548. }
  549. _files.pop_back();
  550. return false;
  551. }
  552. ////////////////////////////////////////////////////////////////////
  553. // Function: CPPPreprocessor::push_string
  554. // Access: Protected
  555. // Description:
  556. ////////////////////////////////////////////////////////////////////
  557. bool CPPPreprocessor::
  558. push_string(const string &input, bool lock_position) {
  559. #ifdef CPP_VERBOSE_LEX
  560. indent(cerr, _files.size() * 2)
  561. << "Pushing to string \"" << input
  562. << "\"\nlock_position = " << lock_position << "\n";
  563. #endif
  564. CPPFile first_file = get_file();
  565. int first_line = get_line_number();
  566. int first_col = get_col_number();
  567. _files.push_back(InputFile());
  568. InputFile &infile = _files.back();
  569. if (infile.connect_input(input)) {
  570. if (lock_position) {
  571. infile._file = first_file;
  572. infile._line_number = first_line;
  573. infile._col_number = first_col;
  574. infile._lock_position = true;
  575. }
  576. infile._prev_last_c = _last_c;
  577. _last_c = '\0';
  578. return true;
  579. }
  580. #ifdef CPP_VERBOSE_LEX
  581. indent(cerr, _files.size() * 2)
  582. << "Unable to read string\n";
  583. #endif
  584. _files.pop_back();
  585. return false;
  586. }
  587. ////////////////////////////////////////////////////////////////////
  588. // Function: CPPPreprocessor::expand_manifests
  589. // Access: Protected
  590. // Description: Given a string, expand all manifests within the
  591. // string and return the new string.
  592. ////////////////////////////////////////////////////////////////////
  593. string CPPPreprocessor::
  594. expand_manifests(const string &input_expr) {
  595. // Get a copy of the expression string we can modify.
  596. string expr = input_expr;
  597. // Repeatedly scan the expr for any manifest names or defined()
  598. // function.
  599. // We'll need to save the set of manifests we've already expanded,
  600. // to guard against recursive references.
  601. set<const CPPManifest *> already_expanded;
  602. bool manifest_found;
  603. do {
  604. manifest_found = false;
  605. size_t p = 0;
  606. while (p < expr.size()) {
  607. if (isalpha(expr[p]) || expr[p] == '_') {
  608. size_t q = p;
  609. while (p < expr.size() && (isalnum(expr[p]) || expr[p] == '_')) {
  610. p++;
  611. }
  612. string ident = expr.substr(q, p - q);
  613. // Here's an identifier. Is it "defined"?
  614. if (ident == "defined") {
  615. expand_defined_function(expr, q, p);
  616. } else {
  617. // Is it a manifest?
  618. Manifests::const_iterator mi = _manifests.find(ident);
  619. if (mi != _manifests.end()) {
  620. const CPPManifest *manifest = (*mi).second;
  621. if (already_expanded.insert(manifest).second) {
  622. expand_manifest_inline(expr, q, p, (*mi).second);
  623. manifest_found = true;
  624. }
  625. }
  626. }
  627. } else {
  628. p++;
  629. }
  630. }
  631. // If we expanded any manifests at all that time, then go back
  632. // through the string and look again--we might have a manifest
  633. // that expands to another manifest.
  634. } while (manifest_found);
  635. return expr;
  636. }
  637. ////////////////////////////////////////////////////////////////////
  638. // Function: CPPPreprocessor::parse_expr
  639. // Access: Protected
  640. // Description: Given a string, expand all manifests within the
  641. // string and evaluate it as an expression. Returns
  642. // NULL if the string is not a valid expression.
  643. //
  644. // This is an internal support function for
  645. // CPPPreprocessor; however, there is a public variant
  646. // of this function defined for CPPParser.
  647. ////////////////////////////////////////////////////////////////////
  648. CPPExpression *CPPPreprocessor::
  649. parse_expr(const string &input_expr, CPPScope *current_scope,
  650. CPPScope *global_scope) {
  651. string expr = expand_manifests(input_expr);
  652. CPPExpressionParser ep(current_scope, global_scope);
  653. ep._verbose = 0;
  654. if (ep.parse_expr(expr, *this)) {
  655. return ep._expr;
  656. } else {
  657. return (CPPExpression *)NULL;
  658. }
  659. }
  660. ////////////////////////////////////////////////////////////////////
  661. // Function: CPPPreprocessor::internal_get_next_token
  662. // Access: Private
  663. // Description:
  664. ////////////////////////////////////////////////////////////////////
  665. CPPToken CPPPreprocessor::
  666. internal_get_next_token() {
  667. if (_state == S_eof || _state == S_end_nested) {
  668. return CPPToken::eof();
  669. }
  670. int c = _last_c;
  671. _last_c = '\0';
  672. if (c == '\0' || c == EOF) {
  673. c = get();
  674. }
  675. // Skip any whitespace, comments, and preprocessor directives before
  676. // the token.
  677. c = skip_whitespace(c);
  678. while (c == '#' && _start_of_line && !should_ignore_preprocessor()) {
  679. c = skip_whitespace(process_directive(c));
  680. }
  681. if (c == '\'') {
  682. return get_quoted_char(c);
  683. } else if (c == '"') {
  684. return get_quoted_string(c);
  685. } else if (isalpha(c) || c == '_') {
  686. return get_identifier(c);
  687. } else if (isdigit(c)) {
  688. return get_number(c);
  689. }
  690. _last_c = c;
  691. if (c == EOF) {
  692. _state = S_eof;
  693. return CPPToken::eof();
  694. }
  695. CPPFile first_file = get_file();
  696. int first_line = get_line_number();
  697. int first_col = get_col_number();
  698. // Check for a number beginning with a decimal point.
  699. int next_c = get();
  700. if (c == '.' && isdigit(next_c)) {
  701. return get_number(c, next_c);
  702. }
  703. // Check for two- or three-character tokens.
  704. _last_c = get();
  705. switch (c) {
  706. case '+':
  707. if (next_c == '+') return CPPToken(PLUSPLUS, first_line, first_col, first_file);
  708. if (next_c == '=') return CPPToken(PLUSEQUAL, first_line, first_col, first_file);
  709. break;
  710. case '-':
  711. if (next_c == '-') return CPPToken(MINUSMINUS, first_line, first_col, first_file);
  712. if (next_c == '=') return CPPToken(MINUSEQUAL, first_line, first_col, first_file);
  713. if (next_c == '>' && _last_c == '*') {
  714. _last_c = get();
  715. return CPPToken(POINTSAT_STAR, first_line, first_col, first_file);
  716. }
  717. if (next_c == '>') return CPPToken(POINTSAT, first_line, first_col, first_file);
  718. break;
  719. case '<':
  720. if (next_c == '<' && _last_c == '=') {
  721. _last_c = get();
  722. return CPPToken(LSHIFTEQUAL, first_line, first_col, first_file);
  723. }
  724. if (next_c == '<') return CPPToken(LSHIFT, first_line, first_col, first_file);
  725. if (next_c == '=') return CPPToken(LECOMPARE, first_line, first_col, first_file);
  726. break;
  727. case '>':
  728. if (next_c == '>' && _last_c == '=') {
  729. _last_c = get();
  730. return CPPToken(RSHIFTEQUAL, first_line, first_col, first_file);
  731. }
  732. if (next_c == '>') return CPPToken(RSHIFT, first_line, first_col, first_file);
  733. if (next_c == '=') return CPPToken(GECOMPARE, first_line, first_col, first_file);
  734. break;
  735. case '|':
  736. if (next_c == '|') return CPPToken(OROR, first_line, first_col, first_file);
  737. if (next_c == '=') return CPPToken(OREQUAL, first_line, first_col, first_file);
  738. break;
  739. case '&':
  740. if (next_c == '&') return CPPToken(ANDAND, first_line, first_col, first_file);
  741. if (next_c == '=') return CPPToken(ANDEQUAL, first_line, first_col, first_file);
  742. break;
  743. case '^':
  744. if (next_c == '=') return CPPToken(XOREQUAL, first_line, first_col, first_file);
  745. break;
  746. case '=':
  747. if (next_c == '=') return CPPToken(EQCOMPARE, first_line, first_col, first_file);
  748. break;
  749. case '!':
  750. if (next_c == '=') return CPPToken(NECOMPARE, first_line, first_col, first_file);
  751. break;
  752. case '.':
  753. if (next_c == '*') return CPPToken(DOT_STAR, first_line, first_col, first_file);
  754. if (next_c == '.' && _last_c == '.') {
  755. _last_c = get();
  756. return CPPToken(ELLIPSIS, first_line, first_col, first_file);
  757. }
  758. break;
  759. case ':':
  760. if (next_c == ':') return CPPToken(SCOPE, first_line, first_col, first_file);
  761. break;
  762. case '*':
  763. if (next_c == '=') return CPPToken(TIMESEQUAL, first_line, first_col, first_file);
  764. break;
  765. case '/':
  766. if (next_c == '=') return CPPToken(DIVIDEEQUAL, first_line, first_col, first_file);
  767. break;
  768. case '%':
  769. if (next_c == '=') return CPPToken(MODEQUAL, first_line, first_col, first_file);
  770. break;
  771. // These are actually preprocessor operators, but it's useful to
  772. // treat them as tokens.
  773. case '#':
  774. if (next_c == '#') return CPPToken(TOKENPASTE, first_line, first_col, first_file);
  775. }
  776. // It wasn't any of the two- or three-character tokens, so put back
  777. // the lookahead character and return the one-character token.
  778. unget(_last_c);
  779. _last_c = next_c;
  780. if (_state == S_nested) {
  781. // If we're running a nested lexer, keep track of the paren
  782. // levels. When we encounter a comma or closing angle bracket at
  783. // the bottom level, we stop.
  784. switch (c) {
  785. case '(':
  786. case '[':
  787. _paren_nesting++;
  788. break;
  789. case ')':
  790. case ']':
  791. _paren_nesting--;
  792. break;
  793. case ',':
  794. if (_paren_nesting <= 0) {
  795. _state = S_end_nested;
  796. return CPPToken::eof();
  797. }
  798. break;
  799. case '>':
  800. if (_paren_nesting <= 0) {
  801. _angle_bracket_found = true;
  802. _state = S_end_nested;
  803. return CPPToken::eof();
  804. }
  805. }
  806. }
  807. return CPPToken(c, first_line, first_col, first_file);
  808. }
  809. ////////////////////////////////////////////////////////////////////
  810. // Function: CPPPreprocessor::skip_whitespace
  811. // Access: Private
  812. // Description:
  813. ////////////////////////////////////////////////////////////////////
  814. int CPPPreprocessor::
  815. skip_whitespace(int c) {
  816. while (c != EOF) {
  817. c = skip_comment(c);
  818. if (c == '\\') {
  819. // A backslash character is an unusual thing to encounter in the
  820. // middle of unquoted C++ code. But it seems to be legal, and
  821. // it seems to mean the same thing it does within quotes: to
  822. // escape the following character. We simply ignore it.
  823. c = get();
  824. }
  825. if (!isspace(c)) {
  826. return c;
  827. }
  828. c = get();
  829. }
  830. return c;
  831. }
  832. ////////////////////////////////////////////////////////////////////
  833. // Function: CPPPreprocessor::skip_comment
  834. // Access: Private
  835. // Description:
  836. ////////////////////////////////////////////////////////////////////
  837. int CPPPreprocessor::
  838. skip_comment(int c) {
  839. if (c == '/') {
  840. int next_c = get();
  841. if (next_c == '*') {
  842. _last_cpp_comment = false;
  843. c = skip_c_comment(get());
  844. } else if (next_c == '/') {
  845. c = skip_cpp_comment(get());
  846. } else {
  847. _last_cpp_comment = false;
  848. unget(next_c);
  849. return c;
  850. }
  851. }
  852. if (!isspace(c)) {
  853. _last_cpp_comment = false;
  854. }
  855. return c;
  856. }
  857. ////////////////////////////////////////////////////////////////////
  858. // Function: CPPPreprocessor::skip_c_comment
  859. // Access: Private
  860. // Description:
  861. ////////////////////////////////////////////////////////////////////
  862. int CPPPreprocessor::
  863. skip_c_comment(int c) {
  864. if (_save_comments) {
  865. CPPCommentBlock *comment = new CPPCommentBlock;
  866. _comments.push_back(comment);
  867. comment->_file = get_file();
  868. comment->_line_number = get_line_number();
  869. comment->_last_line = get_line_number();
  870. comment->_col_number = get_col_number() - 2;
  871. comment->_c_style = true;
  872. comment->_comment = "/*";
  873. while (c != EOF) {
  874. if (c == '*') {
  875. comment->_comment += c;
  876. c = get();
  877. if (c == '/') {
  878. comment->_comment += c;
  879. comment->_last_line = get_line_number();
  880. return get();
  881. }
  882. } else {
  883. comment->_comment += c;
  884. c = get();
  885. }
  886. }
  887. warning("Comment is unterminated",
  888. comment->_line_number, comment->_col_number,
  889. comment->_file);
  890. } else {
  891. CPPFile first_file = get_file();
  892. int first_line_number = get_line_number();
  893. int first_col_number = get_col_number() - 2;
  894. while (c != EOF) {
  895. if (c == '*') {
  896. c = get();
  897. if (c == '/') {
  898. return get();
  899. }
  900. } else {
  901. c = get();
  902. }
  903. }
  904. warning("Comment is unterminated",
  905. first_line_number, first_col_number,
  906. first_file);
  907. }
  908. return c;
  909. }
  910. ////////////////////////////////////////////////////////////////////
  911. // Function: CPPPreprocessor::skip_cpp_comment
  912. // Access: Private
  913. // Description:
  914. ////////////////////////////////////////////////////////////////////
  915. int CPPPreprocessor::
  916. skip_cpp_comment(int c) {
  917. if (_save_comments) {
  918. CPPCommentBlock *comment;
  919. if (_last_cpp_comment) {
  920. // If the last non-whitespace character read was also part of a
  921. // C++ comment, then this is just a continuation of that comment
  922. // block.
  923. assert(!_comments.empty());
  924. comment = _comments.back();
  925. assert(!comment->_c_style);
  926. comment->_comment += "//";
  927. } else {
  928. // Otherwise, this begins a new comment block.
  929. comment = new CPPCommentBlock;
  930. comment->_file = get_file();
  931. comment->_line_number = get_line_number();
  932. comment->_last_line = get_line_number();
  933. comment->_col_number = get_col_number() - 2;
  934. comment->_c_style = false;
  935. comment->_comment = "//";
  936. _comments.push_back(comment);
  937. }
  938. while (c != EOF && c != '\n') {
  939. comment->_comment += c;
  940. c = get();
  941. }
  942. comment->_comment += '\n';
  943. comment->_last_line = get_line_number();
  944. _last_cpp_comment = true;
  945. } else {
  946. while (c != EOF && c != '\n') {
  947. c = get();
  948. }
  949. }
  950. return c;
  951. }
  952. ////////////////////////////////////////////////////////////////////
  953. // Function: CPPPreprocessor::process_directive
  954. // Access: Private
  955. // Description:
  956. ////////////////////////////////////////////////////////////////////
  957. int CPPPreprocessor::
  958. process_directive(int c) {
  959. CPPFile first_file = get_file();
  960. int first_line = get_line_number();
  961. int first_col = get_col_number();
  962. string command, args;
  963. c = get_preprocessor_command(c, command);
  964. c = get_preprocessor_args(c, args);
  965. #ifdef CPP_VERBOSE_LEX
  966. indent(cerr, _files.size() * 2)
  967. << "#" << command << " " << args << "\n";
  968. #endif
  969. if (command == "define") {
  970. handle_define_directive(args, first_line, first_col, first_file);
  971. } else if (command == "undef") {
  972. handle_undef_directive(args, first_line, first_col, first_file);
  973. } else if (command == "ifdef") {
  974. handle_ifdef_directive(args, first_line, first_col, first_file);
  975. } else if (command == "ifndef") {
  976. handle_ifndef_directive(args, first_line, first_col, first_file);
  977. } else if (command == "if") {
  978. handle_if_directive(args, first_line, first_col, first_file);
  979. } else if (command == "else" || command == "elif") {
  980. // Presumably this follows some #if or #ifdef. We don't bother to
  981. // check this, however.
  982. skip_false_if_block(false);
  983. } else if (command == "endif") {
  984. // Presumably this follows some #if or #ifdef. We don't bother to
  985. // check this, however.
  986. } else if (command == "include") {
  987. handle_include_directive(args, first_line, first_col, first_file);
  988. } else if (command == "pragma") {
  989. // Quietly ignore pragmas.
  990. } else if (command == "ident") {
  991. // Quietly ignore idents.
  992. } else if (command == "error") {
  993. handle_error_directive(args, first_line, first_col, first_file);
  994. } else {
  995. warning("Ignoring unknown directive #" + command,
  996. first_line, first_col, first_file);
  997. }
  998. _start_of_line = true;
  999. return '\n';
  1000. }
  1001. ////////////////////////////////////////////////////////////////////
  1002. // Function: CPPPreprocessor::get_preprocessor_command
  1003. // Access: Private
  1004. // Description:
  1005. ////////////////////////////////////////////////////////////////////
  1006. int CPPPreprocessor::
  1007. get_preprocessor_command(int c, string &command) {
  1008. // Skip the hash mark.
  1009. assert(c == '#');
  1010. c = get();
  1011. // Also skip any whitespace following the hash mark--but don't skip
  1012. // past a newline.
  1013. while (c != EOF && (c == ' ' || c == '\t')) {
  1014. c = get();
  1015. }
  1016. // The next sequence of characters is the command.
  1017. while (c != EOF && (isalnum(c) || c == '_')) {
  1018. command += c;
  1019. c = get();
  1020. }
  1021. return c;
  1022. }
  1023. ////////////////////////////////////////////////////////////////////
  1024. // Function: CPPPreprocessor::get_preprocessor_args
  1025. // Access: Private
  1026. // Description:
  1027. ////////////////////////////////////////////////////////////////////
  1028. int CPPPreprocessor::
  1029. get_preprocessor_args(int c, string &args) {
  1030. // Following the command, the rest of the line, as well as any text
  1031. // on successive lines, is part of the arguments to the command.
  1032. while (c != EOF && c != '\n') {
  1033. if (c == '\\') {
  1034. int next_c = get();
  1035. if (next_c == '\n') {
  1036. // Here we have an escaped newline: a continuation.
  1037. args += '\n';
  1038. } else {
  1039. // Just a backslash followed by some non-backslash, keep both.
  1040. args += c;
  1041. if (next_c != EOF) {
  1042. args += next_c;
  1043. }
  1044. }
  1045. } else {
  1046. args += c;
  1047. }
  1048. c = skip_comment(get());
  1049. }
  1050. // Remove any leading and trailing whitespace from the args.
  1051. args = trim_blanks(args);
  1052. return c;
  1053. }
  1054. ////////////////////////////////////////////////////////////////////
  1055. // Function: CPPPreprocessor::handle_define_directive
  1056. // Access: Private
  1057. // Description:
  1058. ////////////////////////////////////////////////////////////////////
  1059. void CPPPreprocessor::
  1060. handle_define_directive(const string &args, int first_line,
  1061. int first_col, const CPPFile &first_file) {
  1062. if (args.empty()) {
  1063. warning("Ignoring empty #define directive",
  1064. first_line, first_col, first_file);
  1065. } else {
  1066. CPPManifest *manifest = new CPPManifest(args, first_file);
  1067. manifest->_vis = preprocessor_vis;
  1068. if (!manifest->_has_parameters) {
  1069. string expr_string = manifest->expand();
  1070. if (!expr_string.empty()) {
  1071. manifest->_expr = parse_expr(expr_string, global_scope, global_scope);
  1072. }
  1073. }
  1074. // ok one memory leak here..
  1075. Manifests::iterator mi = _manifests.find(manifest->_name);
  1076. if(mi != _manifests.end())
  1077. {
  1078. // i do not see a goodway to compare the old and new hmmmm
  1079. //cerr << "Warning Overwriting Constant " << manifest->_name << "\n";
  1080. delete mi->second;
  1081. }
  1082. _manifests[manifest->_name] = manifest;
  1083. }
  1084. }
  1085. ////////////////////////////////////////////////////////////////////
  1086. // Function: CPPPreprocessor::handle_undef_directive
  1087. // Access: Private
  1088. // Description:
  1089. ////////////////////////////////////////////////////////////////////
  1090. void CPPPreprocessor::
  1091. handle_undef_directive(const string &args, int first_line,
  1092. int first_col, const CPPFile &first_file) {
  1093. if (args.empty()) {
  1094. warning("Ignoring empty #undef directive",
  1095. first_line, first_col, first_file);
  1096. } else {
  1097. Manifests::iterator mi = _manifests.find(args);
  1098. if (mi != _manifests.end()) {
  1099. _manifests.erase(mi);
  1100. }
  1101. }
  1102. }
  1103. ////////////////////////////////////////////////////////////////////
  1104. // Function: CPPPreprocessor::handle_ifdef_directive
  1105. // Access: Private
  1106. // Description:
  1107. ////////////////////////////////////////////////////////////////////
  1108. void CPPPreprocessor::
  1109. handle_ifdef_directive(const string &args, int, int, const CPPFile &) {
  1110. Manifests::const_iterator mi = _manifests.find(args);
  1111. if (mi != _manifests.end()) {
  1112. // The macro is defined. We continue.
  1113. return;
  1114. }
  1115. // The macro is undefined. Skip stuff.
  1116. skip_false_if_block(true);
  1117. }
  1118. ////////////////////////////////////////////////////////////////////
  1119. // Function: CPPPreprocessor::handle_ifndef_directive
  1120. // Access: Private
  1121. // Description:
  1122. ////////////////////////////////////////////////////////////////////
  1123. void CPPPreprocessor::
  1124. handle_ifndef_directive(const string &args, int, int, const CPPFile &) {
  1125. Manifests::const_iterator mi = _manifests.find(args);
  1126. if (mi == _manifests.end()) {
  1127. // The macro is undefined. We continue.
  1128. return;
  1129. }
  1130. // The macro is defined. Skip stuff.
  1131. skip_false_if_block(true);
  1132. }
  1133. ////////////////////////////////////////////////////////////////////
  1134. // Function: CPPPreprocessor::handle_if_directive
  1135. // Access: Private
  1136. // Description:
  1137. ////////////////////////////////////////////////////////////////////
  1138. void CPPPreprocessor::
  1139. handle_if_directive(const string &args, int first_line,
  1140. int first_col, const CPPFile &first_file) {
  1141. CPPExpression *expr = parse_expr(args, global_scope, global_scope);
  1142. int expression_result = 0;
  1143. if (expr != (CPPExpression *)NULL) {
  1144. CPPExpression::Result result = expr->evaluate();
  1145. if (result._type == CPPExpression::RT_error) {
  1146. warning("Ignoring invalid expression " + args,
  1147. first_line, first_col, first_file);
  1148. } else {
  1149. expression_result = result.as_integer();
  1150. }
  1151. } else {
  1152. warning("Ignoring invalid expression " + args,
  1153. first_line, first_col, first_file);
  1154. }
  1155. if (expression_result) {
  1156. // The expression result is true. We continue.
  1157. return;
  1158. }
  1159. // The expression result is false. Skip stuff.
  1160. skip_false_if_block(true);
  1161. }
  1162. ////////////////////////////////////////////////////////////////////
  1163. // Function: CPPPreprocessor::handle_include_directive
  1164. // Access: Private
  1165. // Description:
  1166. ////////////////////////////////////////////////////////////////////
  1167. void CPPPreprocessor::
  1168. handle_include_directive(const string &args, int first_line,
  1169. int first_col, const CPPFile &first_file) {
  1170. bool okflag = false;
  1171. Filename filename;
  1172. Filename filename_as_referenced;
  1173. bool angle_quotes = false;
  1174. string expr = args;
  1175. // The filename to include might actually be hidden within a
  1176. // manifest definition. Wow. FreeType depends on this.
  1177. // Just to play things safe, since our manifest-expansion logic
  1178. // might not filter out quotes and angle brackets properly, we'll
  1179. // only expand manifests if we don't begin with a quote or bracket.
  1180. if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
  1181. expr = expand_manifests(expr);
  1182. }
  1183. if (!expr.empty()) {
  1184. if (expr[0] == '"' && expr[expr.size() - 1] == '"') {
  1185. filename = expr.substr(1, expr.size() - 2);
  1186. okflag = true;
  1187. if (_files.size() == 1) {
  1188. // If we're currently processing a top-level file, record the
  1189. // include directive. We don't need to record includes from
  1190. // included files.
  1191. _quote_includes.insert(filename);
  1192. }
  1193. } else if (expr[0] == '<' && expr[expr.size() - 1] == '>') {
  1194. filename = expr.substr(1, expr.size() - 2);
  1195. angle_quotes = true;
  1196. okflag = true;
  1197. if (_files.size() == 1) {
  1198. // If we're currently processing a top-level file, record the
  1199. // include directive. We don't need to record includes from
  1200. // included files.
  1201. _angle_includes.insert(filename);
  1202. }
  1203. }
  1204. }
  1205. filename.set_text();
  1206. filename_as_referenced = filename;
  1207. // Now look for the filename. If we didn't use angle quotes, look
  1208. // first in the current directory.
  1209. bool found_file = false;
  1210. CPPFile::Source source = CPPFile::S_none;
  1211. if (okflag) {
  1212. if (!angle_quotes) {
  1213. found_file = filename.exists();
  1214. source = CPPFile::S_local;
  1215. }
  1216. // Now look for it on the include path.
  1217. if (!found_file && filename.resolve_filename(_system_include_path)) {
  1218. found_file = true;
  1219. source = CPPFile::S_system;
  1220. }
  1221. if (!found_file && filename.resolve_filename(_include_path)) {
  1222. found_file = true;
  1223. source = CPPFile::S_alternate;
  1224. }
  1225. if (!found_file) {
  1226. warning("Cannot find " + filename.get_fullpath(),
  1227. first_line, first_col, first_file);
  1228. } else {
  1229. _last_c = '\0';
  1230. if (!push_file(CPPFile(filename, filename_as_referenced, source))) {
  1231. warning("Unable to read " + filename.get_fullpath(),
  1232. first_line, first_col, first_file);
  1233. }
  1234. }
  1235. } else {
  1236. warning("Ignoring invalid #include directive",
  1237. first_line, first_col, first_file);
  1238. }
  1239. }
  1240. ////////////////////////////////////////////////////////////////////
  1241. // Function: CPPPreprocessor::handle_error_directive
  1242. // Access: Private
  1243. // Description:
  1244. ////////////////////////////////////////////////////////////////////
  1245. void CPPPreprocessor::
  1246. handle_error_directive(const string &args, int first_line,
  1247. int first_col, const CPPFile &first_file) {
  1248. error(args, first_line, first_col, first_file);
  1249. }
  1250. ////////////////////////////////////////////////////////////////////
  1251. // Function: CPPPreprocessor::skip_false_if_block
  1252. // Access: Private
  1253. // Description: We come here when we fail an #if or an #ifdef test,
  1254. // or when we reach the #else clause to something we
  1255. // didn't fail. This function skips all text up until
  1256. // the matching #endif.
  1257. ////////////////////////////////////////////////////////////////////
  1258. void CPPPreprocessor::
  1259. skip_false_if_block(bool consider_elifs) {
  1260. int level = 0;
  1261. _save_comments = false;
  1262. int c = skip_comment(get());
  1263. while (c != EOF) {
  1264. if (c == '#' && _start_of_line) {
  1265. CPPFile first_file = get_file();
  1266. int first_line = get_line_number();
  1267. int first_col = get_col_number();
  1268. // Is this it?
  1269. string command;
  1270. c = get_preprocessor_command(c, command);
  1271. if (command == "if" || command == "ifdef" || command == "ifndef") {
  1272. // Hmm, a nested if block. Even more to skip.
  1273. level++;
  1274. } else if (command == "else") {
  1275. if (level == 0 && consider_elifs) {
  1276. // This will do!
  1277. _save_comments = true;
  1278. return;
  1279. }
  1280. } else if (command == "elif") {
  1281. if (level == 0 && consider_elifs) {
  1282. // If we pass this test, we're in.
  1283. _save_comments = true;
  1284. string args;
  1285. c = get_preprocessor_args(c, args);
  1286. handle_if_directive(args, first_line, first_col, first_file);
  1287. return;
  1288. }
  1289. } else if (command == "endif") {
  1290. if (level == 0) {
  1291. // Here's the end!
  1292. _save_comments = true;
  1293. return;
  1294. }
  1295. level--;
  1296. }
  1297. } else {
  1298. c = skip_comment(get());
  1299. }
  1300. }
  1301. _save_comments = true;
  1302. }
  1303. ////////////////////////////////////////////////////////////////////
  1304. // Function: CPPPreprocessor::get_quoted_char
  1305. // Access: Private
  1306. // Description:
  1307. ////////////////////////////////////////////////////////////////////
  1308. CPPToken CPPPreprocessor::
  1309. get_quoted_char(int c) {
  1310. CPPFile first_file = get_file();
  1311. int first_line = get_line_number();
  1312. int first_col = get_col_number();
  1313. string str = scan_quoted(c);
  1314. YYSTYPE result;
  1315. if (!str.empty()) {
  1316. result.u.integer = (int)str[0];
  1317. } else {
  1318. result.u.integer = 0;
  1319. }
  1320. return CPPToken(CHAR_TOK, first_line, first_col, first_file, str, result);
  1321. }
  1322. ////////////////////////////////////////////////////////////////////
  1323. // Function: CPPPreprocessor::get_quoted_string
  1324. // Access: Private
  1325. // Description:
  1326. ////////////////////////////////////////////////////////////////////
  1327. CPPToken CPPPreprocessor::
  1328. get_quoted_string(int c) {
  1329. CPPFile first_file = get_file();
  1330. int first_line = get_line_number();
  1331. int first_col = get_col_number();
  1332. string str = scan_quoted(c);
  1333. return CPPToken(STRING, first_line, first_col, first_file, str);
  1334. }
  1335. ////////////////////////////////////////////////////////////////////
  1336. // Function: CPPPreprocessor::get_identifier
  1337. // Access: Private
  1338. // Description:
  1339. ////////////////////////////////////////////////////////////////////
  1340. CPPToken CPPPreprocessor::
  1341. get_identifier(int c) {
  1342. CPPFile first_file = get_file();
  1343. int first_line = get_line_number();
  1344. int first_col = get_col_number();
  1345. string name(1, (char)c);
  1346. c = get();
  1347. while (c != EOF && (isalnum(c) || c == '_')) {
  1348. name += c;
  1349. c = get();
  1350. }
  1351. _last_c = c;
  1352. // Is it a manifest?
  1353. Manifests::const_iterator mi = _manifests.find(name);
  1354. if (mi != _manifests.end() && !should_ignore_manifest((*mi).second)) {
  1355. return expand_manifest((*mi).second);
  1356. }
  1357. // Check for keywords.
  1358. int kw = check_keyword(name);
  1359. // Update our internal visibility flag.
  1360. switch (kw) {
  1361. case KW_BEGIN_PUBLISH:
  1362. preprocessor_vis = V_published;
  1363. break;
  1364. case KW_END_PUBLISH:
  1365. preprocessor_vis = V_public;
  1366. break;
  1367. }
  1368. if (kw != 0) {
  1369. YYSTYPE result;
  1370. result.u.identifier = (CPPIdentifier *)NULL;
  1371. return CPPToken(kw, first_line, first_col, first_file, name, result);
  1372. }
  1373. return CPPToken(SIMPLE_IDENTIFIER, first_line, first_col, first_file,
  1374. name);
  1375. }
  1376. ////////////////////////////////////////////////////////////////////
  1377. // Function: CPPPreprocessor::expand_manifest
  1378. // Access: Private
  1379. // Description:
  1380. ////////////////////////////////////////////////////////////////////
  1381. CPPToken CPPPreprocessor::
  1382. expand_manifest(const CPPManifest *manifest) {
  1383. vector_string args;
  1384. if (manifest->_has_parameters) {
  1385. // Hmm, we're expecting arguments.
  1386. extract_manifest_args(manifest->_name, manifest->_num_parameters, args);
  1387. }
  1388. string expanded = " " + manifest->expand(args) + " ";
  1389. push_string(expanded, true);
  1390. if (!manifest->_has_parameters) {
  1391. // If the manifest does not use arguments, then disallow recursive
  1392. // expansion.
  1393. _files.back()._ignore_manifest = manifest;
  1394. }
  1395. #ifdef CPP_VERBOSE_LEX
  1396. indent(cerr, _files.size() * 2)
  1397. << "Expanding " << manifest->_name << " to " << expanded << "\n";
  1398. #endif
  1399. return internal_get_next_token();
  1400. }
  1401. ////////////////////////////////////////////////////////////////////
  1402. // Function: CPPPreprocessor::extract_manifest_args
  1403. // Access: Private
  1404. // Description:
  1405. ////////////////////////////////////////////////////////////////////
  1406. void CPPPreprocessor::
  1407. extract_manifest_args(const string &name, int num_args,
  1408. vector_string &args) {
  1409. CPPFile first_file = get_file();
  1410. int first_line = get_line_number();
  1411. int first_col = get_col_number();
  1412. // Skip whitespace till paren.
  1413. int c = _last_c;
  1414. _last_c = '\0';
  1415. while (c != EOF && isspace(c)) {
  1416. c = get();
  1417. }
  1418. if (c != '(') {
  1419. // No paren, so we have only one arg.
  1420. string arg;
  1421. while (c != EOF && (isalnum(c) || c == '_')) {
  1422. arg += c;
  1423. c = get();
  1424. }
  1425. args.push_back(arg);
  1426. } else {
  1427. // Skip paren.
  1428. c = get();
  1429. string arg;
  1430. while (c != EOF && c != ')') {
  1431. if (c == ',') {
  1432. args.push_back(arg);
  1433. arg = "";
  1434. } else if (c == '"' || c == '\'') {
  1435. // Quoted string or character.
  1436. int quote_mark = c;
  1437. arg += c;
  1438. c = get();
  1439. while (c != EOF && c != quote_mark && c != '\n') {
  1440. if (c == '\\') {
  1441. arg += c;
  1442. c = get();
  1443. }
  1444. if (c != EOF) {
  1445. arg += c;
  1446. c = get();
  1447. }
  1448. }
  1449. arg += c;
  1450. } else if (c == '(') {
  1451. // Nested parens.
  1452. int paren_level = 1;
  1453. while (c != EOF && paren_level > 0) {
  1454. arg += c;
  1455. c = get();
  1456. if (c == '(') {
  1457. paren_level++;
  1458. } else if (c == ')') {
  1459. paren_level--;
  1460. }
  1461. }
  1462. if (c != EOF) {
  1463. arg += c;
  1464. }
  1465. } else {
  1466. arg += c;
  1467. }
  1468. c = get();
  1469. }
  1470. if (num_args != 0 || !arg.empty()) {
  1471. args.push_back(arg);
  1472. }
  1473. }
  1474. if ((int)args.size() != num_args) {
  1475. warning("Wrong number of arguments for manifest " + name,
  1476. first_line, first_col, first_file);
  1477. }
  1478. }
  1479. ////////////////////////////////////////////////////////////////////
  1480. // Function: CPPPreprocessor::expand_defined_function
  1481. // Access: Private
  1482. // Description:
  1483. ////////////////////////////////////////////////////////////////////
  1484. void CPPPreprocessor::
  1485. expand_defined_function(string &expr, size_t q, size_t &p) {
  1486. string result;
  1487. vector_string args;
  1488. extract_manifest_args_inline("defined", 1, args, expr, p);
  1489. if (args.size() >= 1) {
  1490. const string &manifest_name = args[0];
  1491. Manifests::const_iterator mi = _manifests.find(manifest_name);
  1492. if (mi != _manifests.end()) {
  1493. // The macro is defined; the result is "1".
  1494. result = "1";
  1495. } else {
  1496. // The macro is undefined; the result is "0".
  1497. result = "0";
  1498. }
  1499. }
  1500. expr = expr.substr(0, q) + result + expr.substr(p);
  1501. p = q + result.size();
  1502. }
  1503. ////////////////////////////////////////////////////////////////////
  1504. // Function: CPPPreprocessor::expand_manifest_inline
  1505. // Access: Private
  1506. // Description:
  1507. ////////////////////////////////////////////////////////////////////
  1508. void CPPPreprocessor::
  1509. expand_manifest_inline(string &expr, size_t q, size_t &p,
  1510. const CPPManifest *manifest) {
  1511. vector_string args;
  1512. if (manifest->_has_parameters) {
  1513. extract_manifest_args_inline(manifest->_name, manifest->_num_parameters,
  1514. args, expr, p);
  1515. }
  1516. string result = manifest->expand(args);
  1517. expr = expr.substr(0, q) + result + expr.substr(p);
  1518. p = q + result.size();
  1519. }
  1520. ////////////////////////////////////////////////////////////////////
  1521. // Function: CPPPreprocessor::extract_manifest_args_inline
  1522. // Access: Private
  1523. // Description:
  1524. ////////////////////////////////////////////////////////////////////
  1525. void CPPPreprocessor::
  1526. extract_manifest_args_inline(const string &name, int num_args,
  1527. vector_string &args,
  1528. const string &expr, size_t &p) {
  1529. // Skip whitespace till paren.
  1530. while (p < expr.size() && isspace(expr[p])) {
  1531. p++;
  1532. }
  1533. if (p >= expr.size() || expr[p] != '(') {
  1534. // No paren, so we have only one arg.
  1535. size_t q = p;
  1536. while (p < expr.size() && (isalnum(expr[p]) || expr[p] == '_')) {
  1537. p++;
  1538. }
  1539. args.push_back(expr.substr(q, p - q));
  1540. } else if (expr[p] == '"' || expr[p] == '\'') {
  1541. // Quoted string or character.
  1542. int quote_mark = expr[p];
  1543. p++;
  1544. while (p < expr.size() && expr[p] != quote_mark && expr[p] != '\n') {
  1545. if (expr[p] == '\\') {
  1546. p++;
  1547. }
  1548. if (p < expr.size()) {
  1549. p++;
  1550. }
  1551. }
  1552. p++;
  1553. } else {
  1554. // Skip paren.
  1555. p++;
  1556. size_t q = p;
  1557. while (p < expr.size() && expr[p] != ')') {
  1558. if (expr[p] == ',') {
  1559. args.push_back(expr.substr(q, p - q));
  1560. q = p+1;
  1561. } else if (expr[p] == '(') {
  1562. // Nested parens.
  1563. int paren_level = 1;
  1564. while (p+1 < expr.size() && paren_level > 0) {
  1565. p++;
  1566. if (expr[p] == '(') {
  1567. paren_level++;
  1568. } else if (expr[p] == ')') {
  1569. paren_level--;
  1570. }
  1571. }
  1572. }
  1573. p++;
  1574. }
  1575. args.push_back(expr.substr(q, p - q));
  1576. if (p < expr.size() && expr[p] == ')') {
  1577. p++;
  1578. }
  1579. }
  1580. if ((int)args.size() != num_args) {
  1581. warning("Wrong number of arguments for manifest " + name);
  1582. }
  1583. }
  1584. ////////////////////////////////////////////////////////////////////
  1585. // Function: CPPPreprocessor::get_number
  1586. // Access: Private
  1587. // Description:
  1588. ////////////////////////////////////////////////////////////////////
  1589. CPPToken CPPPreprocessor::
  1590. get_number(int c, int c2) {
  1591. CPPFile first_file = get_file();
  1592. int first_line = get_line_number();
  1593. int first_col = get_col_number();
  1594. string num(1, (char)c);
  1595. bool leading_zero = (c == '0');
  1596. bool decimal_point = (c == '.');
  1597. if (c2 == 0) {
  1598. c = get();
  1599. } else {
  1600. c = c2;
  1601. }
  1602. if (leading_zero && c == 'x') {
  1603. // Here we have a hex number.
  1604. num += c;
  1605. c = get();
  1606. while (c != EOF && (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f'))) {
  1607. num += c;
  1608. c = get();
  1609. }
  1610. while (c == 'L' || c == 'U') {
  1611. // We allow (and ignore) an 'L' and/or 'U' following the number.
  1612. c = get();
  1613. }
  1614. _last_c = c;
  1615. YYSTYPE result;
  1616. result.u.integer = strtol(num.c_str(), (char **)NULL, 16);
  1617. return CPPToken(INTEGER, first_line, first_col, first_file, num, result);
  1618. }
  1619. while (c != EOF && isdigit(c)) {
  1620. num += c;
  1621. c = get();
  1622. }
  1623. if (c == '.' && !decimal_point) {
  1624. // Now we have a floating-point number.
  1625. decimal_point = true;
  1626. num += c;
  1627. c = get();
  1628. while (c != EOF && isdigit(c)) {
  1629. num += c;
  1630. c = get();
  1631. }
  1632. }
  1633. if (decimal_point) {
  1634. if (tolower(c) == 'e') {
  1635. // An exponent is allowed.
  1636. num += c;
  1637. c = get();
  1638. if (c == '-' || c == '+') {
  1639. num += c;
  1640. c = get();
  1641. }
  1642. while (c != EOF && isdigit(c)) {
  1643. num += c;
  1644. c = get();
  1645. }
  1646. }
  1647. if (c == 'f') {
  1648. // We allow (and ignore) an 'f' following the number.
  1649. c = get();
  1650. }
  1651. _last_c = c;
  1652. YYSTYPE result;
  1653. result.u.real = strtod(num.c_str(), (char **)NULL);
  1654. return CPPToken(REAL, first_line, first_col, first_file, num, result);
  1655. }
  1656. // This is a decimal or octal integer number.
  1657. while (c == 'L' || c == 'U') {
  1658. // We allow (and ignore) an 'L' and/or 'U' following the number.
  1659. c = get();
  1660. }
  1661. _last_c = c;
  1662. YYSTYPE result;
  1663. if (leading_zero) {
  1664. // A leading zero implies an octal number. strtol() is supposed
  1665. // to be able to make this distinction by itself, but we'll do it
  1666. // explicitly just to be sure.
  1667. result.u.integer = strtol(num.c_str(), (char **)NULL, 8);
  1668. } else {
  1669. // A decimal (base 10) integer.
  1670. result.u.integer = strtol(num.c_str(), (char **)NULL, 10);
  1671. }
  1672. return CPPToken(INTEGER, first_line, first_col, first_file, num, result);
  1673. }
  1674. ////////////////////////////////////////////////////////////////////
  1675. // Function: CPPPreprocessor::check_keyword
  1676. // Access: Private, Static
  1677. // Description:
  1678. ////////////////////////////////////////////////////////////////////
  1679. int CPPPreprocessor::
  1680. check_keyword(const string &name) {
  1681. if (name == "__begin_publish") return KW_BEGIN_PUBLISH;
  1682. if (name == "bool") return KW_BOOL;
  1683. if (name == "catch") return KW_CATCH;
  1684. if (name == "char") return KW_CHAR;
  1685. if (name == "wchar_t") return KW_WCHAR_T;
  1686. if (name == "class") return KW_CLASS;
  1687. if (name == "const") return KW_CONST;
  1688. if (name == "delete") return KW_DELETE;
  1689. if (name == "double") return KW_DOUBLE;
  1690. if (name == "dynamic_cast") return KW_DYNAMIC_CAST;
  1691. if (name == "else") return KW_ELSE;
  1692. if (name == "__end_publish") return KW_END_PUBLISH;
  1693. if (name == "enum") return KW_ENUM;
  1694. if (name == "extern") return KW_EXTERN;
  1695. if (name == "explicit") return KW_EXPLICIT;
  1696. if (name == "__published") return KW_PUBLISHED;
  1697. if (name == "false") return KW_FALSE;
  1698. if (name == "float") return KW_FLOAT;
  1699. if (name == "friend") return KW_FRIEND;
  1700. if (name == "for") return KW_FOR;
  1701. if (name == "goto") return KW_GOTO;
  1702. if (name == "if") return KW_IF;
  1703. if (name == "inline") return KW_INLINE;
  1704. if (name == "int") return KW_INT;
  1705. if (name == "long") return KW_LONG;
  1706. if (name == "mutable") return KW_MUTABLE;
  1707. if (name == "namespace") return KW_NAMESPACE;
  1708. if (name == "new") return KW_NEW;
  1709. if (name == "operator") return KW_OPERATOR;
  1710. if (name == "private") return KW_PRIVATE;
  1711. if (name == "protected") return KW_PROTECTED;
  1712. if (name == "public") return KW_PUBLIC;
  1713. if (name == "register") return KW_REGISTER;
  1714. if (name == "return") return KW_RETURN;
  1715. if (name == "short") return KW_SHORT;
  1716. if (name == "signed") return KW_SIGNED;
  1717. if (name == "sizeof") return KW_SIZEOF;
  1718. if (name == "static") return KW_STATIC;
  1719. if (name == "static_cast") return KW_STATIC_CAST;
  1720. if (name == "struct") return KW_STRUCT;
  1721. if (name == "template") return KW_TEMPLATE;
  1722. if (name == "throw") return KW_THROW;
  1723. if (name == "true") return KW_TRUE;
  1724. if (name == "try") return KW_TRY;
  1725. if (name == "typedef") return KW_TYPEDEF;
  1726. if (name == "typename") return KW_TYPENAME;
  1727. if (name == "union") return KW_UNION;
  1728. if (name == "unsigned") return KW_UNSIGNED;
  1729. if (name == "using") return KW_USING;
  1730. if (name == "virtual") return KW_VIRTUAL;
  1731. if (name == "void") return KW_VOID;
  1732. if (name == "volatile") return KW_VOLATILE;
  1733. if (name == "while") return KW_WHILE;
  1734. if (!cpp_longlong_keyword.empty() && name == cpp_longlong_keyword) {
  1735. return KW_LONGLONG;
  1736. }
  1737. return 0;
  1738. }
  1739. ////////////////////////////////////////////////////////////////////
  1740. // Function: CPPPreprocessor::scan_quoted
  1741. // Access: Private
  1742. // Description:
  1743. ////////////////////////////////////////////////////////////////////
  1744. string CPPPreprocessor::
  1745. scan_quoted(int c) {
  1746. int quote_mark = c;
  1747. string str;
  1748. c = get();
  1749. while (c != EOF && c != '\n' && c != quote_mark) {
  1750. if (c == '\\') {
  1751. // Backslash means a special character follows.
  1752. c = get();
  1753. switch (c) {
  1754. case 'n':
  1755. c = '\n';
  1756. break;
  1757. case 't':
  1758. c = '\t';
  1759. break;
  1760. case 'r':
  1761. c = '\r';
  1762. break;
  1763. case 'x':
  1764. // hex character.
  1765. c = get();
  1766. if (isxdigit(c)) {
  1767. int val = hex_val(c);
  1768. c = get();
  1769. if (isxdigit(c)) {
  1770. val = (val << 4) | hex_val(c);
  1771. } else {
  1772. unget(c);
  1773. }
  1774. c = val;
  1775. }
  1776. break;
  1777. case '0':
  1778. case '1':
  1779. case '2':
  1780. case '3':
  1781. case '4':
  1782. case '5':
  1783. case '6':
  1784. case '7':
  1785. // Octal character.
  1786. {
  1787. int val = (c - '0');
  1788. c = get();
  1789. if (c >= '0' && c <= '7') {
  1790. val = (val << 3) | (c - '0');
  1791. c = get();
  1792. if (c >= '0' && c <= '7') {
  1793. val = (val << 3) | (c - '0');
  1794. } else {
  1795. unget(c);
  1796. }
  1797. } else {
  1798. unget(c);
  1799. }
  1800. c = val;
  1801. }
  1802. break;
  1803. }
  1804. }
  1805. str += c;
  1806. c = get();
  1807. }
  1808. if (c != quote_mark) {
  1809. warning("Unclosed string");
  1810. }
  1811. return str;
  1812. }
  1813. ////////////////////////////////////////////////////////////////////
  1814. // Function: CPPPreprocessor::should_ignore_manifest
  1815. // Access: Public
  1816. // Description: Returns true if the manifest is one that is being
  1817. // ignored right now (presumably because we are
  1818. // presently expanding it).
  1819. ////////////////////////////////////////////////////////////////////
  1820. bool CPPPreprocessor::
  1821. should_ignore_manifest(const CPPManifest *manifest) const {
  1822. Files::const_iterator fi;
  1823. for (fi = _files.begin(); fi != _files.end(); ++fi) {
  1824. if ((*fi)._ignore_manifest == manifest) {
  1825. return true;
  1826. }
  1827. }
  1828. return false;
  1829. }
  1830. ////////////////////////////////////////////////////////////////////
  1831. // Function: CPPPreprocessor::should_ignore_preprocessor
  1832. // Access: Public
  1833. // Description: Returns true if we should ignore any preprocessor
  1834. // directives (e.g. we're presently expanding a
  1835. // manifest).
  1836. ////////////////////////////////////////////////////////////////////
  1837. bool CPPPreprocessor::
  1838. should_ignore_preprocessor() const {
  1839. Files::const_iterator fi;
  1840. for (fi = _files.begin(); fi != _files.end(); ++fi) {
  1841. if ((*fi)._ignore_manifest != NULL) {
  1842. return true;
  1843. }
  1844. }
  1845. return false;
  1846. }
  1847. ////////////////////////////////////////////////////////////////////
  1848. // Function: CPPPreprocessor::get
  1849. // Access: Private
  1850. // Description:
  1851. ////////////////////////////////////////////////////////////////////
  1852. int CPPPreprocessor::
  1853. get() {
  1854. if (_unget != '\0') {
  1855. int c = _unget;
  1856. _unget = '\0';
  1857. return c;
  1858. }
  1859. if (_files.empty()) {
  1860. return EOF;
  1861. }
  1862. int c = _files.back().get();
  1863. while (c == EOF && !_files.empty()) {
  1864. #ifdef CPP_VERBOSE_LEX
  1865. indent(cerr, _files.size() * 2)
  1866. << "End of input stream, restoring to previous input\n";
  1867. #endif
  1868. int last_c = _files.back()._prev_last_c;
  1869. _files.pop_back();
  1870. if (last_c != '\0') {
  1871. c = last_c;
  1872. } else if (!_files.empty()) {
  1873. c = _files.back().get();
  1874. }
  1875. }
  1876. if (c == '\n') {
  1877. _start_of_line = true;
  1878. } else if (!isspace(c) && c != '#') {
  1879. _start_of_line = false;
  1880. }
  1881. return c;
  1882. }
  1883. ////////////////////////////////////////////////////////////////////
  1884. // Function: CPPPreprocessor::unget
  1885. // Access: Private
  1886. // Description:
  1887. ////////////////////////////////////////////////////////////////////
  1888. void CPPPreprocessor::
  1889. unget(int c) {
  1890. assert(_unget == '\0');
  1891. _unget = c;
  1892. }
  1893. ////////////////////////////////////////////////////////////////////
  1894. // Function: CPPPreprocessor::nested_parse_template_instantiation
  1895. // Access: Private
  1896. // Description: Recursively invokes yacc to parse the stuff within
  1897. // angle brackets that's the template instantiation part
  1898. // of an identifier. This involves setting and
  1899. // restoring some state flags so we can return EOF when
  1900. // we reach the closing bracket.
  1901. ////////////////////////////////////////////////////////////////////
  1902. CPPTemplateParameterList *CPPPreprocessor::
  1903. nested_parse_template_instantiation(CPPTemplateScope *scope) {
  1904. #ifdef CPP_VERBOSE_LEX
  1905. indent(cerr, _files.size() * 2)
  1906. << "Beginning nested parse\n";
  1907. #endif
  1908. assert(scope != NULL);
  1909. State old_state = _state;
  1910. int old_nesting = _paren_nesting;
  1911. const CPPTemplateParameterList &formal_params = scope->_parameters;
  1912. CPPTemplateParameterList::Parameters::const_iterator pi;
  1913. _angle_bracket_found = false;
  1914. CPPToken token = internal_get_next_token();
  1915. if (token._token == '>') {
  1916. _angle_bracket_found = true;
  1917. } else {
  1918. _saved_tokens.push_back(token);
  1919. }
  1920. CPPTemplateParameterList *actual_params = new CPPTemplateParameterList;
  1921. for (pi = formal_params._parameters.begin();
  1922. pi != formal_params._parameters.end() && !_angle_bracket_found;
  1923. ++pi) {
  1924. _state = S_nested;
  1925. _paren_nesting = 0;
  1926. CPPFile first_file = get_file();
  1927. int first_line = get_line_number();
  1928. int first_col = get_col_number();
  1929. CPPDeclaration *decl = (*pi);
  1930. if (decl->as_type()) {
  1931. _saved_tokens.push_back(CPPToken(START_TYPE));
  1932. CPPType *type = ::parse_type(this, current_scope, global_scope);
  1933. if (type == NULL) {
  1934. warning("Invalid type", first_line, first_col, first_file);
  1935. skip_to_end_nested();
  1936. type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown));
  1937. }
  1938. actual_params->_parameters.push_back(type);
  1939. } else {
  1940. _saved_tokens.push_back(CPPToken(START_CONST_EXPR));
  1941. CPPExpression *expr = parse_const_expr(this, current_scope, global_scope);
  1942. if (expr == NULL) {
  1943. warning("Invalid expression", first_line, first_col, first_file);
  1944. skip_to_end_nested();
  1945. expr = new CPPExpression(0);
  1946. }
  1947. actual_params->_parameters.push_back(expr);
  1948. }
  1949. }
  1950. if (!_angle_bracket_found) {
  1951. warning("Ignoring extra parameters in template instantiation");
  1952. skip_to_angle_bracket();
  1953. }
  1954. _state = old_state;
  1955. _paren_nesting = old_nesting;
  1956. _angle_bracket_found = false;
  1957. #ifdef CPP_VERBOSE_LEX
  1958. indent(cerr, _files.size() * 2)
  1959. << "Ending nested parse\n";
  1960. #endif
  1961. return actual_params;
  1962. }
  1963. ////////////////////////////////////////////////////////////////////
  1964. // Function: CPPPreprocessor::skip_to_end_nested
  1965. // Access: Private
  1966. // Description: This is an error-recovery function, called after
  1967. // returning from a nested parse. If the state is not
  1968. // S_end_nested, there was an error in parsing the
  1969. // nested tokens, and not all of the nested tokens may
  1970. // have been consumed. This function will consume the
  1971. // rest of the nested tokens.
  1972. ////////////////////////////////////////////////////////////////////
  1973. void CPPPreprocessor::
  1974. skip_to_end_nested() {
  1975. #ifdef CPP_VERBOSE_LEX
  1976. indent(cerr, _files.size() * 2)
  1977. << "Skipping tokens:\n";
  1978. #endif
  1979. // Eat any eof tokens on the pushback stack.
  1980. while (!_saved_tokens.empty() && _saved_tokens.back().is_eof()) {
  1981. _saved_tokens.pop_back();
  1982. }
  1983. while (_state != S_end_nested && _state != S_eof) {
  1984. get_next_token();
  1985. }
  1986. #ifdef CPP_VERBOSE_LEX
  1987. indent(cerr, _files.size() * 2)
  1988. << "Done skipping tokens.\n";
  1989. #endif
  1990. }
  1991. ////////////////////////////////////////////////////////////////////
  1992. // Function: CPPPreprocessor::skip_to_angle_bracket
  1993. // Access: Private
  1994. // Description: This is an error-recovery function, called after
  1995. // returning from a nested parse. If we haven't yet
  1996. // consumed the closing angle bracket on the template
  1997. // instantiation, keep consuming tokens until we do.
  1998. ////////////////////////////////////////////////////////////////////
  1999. void CPPPreprocessor::
  2000. skip_to_angle_bracket() {
  2001. #ifdef CPP_VERBOSE_LEX
  2002. indent(cerr, _files.size() * 2)
  2003. << "Skipping tokens:\n";
  2004. #endif
  2005. while (!_angle_bracket_found && _state != S_eof) {
  2006. _state = S_nested;
  2007. while (_state != S_end_nested && _state != S_eof) {
  2008. get_next_token();
  2009. }
  2010. }
  2011. // Eat any eof tokens on the pushback stack.
  2012. while (!_saved_tokens.empty() && _saved_tokens.back().is_eof()) {
  2013. _saved_tokens.pop_back();
  2014. }
  2015. #ifdef CPP_VERBOSE_LEX
  2016. indent(cerr, _files.size() * 2)
  2017. << "Done skipping tokens.\n";
  2018. #endif
  2019. }