cppManifest.cxx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Filename: cppManifest.cxx
  2. // Created by: drose (22Oct99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, 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://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "cppManifest.h"
  19. #include "cppExpression.h"
  20. #include <ctype.h>
  21. ////////////////////////////////////////////////////////////////////
  22. // Function: CPPManifest::ExpansionNode::Constructor
  23. // Access: Public
  24. // Description:
  25. ////////////////////////////////////////////////////////////////////
  26. CPPManifest::ExpansionNode::
  27. ExpansionNode(int parm_number) :
  28. _parm_number(parm_number)
  29. {
  30. }
  31. ////////////////////////////////////////////////////////////////////
  32. // Function: CPPManifest::ExpansionNode::Constructor
  33. // Access: Public
  34. // Description:
  35. ////////////////////////////////////////////////////////////////////
  36. CPPManifest::ExpansionNode::
  37. ExpansionNode(const string &str) :
  38. _parm_number(-1), _str(str)
  39. {
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: CPPManifest::Constructor
  43. // Access: Public
  44. // Description:
  45. ////////////////////////////////////////////////////////////////////
  46. CPPManifest::
  47. CPPManifest(const string &args, const CPPFile &file) : _file(file) {
  48. assert(!args.empty());
  49. assert(!isspace(args[0]));
  50. _expr = (CPPExpression *)NULL;
  51. _vis = V_public;
  52. // First, identify the manifest name.
  53. size_t p = 0;
  54. while (p < args.size() && !isspace(args[p]) && args[p] != '(') {
  55. p++;
  56. }
  57. _name = args.substr(0, p);
  58. vector_string parameter_names;
  59. if (args[p] == '(') {
  60. // Hmm, parameters.
  61. _has_parameters = true;
  62. parse_parameters(args, p, parameter_names);
  63. _num_parameters = parameter_names.size();
  64. p++;
  65. } else {
  66. _has_parameters = false;
  67. _num_parameters = 0;
  68. }
  69. // Now identify the expansion. Skip whitespace.
  70. while (p < args.size() && isspace(args[p])) {
  71. p++;
  72. }
  73. save_expansion(args.substr(p), parameter_names);
  74. }
  75. ////////////////////////////////////////////////////////////////////
  76. // Function: CPPManifest::Destructor
  77. // Access: Public
  78. // Description:
  79. ////////////////////////////////////////////////////////////////////
  80. CPPManifest::
  81. ~CPPManifest() {
  82. if (_expr != (CPPExpression *)NULL) {
  83. delete _expr;
  84. }
  85. }
  86. ////////////////////////////////////////////////////////////////////
  87. // Function: CPPManifest::expand
  88. // Access: Public
  89. // Description:
  90. ////////////////////////////////////////////////////////////////////
  91. string CPPManifest::
  92. expand(const vector_string &args) const {
  93. string result;
  94. Expansion::const_iterator ei;
  95. for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
  96. if ((*ei)._parm_number >= 0) {
  97. int i = (*ei)._parm_number;
  98. if (i < (int)args.size()) {
  99. result += " " + args[i] + " ";
  100. } else {
  101. result += " ";
  102. }
  103. }
  104. if (!(*ei)._str.empty()) {
  105. result += (*ei)._str;
  106. }
  107. }
  108. return result;
  109. }
  110. ////////////////////////////////////////////////////////////////////
  111. // Function: CPPManifest::determine_type
  112. // Access: Public
  113. // Description: Returns the type of the manifest, if it is known,
  114. // or NULL if the type cannot be determined.
  115. ////////////////////////////////////////////////////////////////////
  116. CPPType *CPPManifest::
  117. determine_type() const {
  118. if (_expr != (CPPExpression *)NULL) {
  119. return _expr->determine_type();
  120. }
  121. return (CPPType *)NULL;
  122. }
  123. ////////////////////////////////////////////////////////////////////
  124. // Function: CPPManifest::output
  125. // Access: Public
  126. // Description:
  127. ////////////////////////////////////////////////////////////////////
  128. void CPPManifest::
  129. output(ostream &out) const {
  130. out << _name;
  131. if (_has_parameters) {
  132. out << "(";
  133. if (_num_parameters > 0) {
  134. out << "$1";
  135. for (int i = 1; i < _num_parameters; i++) {
  136. out << ", $" << i + 1;
  137. }
  138. }
  139. out << ")";
  140. }
  141. out << " ";
  142. Expansion::const_iterator ei;
  143. for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
  144. if ((*ei)._parm_number >= 0) {
  145. out << " $" << (*ei)._parm_number + 1 << " ";
  146. }
  147. if (!(*ei)._str.empty()) {
  148. out << (*ei)._str;
  149. }
  150. }
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: CPPManifest::parse_parameters
  154. // Access: Private
  155. // Description:
  156. ////////////////////////////////////////////////////////////////////
  157. void CPPManifest::
  158. parse_parameters(const string &args, size_t &p,
  159. vector_string &parameter_names) {
  160. assert(p < args.size());
  161. assert(args[p] == '(');
  162. p++;
  163. while (p < args.size() && isspace(args[p])) {
  164. p++;
  165. }
  166. while (p < args.size() && args[p] != ')') {
  167. // Here's the beginning of a parm.
  168. size_t q = p;
  169. while (p < args.size() && !isspace(args[p]) &&
  170. args[p] != ')' && args[p] != ',') {
  171. p++;
  172. }
  173. parameter_names.push_back(args.substr(q, p - q));
  174. // Skip whitespace after the parameter name.
  175. while (p < args.size() && isspace(args[p])) {
  176. p++;
  177. }
  178. if (p < args.size() && args[p] == ',') {
  179. p++;
  180. // Skip whitespace after a comma.
  181. while (p < args.size() && isspace(args[p])) {
  182. p++;
  183. }
  184. }
  185. }
  186. }
  187. ////////////////////////////////////////////////////////////////////
  188. // Function: CPPManifest::save_expansion
  189. // Access: Private
  190. // Description:
  191. ////////////////////////////////////////////////////////////////////
  192. void CPPManifest::
  193. save_expansion(const string &exp, const vector_string &parameter_names) {
  194. if (parameter_names.empty()) {
  195. // No parameters; this is an easy case.
  196. _expansion.push_back(ExpansionNode(exp));
  197. return;
  198. }
  199. // Walk through the expansion string. For each substring that is an
  200. // identifier, check it against parameter_names.
  201. size_t p = 0;
  202. size_t last = 0;
  203. while (p < exp.size()) {
  204. if (isalpha(exp[p]) || exp[p] == '_') {
  205. // Here's the start of an identifier. Find the end of it.
  206. size_t q = p;
  207. p++;
  208. while (p < exp.size() && isalnum(exp[p]) || exp[p] == '_') {
  209. p++;
  210. }
  211. string ident = exp.substr(q, p - q);
  212. // Is this identifier one of our parameters?
  213. int pnum = -1;
  214. for (int i = 0; pnum == -1 && i < (int)parameter_names.size(); i++) {
  215. if (parameter_names[i] == ident) {
  216. pnum = i;
  217. }
  218. }
  219. if (pnum != -1) {
  220. // Yep!
  221. if (last != q) {
  222. _expansion.push_back(ExpansionNode(exp.substr(last, q - last)));
  223. }
  224. _expansion.push_back(pnum);
  225. last = p;
  226. }
  227. } else {
  228. p++;
  229. }
  230. }
  231. if (last != p) {
  232. _expansion.push_back(exp.substr(last, p - last));
  233. }
  234. }