utility_io.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /** \file itasc/kdl/utilities/utility_io.cpp
  2. * \ingroup itasc
  3. */
  4. /*****************************************************************************
  5. * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
  6. *
  7. * \version
  8. * ORO_Geometry V0.2
  9. *
  10. * \par History
  11. * - $log$
  12. *
  13. * \par Release
  14. * $Name: $
  15. * \todo
  16. * make IO routines more robust against the differences between DOS/UNIX end-of-line style.
  17. ****************************************************************************/
  18. #include "utility_io.h"
  19. #include "error.h"
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23. namespace KDL {
  24. //
  25. // _functions are private functions
  26. //
  27. void _check_istream(std::istream& is)
  28. {
  29. if ((!is.good())&&(is.eof()) )
  30. {
  31. throw Error_BasicIO_File();
  32. }
  33. }
  34. // Eats until the end of the line
  35. static int _EatUntilEndOfLine( std::istream& is, int* countp=NULL) {
  36. int ch;
  37. int count;
  38. count = 0;
  39. do {
  40. ch = is.get();
  41. count++;
  42. _check_istream(is);
  43. } while (ch!='\n');
  44. if (countp!=NULL) *countp = count;
  45. return ch;
  46. }
  47. // Eats until the end of the comment
  48. static int _EatUntilEndOfComment( std::istream& is, int* countp=NULL) {
  49. int ch;
  50. int count;
  51. count = 0;
  52. int prevch;
  53. ch = 0;
  54. do {
  55. prevch = ch;
  56. ch = is.get();
  57. count++;
  58. _check_istream(is);
  59. if ((prevch=='*')&&(ch=='/')) {
  60. break;
  61. }
  62. } while (true);
  63. if (countp!=NULL) *countp = count;
  64. ch = is.get();
  65. return ch;
  66. }
  67. // Eats space-like characters and comments
  68. // possibly returns the number of space-like characters eaten.
  69. static int _EatSpace( std::istream& is,int* countp=NULL) {
  70. int ch;
  71. int count;
  72. count=-1;
  73. do {
  74. _check_istream(is);
  75. ch = is.get();
  76. count++;
  77. if (ch == '#') {
  78. ch = _EatUntilEndOfLine(is,&count);
  79. }
  80. if (ch == '/') {
  81. ch = is.get();
  82. if (ch == '/') {
  83. ch = _EatUntilEndOfLine(is,&count);
  84. } else if (ch == '*') {
  85. ch = _EatUntilEndOfComment(is,&count);
  86. } else {
  87. is.putback(ch);
  88. ch = '/';
  89. }
  90. }
  91. } while ((ch==' ')||(ch=='\n')||(ch=='\t'));
  92. if (countp!=NULL) *countp = count;
  93. return ch;
  94. }
  95. // Eats whites, returns, tabs and the delim character
  96. // Checks whether delim char. is encountered.
  97. void Eat( std::istream& is, int delim )
  98. {
  99. int ch;
  100. ch=_EatSpace(is);
  101. if (ch != delim) {
  102. throw Error_BasicIO_Exp_Delim();
  103. }
  104. ch=_EatSpace(is);
  105. is.putback(ch);
  106. }
  107. // Eats whites, returns, tabs and the delim character
  108. // Checks whether delim char. is encountered.
  109. // EatEnd does not eat all space-like char's at the end.
  110. void EatEnd( std::istream& is, int delim )
  111. {
  112. int ch;
  113. ch=_EatSpace(is);
  114. if (ch != delim) {
  115. throw Error_BasicIO_Exp_Delim();
  116. }
  117. }
  118. // For each space in descript, this routine eats whites,tabs, and newlines (at least one)
  119. // There should be no consecutive spaces in the description.
  120. // for each letter in descript, its reads the corresponding letter in the output
  121. // the routine is case insensitive.
  122. // Simple routine, enough for our purposes.
  123. // works with ASCII chars
  124. inline char Upper(char ch)
  125. {
  126. /*if (('a'<=ch)&&(ch<='z'))
  127. return (ch-'a'+'A');
  128. else
  129. return ch;
  130. */
  131. return toupper(ch);
  132. }
  133. void Eat(std::istream& is,const char* descript)
  134. {
  135. // eats whites before word
  136. char ch;
  137. char chdescr;
  138. ch=_EatSpace(is);
  139. is.putback(ch);
  140. const char* p;
  141. p = descript;
  142. while ((*p)!=0) {
  143. chdescr = (char)Upper(*p);
  144. if (chdescr==' ') {
  145. int count=0;
  146. ch=_EatSpace(is,&count);
  147. is.putback(ch);
  148. if (count==0) {
  149. throw Error_BasicIO_Not_A_Space();
  150. }
  151. } else {
  152. ch=(char)is.get();
  153. if (chdescr!=Upper(ch)) {
  154. throw Error_BasicIO_Unexpected();
  155. }
  156. }
  157. p++;
  158. }
  159. }
  160. void EatWord(std::istream& is,const char* delim,char* storage,int maxsize)
  161. {
  162. int ch;
  163. char* p;
  164. int size;
  165. // eat white before word
  166. ch=_EatSpace(is);
  167. p = storage;
  168. size=0;
  169. int count = 0;
  170. while ((count==0)&&(strchr(delim,ch)==NULL)) {
  171. *p = (char) toupper(ch);
  172. ++p;
  173. if (size==maxsize) {
  174. throw Error_BasicIO_ToBig();
  175. }
  176. _check_istream(is);
  177. ++size;
  178. //ch = is.get();
  179. ch =_EatSpace(is,&count);
  180. }
  181. *p=0;
  182. is.putback(ch);
  183. }
  184. }