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