std.easygen.cpp: easygen.cpp
#define __my__release
#pragma comment(lib,"parser.lib")
//TODO:
// arithmetic overflow check
// exception handling
// speedUp, FE, expressions cache
#include "easygen.h"
#include "conio.h"
using namespace std;
const int maxStringLen = 10240;
const char* randseedParamName = "randseed";
const char defaultSpaceChar = ' ';
const char* formalInputFName = "formal.input";
bool wasSpaceChar;
void genError::processParseError()
{
if (wasError()) {
parseError* tmp = getLastError();
ostringstream ss;
ss << string(errorMessageByCode(tmp->code))
<< ". Line: " << tmp->line << ", pos: " << tmp->pos;
throw genError(ss.str());
}
}
char* testInfo::loadFormatFile(const string& fileName)
{
ifstream f(fileName.c_str());
char tmp[maxStringLen];
string res;
while (1) {
f.getline(tmp, maxStringLen);
size_t len = strlen(tmp);
tmp[len+1] = 0; tmp[len] = '\n';
if (!f) break;
res += tmp;
}
char* res1 = (char*)malloc(res.length() + 1);
strcpy(res1, res.c_str());
return res1;
}
testInfo::testInfo(int argc, char* argv[])
{
string s;
size_t i,j,k;
for (i = 1; i < (size_t)argc; i++) {
if (i > 1) s += " ";
s += argv[i];
}
i = 0; k = s.length();
while (i < k) {
while (i < k && isspace(s[i])) ++i;
if (i >= k) break;
j = i;
while (i < k && s[i] != '=' && !isspace(s[i])) ++i;
if (i >= k) throw genError("illegal command line arguments");
string val, name = s.substr(j, i-j);
while (i < k && isspace(s[i]) && s[i] != '=') ++i;
if (i >= k || s[i] != '=') throw genError("illegal command line arguments");
++i;
while (i < k && isspace(s[i])) ++i;
if (i >= k) throw genError("illegal command line arguments");
j = i;
if (s[i] == '\'') {
++i; bool screen = false, ok = false;
val = "";
while (i < k) {
if (screen) {
if (s[i] == '\\' || s[i] == '\'') val += s[i];
else throw genError("illegal char after \\ in command line");
} else {
if (s[i] == '\\') screen = true;
else if (s[i] == '\'') {ok = true; i++; break;}
else val += s[i];
}
i++;
}
if (!ok) throw genError("illegal string value in conmand line");
} else {
while (i < k && !isspace(s[i])) ++i;
val = s.substr(j, i-j);
}
if (params.find(name) != params.end())
throw genError("double param defenition in command line");
params[name] = val;
}
buf = loadFormatFile(formalInputFName);
initialize(buf);
objRecord* tmp = parseObjRecord();
genError::processParseError();
desc.a.pointerToData = 0; desc.a.recPart = tmp;
desc.a = mallocRecord(desc.a, 1);
wasSpaceChar = true;
paramsToVars();
}
testInfo::~testInfo()
{
print();
destroyRecData(desc.a);
objRecordDestructor(desc.a.recPart);
finalize();
free(buf);
}
INT64 testInfo::getIntParam(const string& name)
{
string tmp = params[name];
if (tmp.length() > getMaxIntLen()) throw genError("too long integer in command line");
istringstream ss(tmp); INT64 res;
ss >> res;
if (ss.fail()) throw genError("trying to get int param from non-int param");
return res;
}
real testInfo::getFloatParam(const string& name)
{
string tmp = params[name];
istringstream ss(tmp); real res;
ss >> res;
if (ss.fail()) throw genError("trying to get float param from non-float param");
return res;
}
void testInfo::paramsToVars()
{
for (map::iterator i = params.begin(); i != params.end(); ++i) {
if (i->first == randseedParamName) setRandSeed(getIntParam(i->first));
else {
objWithData tmp = findObject(i->first.c_str(), desc.a, 0);
if (tmp.objPart) {
switch (tmp.objPart->objKind) {
case oInteger:
desc.operator [](i->first) = getIntParam(i->first);
break;
case oFloat:
desc.operator [](i->first) = getFloatParam(i->first);
break;
case oString:
desc.operator [](i->first) = i->second;
break;
}
genError::processParseError();
}
}
}
genError::processParseError();
}
prxObject testInfo::operator [](const string& name)
{
return desc.operator [] (name);
}
void testInfo::print()
{
desc.print();
}
void testInfo::autoGen()
{
desc.autoGen();
}
prxObject prxRecord::operator [](const string& name)
{
objWithData tmp = byName(a, name.c_str());
genError::processParseError();
if (tmp.objPart) return prxObject(tmp);
else throw genError("object with name '" + name + "' not found");
}
void prxRecord::print()
{
if ((!a.pointerToData || !a.pointerToData->data) && a.recPart->n)
throw genError("uninitialized data while printing");
for (int i = 0; i < a.recPart->n; i++) {
objWithData st;
st.objPart = &(a.recPart->seq[i]);
st.pointerToData = &(a.pointerToData->data[i]);
prxObject tmp(st);
tmp.print();
}
}
void prxRecord::autoGen()
{
autoGenRecord(a);
}
prxRecord prxObject::operator [] (int index)
{
recWithData tmp = byIndex(a, index);
genError::processParseError();
return prxRecord(tmp);
}
INT64 prxObject::operator = (const INT64& value)
{
if (a.objPart->objKind != oInteger)
throw genError("trying to assign integer to non-int object");
setIntValue(a, value);
genError::processParseError();
return value;
}
int prxObject::operator = (const int& value)
{
return *this = (INT64)value;
}
real prxObject::operator = (const real& value)
{
if (a.objPart->objKind != oFloat)
throw genError("trying to assign float to non-float object");
setFloatValue(a, value);
genError::processParseError();
return value;
}
string prxObject::operator = (const string& value)
{
if (a.objPart->objKind != oString)
throw genError("trying to assign string to non-string object");
setStrValue(a, value.c_str());
genError::processParseError();
return value;
}
prxObject::operator INT64()
{
if (a.objPart->objKind != oInteger)
throw genError("trying to get integer from non-int object");
INT64 res = getIntValue(a);
genError::processParseError();
return res;
}
prxObject::operator int()
{
return (int)(INT64)(*this);
}
prxObject::operator real()
{
if (a.objPart->objKind != oFloat)
throw genError("trying to get float from non-float object");
real res = getFloatValue(a);
genError::processParseError();
return res;
}
prxObject::operator string()
{
if (a.objPart->objKind != oString)
throw genError("trying to get string from non-string object");
string res(getStrValue(a));
genError::processParseError();
return res;
}
void prxObject::print()
{
if ((!a.pointerToData || !a.pointerToData->value) &&
a.objPart->objKind != oNewLine && a.objPart->objKind != oSoftLine)
throw genError("uninitialized data while printing");
int objk = a.objPart->objKind;
switch (objk) {
case oNewLine: case oSoftLine:
cout << endl; wasSpaceChar = true;
break;
case oInteger: case oFloat: case oString:
if (!wasSpaceChar) cout << defaultSpaceChar;
if (objk == oInteger) {
cout << getIntValue(a);
} else if (objk == oString) {
cout << getStrValue(a);
} else if (objk == oFloat) {
cout << fixed << setprecision(getFloatDig(a)) << getFloatValue(a);
}
genError::processParseError();
wasSpaceChar = 0;
break;
case oSeq:
int n = getSeqLen(a);
for (int i = 1; i <= n; i++) {
prxRecord tmp(byIndex(a, i));
genError::processParseError();
tmp.print();
}
break;
}
}
void prxObject::autoGen()
{
switch (a.objPart->objKind) {
case oNewLine: case oSoftLine: cout << endl; break;
case oInteger: autoGenInt(a); break;
case oFloat: autoGenFloat(a); break;
case oString: autoGenStr(a); break;
case oSeq: autoGenSeq(a); break;
}
}
#ifndef __my__release
/*int main(int argc, char* argv[])
{
freopen("output.txt","w",stdout);
try {
testInfo super(argc, argv);
super.autoGen();
} catch (genError a) {
cout << a.err();
}
*/
/*freopen("format.txt","r",stdin);
char s[10000]; cin.getline(s,10000);
parseError* res = validate(s);
cout << res->code;
fclose(stdin);*/
/* fclose(stdout);
return 0;
} */
const int maxn = 100;
int n, t[maxn][maxn], ans[maxn];
int main(int argc, char* argv[])
{
try {
testInfo a(argc, argv);
n = a["n"];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) t[i][j] = 0;
else {
t[i][j] = genRandInt(0, 2);
if (t[i][j] == 2) t[i][j] = 3;
}
ans[i] += t[i][j];
}
a["a"][i]["sc"] = ans[i];
}
} catch (genError a) {
cout << a.err();
}
return 0;
}
#endif