00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "basepacking.h"
00036 #include "parsers.h"
00037
00038 #include <float.h>
00039 #include <stdio.h>
00040 #include <iostream>
00041 #include <vector>
00042 using namespace std;
00043 using namespace parse_utils;
00044 using namespace basepacking_h;
00045
00046
00047
00048
00049 const double Dimension::INFTY = 1e100;
00050 const double Dimension::EPSILON_ACCURACY = 1e10;
00051 const int Dimension::UNDEFINED = -1;
00052 const int Dimension::ORIENT_NUM = 8;
00053
00054 const int HardBlockInfoType::ORIENT_NUM = Dimension::ORIENT_NUM;
00055
00056 void HardBlockInfoType::set_dimensions(int i,
00057 double w,
00058 double h)
00059 {
00060 in_blocks[i].width.resize(ORIENT_NUM);
00061 in_blocks[i].height.resize(ORIENT_NUM);
00062 for (int j = 0; j < ORIENT_NUM; j++)
00063 if (j % 2 == 0)
00064 {
00065 in_blocks[i].width[j] = w;
00066 in_blocks[i].height[j] = h;
00067 }
00068 else
00069 {
00070 in_blocks[i].width[j] = h;
00071 in_blocks[i].height[j] = w;
00072 }
00073 }
00074
00075 HardBlockInfoType::HardBlockInfoType(ifstream& ins,
00076 const string& format)
00077 : blocks(in_blocks),
00078 block_names(in_block_names)
00079 {
00080 if (format == "txt")
00081 ParseTxt(ins);
00082 else if (format == "blocks")
00083 ParseBlocks(ins);
00084 else
00085 {
00086 cout << "ERROR: invalid format: " << format << endl;
00087 exit(1);
00088 }
00089 }
00090
00091 void HardBlockInfoType::ParseTxt(ifstream& ins)
00092 {
00093 int blocknum = -1;
00094 ins >> blocknum;
00095
00096 if (!ins.good())
00097 {
00098 cout << "ERROR: cannot read the block count." << endl;
00099 exit(1);
00100 }
00101
00102 in_blocks.resize(blocknum+2);
00103 in_block_names.resize(blocknum+2);
00104 for (int i = 0; i < blocknum; i++)
00105 {
00106 double w, h;
00107 ins >> w >> h;
00108
00109 if (!ins.good())
00110 {
00111 cout << "ERROR: cannot read block no." << i << endl;
00112 exit(1);
00113 }
00114
00115 set_dimensions(i, w, h);
00116
00117 char temp[100];
00118 temp[0] = '\0';
00119 sprintf(temp, "%d", i);
00120 in_block_names[i] = temp;
00121 }
00122 set_dimensions(blocknum, 0, Dimension::INFTY);
00123 in_block_names[blocknum] = "LEFT";
00124
00125 set_dimensions(blocknum+1, Dimension::INFTY, 0);
00126 in_block_names[blocknum+1] = "BOTTOM";
00127 }
00128
00129
00130
00131 void HardBlockInfoType::ParseBlocks(ifstream& ins)
00132 {
00133 char block_name[100];
00134 char block_type[100];
00135 char tempWord[100];
00136
00137 int numSoftBl=0;
00138 int numHardBl=0;
00139 int numTerm=0;
00140
00141 int indexBlock=0;
00142
00143 if(!ins)
00144 {
00145 cout << "ERROR: .blocks file could not be opened successfully"
00146 << endl;
00147 exit(1);
00148 }
00149
00150 skiptoeol(ins);
00151 while(!ins.eof())
00152 {
00153 ins >> tempWord;
00154 if(!(strcmp(tempWord,"NumSoftRectangularBlocks")))
00155 break;
00156 }
00157
00158 if (!ins.good())
00159 {
00160 cout << "ERROR in parsing .blocks file." << endl;
00161 exit(1);
00162 }
00163
00164 ins >> tempWord;
00165 ins >> numSoftBl;
00166 if (numSoftBl != 0)
00167 {
00168 cout << "ERROR: soft block packing is not supported for now." << endl;
00169 exit(0);
00170 }
00171
00172 while(!ins.eof())
00173 {
00174 ins >> tempWord;
00175 if (!(strcmp(tempWord, "NumHardRectilinearBlocks")))
00176 break;
00177 }
00178 ins >> tempWord;
00179 ins >> numHardBl;
00180
00181 while(!ins.eof())
00182 {
00183 ins >> tempWord;
00184 if (!(strcmp(tempWord, "NumTerminals")))
00185 break;
00186 }
00187 ins >> tempWord;
00188 ins >> numTerm;
00189
00190 in_blocks.resize(numHardBl+2);
00191 in_block_names.resize(numHardBl+2);
00192 while(ins.good())
00193 {
00194 block_type[0] = '\0';
00195 eatblank(ins);
00196
00197 if (ins.eof())
00198 break;
00199 if (ins.peek() == '#')
00200 eathash(ins);
00201 else
00202 {
00203 eatblank(ins);
00204 if (ins.peek() == '\n' || ins.peek() == '\r')
00205 {
00206 ins.get();
00207 continue;
00208 }
00209
00210 ins >> block_name;
00211 ins >> block_type;
00212
00213 if (!strcmp(block_type, "softrectangular"))
00214 {
00215 cout << "ERROR: soft block packing is not supported now." << endl;
00216 exit(1);
00217 }
00218 else if (!strcmp(block_type,"hardrectilinear"))
00219 {
00220 Point tempPoint;
00221 vector<Point> vertices;
00222 int numVertices;
00223 bool success;
00224 double width, height;
00225
00226 ins >> numVertices;
00227 success = true;
00228 if (numVertices != 4)
00229 {
00230 cout << "ERROR in parsing .blocks file. "
00231 << "rectilinear blocks can be only rectangles for now"
00232 << endl;
00233 exit(1);
00234 }
00235
00236 for (int i=0; i < numVertices; ++i)
00237 {
00238 success &= needCaseChar(ins, '('); ins.get();
00239 ins >> tempPoint.x;
00240 success &= needCaseChar(ins, ','); ins.get();
00241 ins >> tempPoint.y;
00242 success &= needCaseChar(ins, ')'); ins.get();
00243 vertices.push_back(tempPoint);
00244 }
00245 if (!success)
00246 {
00247 cout << "ERROR in parsing .blocks file while processing "
00248 << "hardrectilinear blocks." << endl;
00249 exit(1);
00250 }
00251
00252 width = vertices[2].x - vertices[0].x;
00253 height = vertices[2].y - vertices[0].y;
00254
00255
00256
00257
00258
00259
00260 set_dimensions(indexBlock, width, height);
00261 if (indexBlock >= int(block_names.size()))
00262 {
00263 cout << "ERROR: too many hard block specified." << endl;
00264 exit(1);
00265 }
00266 in_block_names[indexBlock] = block_name;
00267 ++indexBlock;
00268 }
00269 else if (!strcmp(block_type,"terminal"))
00270 { }
00271 else if (ins.good())
00272 {
00273 cout << "ERROR: invalid block type: " << block_type << endl;
00274 exit(1);
00275 }
00276 }
00277 }
00278 ins.close();
00279
00280 if (numSoftBl+numHardBl != indexBlock)
00281 {
00282 cout << "ERROR in parsing .blocks file. # blocks do not tally "
00283 << (indexBlock) << " vs. "
00284 << (numSoftBl+numHardBl) << endl;
00285 exit(1);
00286 }
00287 set_dimensions(numHardBl, 0, Dimension::INFTY);
00288 in_block_names[numHardBl] = "LEFT";
00289
00290 set_dimensions(numHardBl+1, Dimension::INFTY, 0);
00291 in_block_names[numHardBl+1] = "BOTTOM";
00292 }
00293