aRts audio server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
4.0KB

  1. /*
  2. Copyright (C) 2000 Stefan Westerfeld
  3. stefan@space.twc.de
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include <list>
  20. #include <string>
  21. #include <map>
  22. #include "namespace.h"
  23. #include <assert.h>
  24. using namespace std;
  25. /* generic utilities */
  26. static list<string> symbolToList(string symbol)
  27. {
  28. list<string> result;
  29. string current;
  30. string::iterator si;
  31. for(si = symbol.begin(); si != symbol.end(); si++)
  32. {
  33. if(*si != ':')
  34. {
  35. current += *si;
  36. }
  37. else
  38. {
  39. if(!current.empty())
  40. result.push_back(current);
  41. current = "";
  42. }
  43. }
  44. result.push_back(current);
  45. return result;
  46. }
  47. static string listToSymbol(list<string>& symlist)
  48. {
  49. string s;
  50. list<string>::iterator si;
  51. for(si = symlist.begin(); si != symlist.end(); si++)
  52. {
  53. if(!s.empty()) s += "::";
  54. s += *si;
  55. }
  56. return s;
  57. }
  58. /* ModuleHelper */
  59. static list<string> modulePath;
  60. static map<string,bool> moduleDefinitions;
  61. void ModuleHelper::enter(const char *name)
  62. {
  63. modulePath.push_back(name);
  64. }
  65. void ModuleHelper::leave()
  66. {
  67. assert(!modulePath.empty());
  68. modulePath.pop_back();
  69. }
  70. string prependModulePath(string s)
  71. {
  72. if(modulePath.empty())
  73. return s;
  74. else
  75. return listToSymbol(modulePath)+"::"+s;
  76. }
  77. void ModuleHelper::define(const char *name)
  78. {
  79. moduleDefinitions[prependModulePath(name)] = true;
  80. }
  81. char *ModuleHelper::qualify(const char *name)
  82. {
  83. char *result = 0;
  84. // TODO: nested namespaces
  85. string inCurrentModule = prependModulePath(name);
  86. if(moduleDefinitions[inCurrentModule])
  87. {
  88. result = strdup(inCurrentModule.c_str());
  89. }
  90. else if(moduleDefinitions[name])
  91. {
  92. result = strdup(name);
  93. }
  94. else
  95. {
  96. fprintf(stderr,"warning: qualifyName failed for %s\n",name);
  97. result = strdup(name);
  98. }
  99. return result;
  100. }
  101. /* NamespaceHelper */
  102. NamespaceHelper::NamespaceHelper(FILE *outputfile) : out(outputfile)
  103. {
  104. }
  105. NamespaceHelper::~NamespaceHelper()
  106. {
  107. leaveAll();
  108. }
  109. void NamespaceHelper::setFromSymbol(string symbol)
  110. {
  111. list<string> symlist = symbolToList(symbol);
  112. symlist.pop_back();
  113. /* check that the current namespace doesn't contain wrong parts at end */
  114. list<string>::iterator ni,si;
  115. ni = currentNamespace.begin();
  116. si = symlist.begin();
  117. long wrong = currentNamespace.size();
  118. while(ni != currentNamespace.end() && si != symlist.end() && *ni == *si)
  119. {
  120. ni++;
  121. si++;
  122. wrong--;
  123. }
  124. while(wrong--)
  125. {
  126. fprintf(out,"}\n");
  127. }
  128. /* enter new components at the end */
  129. while(si != symlist.end())
  130. {
  131. fprintf(out,"namespace %s {\n",(*si++).c_str());
  132. }
  133. currentNamespace = symlist;
  134. }
  135. void NamespaceHelper::leaveAll()
  136. {
  137. setFromSymbol("unqualified");
  138. }
  139. string NamespaceHelper::printableForm(string symbol)
  140. {
  141. list<string> symlist = symbolToList(symbol);
  142. list<string> current = currentNamespace;
  143. while(!current.empty())
  144. {
  145. // namespace longer than symbol?
  146. assert(!symlist.empty());
  147. if(*current.begin() == *symlist.begin())
  148. {
  149. current.pop_front();
  150. symlist.pop_front();
  151. }
  152. else
  153. {
  154. return "::"+symbol;
  155. }
  156. }
  157. return listToSymbol(symlist);
  158. }
  159. string NamespaceHelper::nameOf(string symbol)
  160. {
  161. if(symbol.empty()) return "";
  162. list<string> symlist = symbolToList(symbol);
  163. return symlist.back();
  164. }
  165. string NamespaceHelper::namespaceOf(string symbol)
  166. {
  167. list<string> symlist = symbolToList(symbol);
  168. if(symlist.size() < 2) return "";
  169. symlist.pop_back();
  170. return listToSymbol(symlist);
  171. }