FortranFormat.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "FortranFormat.h"
00019 #include "Error.h"
00020
00021 FortranFormat::FortranFormat()
00022 {
00023 inputPos = -1;
00024 endOfPattern = false;
00025 }
00026
00027 void FortranFormat::SetInputFile(IFILE & file)
00028 {
00029 input = file;
00030 inputPos = -1;
00031 endOfPattern = false;
00032 }
00033
00034 void FortranFormat::SetFormat(const String & formatString)
00035 {
00036 format = formatString;
00037
00038 inputPos = -1;
00039 endOfPattern = false;
00040
00041 repeatCount = 0;
00042
00043 format.Clear();
00044
00045
00046
00047 int level = 0;
00048 for (int i = 0; i < formatString.Length(); i++)
00049 {
00050 if (formatString[i] == ' ' || formatString[i] == '\t' ||
00051 formatString[i] == '\n' || formatString[i] == '\r')
00052 continue;
00053
00054 if (formatString[i] == '(')
00055 level++;
00056
00057 if (formatString[i] == ')')
00058 level--;
00059
00060 format += formatString[i];
00061
00062 if (level == 0) break;
00063 }
00064
00065 if (format[0] != '(' || format[format.Length() - 1] != ')')
00066 error("Invalid FORTRAN format statement\n\n"
00067 "The statement \"%s\" is not bracketed correctly.\n",
00068 (const char *) formatString);
00069
00070 lastBracket = 1;
00071 lastCount = 0;
00072
00073 formatPos = 1;
00074 repeatCount = 0;
00075
00076 bracketStack.Clear();
00077 bracketCounter.Clear();
00078 bracketCount.Clear();
00079 }
00080
00081 int FortranFormat::GetNextInteger()
00082 {
00083 GetNextField(buffer);
00084
00085 return buffer.AsInteger();
00086 }
00087
00088 char FortranFormat::GetNextCharacter()
00089 {
00090 GetNextField(buffer);
00091
00092 return buffer[0];
00093 }
00094
00095 void FortranFormat::GetNextField(String & field)
00096 {
00097 while (!ProcessToken(field))
00098 ;
00099 }
00100
00101 bool FortranFormat::ProcessToken(String & field)
00102 {
00103
00104 endOfPattern = false;
00105
00106
00107 if (inputPos == -1)
00108 {
00109 inputLine.ReadLine(input);
00110 inputPos = 0;
00111 }
00112
00113
00114 if (repeatCount == 0)
00115 repeatCount = GetIntegerFromFormat();
00116
00117
00118 if (repeatCount == 0)
00119 repeatCount = 1;
00120
00121 int repeatPos = formatPos;
00122
00123
00124 if (format[formatPos] == '(')
00125 {
00126 formatPos++;
00127
00128 bracketStack.Push(formatPos);
00129 bracketCounter.Push(repeatCount);
00130 bracketCount.Push(repeatCount);
00131
00132 repeatCount = 0;
00133
00134 return false;
00135 }
00136
00137
00138 if (format[formatPos] == 'X')
00139 {
00140 formatPos++;
00141
00142
00143 RejectWidth('X');
00144
00145
00146 inputPos += repeatCount;
00147
00148
00149 repeatCount = 0;
00150
00151 FinishField();
00152
00153 return false;
00154 }
00155
00156
00157 if (format[formatPos] == '/')
00158 {
00159 formatPos++;
00160
00161
00162 RejectWidth('/');
00163
00164
00165 while (repeatCount--)
00166 inputLine.ReadLine(input);
00167
00168 inputPos = 0;
00169
00170
00171 if (format[formatPos] == ',' || format[formatPos] || ')')
00172 FinishField();
00173
00174 return false;
00175 }
00176
00177
00178 if (format[formatPos] == 'Q' || format[formatPos] == 'P' || format[formatPos] == 'B')
00179 {
00180 formatPos++;
00181
00182 int problemStart = formatPos;
00183
00184 while (format[formatPos] != ',' && format[formatPos] != ')' && format[formatPos] != '/')
00185 formatPos++;
00186
00187 error("Unsupported pattern in FORMAT statement\n\n"
00188 "Statement \"%s\" includes unsupporterd pattern '%s'\n",
00189 (const char *) format,
00190 (const char *) format.SubStr(problemStart, formatPos - problemStart));
00191 }
00192
00193 if (format[formatPos] == ':')
00194 {
00195 formatPos++;
00196
00197 if (format[formatPos] == ',' || format[formatPos] || ')')
00198 FinishField();
00199
00200 repeatCount = 0;
00201
00202 endOfPattern = true;
00203
00204 return false;
00205 }
00206
00207
00208
00209
00210 int typeStart = formatPos;
00211
00212 while (CharacterFollows())
00213 formatPos++;
00214
00215 int typeLen = formatPos - typeStart;
00216
00217
00218 int width = GetIntegerFromFormat();
00219
00220 if (width == 0)
00221 error("Unrecognized FORMAT statement\n\n"
00222 "Statement \"%s\" is missing a width specifier for a field of type '%s'\n",
00223 (const char *) format, (const char *) format.SubStr(typeStart, typeLen));
00224
00225
00226 if (format[typeStart] == 'T')
00227 {
00228
00229 if (format[typeStart + 1] == 'L')
00230 inputPos = width > inputPos ? 0 : inputPos - width;
00231
00232 else if (format[typeStart + 1] == 'R')
00233 inputPos += width;
00234
00235 else
00236 inputPos = width;
00237
00238 repeatCount--;
00239
00240 if (repeatCount)
00241 formatPos = repeatPos;
00242 else
00243 FinishField();
00244
00245 return false;
00246 }
00247
00248
00249 field.Copy(inputLine, inputPos, width);
00250 field.Trim();
00251
00252 inputPos += width;
00253
00254 repeatCount--;
00255
00256 if (repeatCount)
00257 formatPos = repeatPos;
00258 else
00259 FinishField();
00260
00261 return true;
00262 }
00263
00264 int FortranFormat::GetIntegerFromFormat()
00265 {
00266 int result = 0;
00267
00268 while (DigitFollows())
00269 result = result * 10 + (int)(format[formatPos++] - '0');
00270
00271 return result;
00272 }
00273
00274 bool FortranFormat::DigitFollows()
00275 {
00276 return (format[formatPos] >= '0') && (format[formatPos] <= '9');
00277 }
00278
00279 bool FortranFormat::CharacterFollows()
00280 {
00281 return (format[formatPos] >= 'A') && (format[formatPos] <= 'Z');
00282 }
00283
00284 void FortranFormat::RejectWidth(char ch)
00285 {
00286
00287 if (DigitFollows())
00288 error("Unrecognized FORTRAN format statement\n\n"
00289 "The statement \"%s\" includes width specifier for field of type '%c'.\n",
00290 (const char *) format, ch);
00291 }
00292
00293 void FortranFormat::FinishField(bool)
00294 {
00295
00296 while (format[formatPos] != ',' && format[formatPos] != ')')
00297 {
00298 if (format[formatPos] == '/')
00299 return;
00300
00301 formatPos++;
00302 }
00303
00304
00305 if (format[formatPos] == ',')
00306 {
00307 formatPos++;
00308 return;
00309 }
00310
00311
00312
00313 if (bracketStack.Length())
00314 {
00315
00316 lastBracket = bracketStack.Pop();
00317 lastCount = bracketCount.Pop();
00318 int lastCounter = bracketCounter.Pop() - 1;
00319
00320
00321 if (lastCounter)
00322 {
00323 bracketStack.Push(lastBracket);
00324 bracketCount.Push(lastCount);
00325 bracketCounter.Push(lastCounter);
00326
00327 formatPos = lastBracket;
00328 }
00329 else
00330
00331 {
00332 formatPos++;
00333 FinishField();
00334 return;
00335 }
00336 }
00337 else
00338 {
00339
00340 inputPos = -1;
00341 endOfPattern = true;
00342
00343
00344 formatPos = lastBracket;
00345
00346 if (lastBracket == 1)
00347 return;
00348
00349
00350 bracketStack.Push(lastBracket);
00351 bracketCounter.Push(lastCount);
00352 bracketCount.Push(lastCount);
00353 }
00354 }
00355
00356 void FortranFormat::Flush()
00357 {
00358 while (!endOfPattern)
00359 ProcessToken(buffer);
00360
00361 inputPos = -1;
00362
00363 lastBracket = 1;
00364 lastCount = 0;
00365
00366 formatPos = 1;
00367 repeatCount = 0;
00368
00369 bracketStack.Clear();
00370 bracketCounter.Clear();
00371 bracketCount.Clear();
00372 }