Corrected the LEF read routine so that it parses an ORIGIN line in

a LEF macro that has parentheses around the coordinates.  Weirdly,
this is requires by the LEF/DEF spec, but is rarely if ever seen
in actual LEF files.  Go figure.
This commit is contained in:
Tim Edwards 2020-05-10 12:21:04 -04:00
parent 35175882bc
commit f0d2c8db0f
2 changed files with 51 additions and 6 deletions

View File

@ -1 +1 @@
8.3.6
8.3.7

View File

@ -802,6 +802,55 @@ LefReadLayer(f, obstruct)
return LefReadLayers(f, obstruct, (TileType *)NULL, (Rect **)NULL);
}
/*
*------------------------------------------------------------
* LefReadLefPoint --
*
* Read a LEF point record from the file, and
* return the two coordinates in LEF units (floating-point).
*
* Results:
* Return 0 on success, 1 on error.
*
* Side Effects:
* Reads input from file f;
* Returns values for the two point coordinates, as type
* float, in "xp" and "yp".
*
* Note:
* Most LEF files do not put parentheses around points, e.g.,
* in the ORIGIN statement, although the LEF specification
* definition of a point insists that it must. Therefore
* we attempt to parse points correctly either way.
*
*------------------------------------------------------------
*/
int
LefReadLefPoint(f, xp, yp)
FILE *f;
float *xp, *yp;
{
char *token;
bool needMatch = FALSE;
token = LefNextToken(f, TRUE);
if (*token == '(')
{
token = LefNextToken(f, TRUE);
needMatch = TRUE;
}
if (!token || sscanf(token, "%f", xp) != 1) return 1;
token = LefNextToken(f, TRUE);
if (!token || sscanf(token, "%f", yp) != 1) return 1;
if (needMatch)
{
token = LefNextToken(f, TRUE);
if (*token != ')') return 1;
}
return 0;
}
/*
*------------------------------------------------------------
* LefReadRect --
@ -1620,11 +1669,7 @@ size_error:
LefEndStatement(f);
break;
case LEF_ORIGIN:
token = LefNextToken(f, TRUE);
if (!token || sscanf(token, "%f", &x) != 1) goto origin_error;
token = LefNextToken(f, TRUE);
if (!token || sscanf(token, "%f", &y) != 1) goto origin_error;
if (LefReadLefPoint(f, x, y) != 0) goto origin_error;
lefBBox.r_xbot = -(int)roundf(x / oscale);
lefBBox.r_ybot = -(int)roundf(y / oscale);
if (has_size)