From 51b70f65776cf191cbcbfa66eeef76788b8cf2ab Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 6 Jun 2019 09:59:56 -0400 Subject: [PATCH 1/2] Corrected an error in the LEF/DEF geometry reading, because I discovered that not all LEF/DEF rectangle coordinates are in canonical order. Took the opportunity to update the LefError() routine with an additional argument so that it can separate errors, warnings, and informational messages, and will correctly state whether the output is for a LEF or DEF read operation. --- lef/defRead.c | 90 ++++++++++--------- lef/lefInt.h | 15 +++- lef/lefRead.c | 240 +++++++++++++++++++++++++++++++++++++------------- lef/lefTech.c | 7 +- 4 files changed, 240 insertions(+), 112 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index 0b5e3261..b71d6ddd 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -105,7 +105,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) if (routeLayer < 0) { - LefError("Unknown layer type \"%s\" for NEW route\n", token); + LefError(DEF_ERROR, "Unknown layer type \"%s\" for NEW route\n", token); continue; } paintLayer = routeLayer; @@ -116,7 +116,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) token = LefNextToken(f, TRUE); if (sscanf(token, "%f", &w) != 1) { - LefError("Bad width in special net\n"); + LefError(DEF_ERROR, "Bad width in special net\n"); continue; } if (w != 0) @@ -138,7 +138,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) else if (valid == FALSE) { - LefError("Route has via name \"%s\" but no points!\n", token); + LefError(DEF_ERROR, "Route has via name \"%s\" but no points!\n", token); continue; } he = HashLookOnly(&LefInfo, token); @@ -197,7 +197,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else if ((paintLayer = DBTechNameType(LefLower(token))) >= 0) { - LefError("Error: Via \"%s\" named but undefined.\n", token); + LefError(DEF_ERROR, "Error: Via \"%s\" named but undefined.\n", + token); newRoute->r_r.r_xbot = refp.p_x - paintWidth; newRoute->r_r.r_ybot = refp.p_y - paintWidth; newRoute->r_r.r_xtop = refp.p_x + paintWidth; @@ -209,7 +210,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) newRoute->r_r.r_ytop >>= 1; } else - LefError("Via name \"%s\" unknown in route.\n", token); + LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token); /* After the via, the new route layer becomes whatever */ /* residue of the via was NOT the previous route layer. */ @@ -244,7 +245,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } } else - LefError("Via name \"%s\" unknown in route.\n", token); + LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token); } else { @@ -261,7 +262,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { if (valid == FALSE) { - LefError("No reference point for \"*\" wildcard\n"); + LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n"); goto endCoord; } } @@ -271,7 +272,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - LefError("Cannot parse X coordinate.\n"); + LefError(DEF_ERROR, "Cannot parse X coordinate.\n"); goto endCoord; } token = LefNextToken(f, TRUE); /* read Y */ @@ -279,7 +280,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { if (valid == FALSE) { - LefError("No reference point for \"*\" wildcard\n"); + LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n"); freeMagic(newRoute); newRoute = NULL; goto endCoord; @@ -291,7 +292,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - LefError("Cannot parse Y coordinate.\n"); + LefError(DEF_ERROR, "Cannot parse Y coordinate.\n"); goto endCoord; } @@ -306,7 +307,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { /* non-default route extension */ if (sscanf(token, "%f", &z) != 1) - LefError("Can't parse route extension value.\n"); + LefError(DEF_ERROR, "Can't parse route extension value.\n"); /* all values will be divided by 2, so we need */ /* to multiply up by 2 now. */ @@ -326,7 +327,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* Skip over nonmanhattan segments, reset the reference */ /* point, and output a warning. */ - LefError("Can't deal with nonmanhattan geometry in route.\n"); + LefError(DEF_ERROR, "Can't deal with nonmanhattan geometry in route.\n"); locarea.r_xbot = refp.p_x; locarea.r_ybot = refp.p_y; } @@ -471,7 +472,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) keyword = Lookup(token, net_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in NET " + LefError(DEF_INFO, "Unknown keyword \"%s\" in NET " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -508,7 +509,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) subkey = Lookup(token, net_property_keys); if (subkey < 0) { - LefError("Unknown net property \"%s\" in " + LefError(DEF_INFO, "Unknown net property \"%s\" in " "NET definition; ignoring.\n", token); continue; } @@ -530,7 +531,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) case DEF_NET_END: if (!LefParseEndStatement(f, sname)) { - LefError("Net END statement missing.\n"); + LefError(DEF_ERROR, "Net END statement missing.\n"); keyword = -1; } break; @@ -542,7 +543,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) TxPrintf(" Processed %d%s nets total.\n", processed, (special) ? " special" : ""); else - LefError("Warning: Number of nets read (%d) does not match " + LefError(DEF_WARNING, "Number of nets read (%d) does not match " "the number declared (%d).\n", processed, total); freeMagic((char *)defLayerMap); @@ -600,7 +601,7 @@ DefReadLocation(use, f, oscale, tptr) keyword = Lookup(token, orientations); if (keyword < 0) { - LefError("Unknown macro orientation \"%s\".\n", token); + LefError(DEF_ERROR, "Unknown macro orientation \"%s\".\n", token); return -1; } @@ -668,7 +669,7 @@ DefReadLocation(use, f, oscale, tptr) return 0; parse_error: - LefError("Cannot parse location: must be ( X Y ) orient\n"); + LefError(DEF_ERROR, "Cannot parse location: must be ( X Y ) orient\n"); return -1; } @@ -755,7 +756,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in PINS " + LefError(DEF_INFO, "Unknown keyword \"%s\" in PINS " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -769,7 +770,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (pending) { - LefError("Pin specified without layer, was not placed.\n"); + LefError(DEF_ERROR, "Pin specified without layer, was not placed.\n"); } /* Update the record of the number of pins */ @@ -781,7 +782,7 @@ DefReadPins(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%2047s", pinname) != 1) { - LefError("Bad pin statement: Need pin name\n"); + LefError(DEF_ERROR, "Bad pin statement: Need pin name\n"); LefEndStatement(f); break; } @@ -799,7 +800,7 @@ DefReadPins(f, rootDef, sname, oscale, total) subkey = Lookup(token, pin_property_keys); if (subkey < 0) { - LefError("Unknown pin property \"%s\" in " + LefError(DEF_ERROR, "Unknown pin property \"%s\" in " "PINS definition; ignoring.\n", token); continue; } @@ -814,7 +815,7 @@ DefReadPins(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_classes); if (subkey < 0) - LefError("Unknown pin class\n"); + LefError(DEF_ERROR, "Unknown pin class\n"); else pinDir = lef_class_to_bitmask[subkey]; break; @@ -869,7 +870,7 @@ DefReadPins(f, rootDef, sname, oscale, total) case DEF_PINS_END: if (!LefParseEndStatement(f, sname)) { - LefError("Pins END statement missing.\n"); + LefError(DEF_ERROR, "Pins END statement missing.\n"); keyword = -1; } break; @@ -880,7 +881,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d pins total.\n", processed); else - LefError("Warning: Number of pins read (%d) does not match " + LefError(DEF_WARNING, "Number of pins read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -939,7 +940,7 @@ DefReadVias(f, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in VIAS " + LefError(DEF_INFO, "Unknown keyword \"%s\" in VIAS " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -957,7 +958,7 @@ DefReadVias(f, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%2047s", vianame) != 1) { - LefError("Bad via statement: Need via name\n"); + LefError(DEF_ERROR, "Bad via statement: Need via name\n"); LefEndStatement(f); break; } @@ -977,7 +978,7 @@ DefReadVias(f, sname, oscale, total) } else { - LefError("Warning: Composite via \"%s\" redefined.\n", vianame); + LefError(DEF_WARNING, "Composite via \"%s\" redefined.\n", vianame); lefl = LefRedefined(lefl, vianame); } @@ -993,7 +994,7 @@ DefReadVias(f, sname, oscale, total) subkey = Lookup(token, via_property_keys); if (subkey < 0) { - LefError("Unknown via property \"%s\" in " + LefError(DEF_INFO, "Unknown via property \"%s\" in " "VIAS definition; ignoring.\n", token); continue; } @@ -1010,7 +1011,7 @@ DefReadVias(f, sname, oscale, total) case DEF_VIAS_END: if (!LefParseEndStatement(f, sname)) { - LefError("Vias END statement missing.\n"); + LefError(DEF_ERROR, "Vias END statement missing.\n"); keyword = -1; } break; @@ -1021,7 +1022,7 @@ DefReadVias(f, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d vias total.\n", processed); else - LefError("Warning: Number of vias read (%d) does not match " + LefError(DEF_WARNING, "Number of vias read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -1093,7 +1094,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in COMPONENT " + LefError(DEF_INFO, "Unknown keyword \"%s\" in COMPONENT " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -1111,7 +1112,8 @@ DefReadComponents(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%511s", usename) != 1) { - LefError("Bad component statement: Need use and macro names\n"); + LefError(DEF_ERROR, "Bad component statement: Need " + "use and macro names\n"); LefEndStatement(f); break; } @@ -1129,8 +1131,8 @@ DefReadComponents(f, rootDef, sname, oscale, total) defMacro->cd_flags &= ~CDNOTFOUND; if (!DBCellRead(defMacro, (char *)NULL, TRUE, NULL)) { - LefError("Cell %s is not defined. Maybe you have not " - "read the corresponding LEF file?\n", + LefError(DEF_ERROR, "Cell %s is not defined. Maybe you " + "have not read the corresponding LEF file?\n", token); LefEndStatement(f); DBCellDeleteDef(defMacro); @@ -1163,7 +1165,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) subkey = Lookup(token, property_keys); if (subkey < 0) { - LefError("Unknown component property \"%s\" in " + LefError(DEF_INFO, "Unknown component property \"%s\" in " "COMPONENT definition; ignoring.\n", token); continue; } @@ -1198,7 +1200,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) case DEF_COMP_END: if (!LefParseEndStatement(f, sname)) { - LefError("Component END statement missing.\n"); + LefError(DEF_ERROR, "Component END statement missing.\n"); keyword = -1; } @@ -1216,7 +1218,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d subcell instances total.\n", processed); else - LefError("Warning: Number of subcells read (%d) does not match " + LefError(DEF_WARNING, "Number of subcells read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -1330,7 +1332,7 @@ DefRead(inName) keyword = Lookup(token, sections); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in DEF file; ignoring.\n", token); + LefError(DEF_INFO, "Unknown keyword \"%s\" in DEF file; ignoring.\n", token); LefEndStatement(f); continue; } @@ -1346,7 +1348,7 @@ DefRead(inName) token = LefNextToken(f, TRUE); if (strcmp(token, DBTechName)) { - LefError("Warning: DEF technology name \"%s\" does not" + LefError(DEF_WARNING, "DEF technology name \"%s\" does not" " match current magic technology name \"%s\"\n", token, DBTechName); } @@ -1366,8 +1368,8 @@ DefRead(inName) token = LefNextToken(f, TRUE); if (sscanf(token, "%d", &dscale) != 1) { - LefError("Invalid syntax for UNITS statement.\n"); - LefError("Assuming default value of 100\n"); + LefError(DEF_ERROR, "Invalid syntax for UNITS statement.\n"); + LefError(DEF_INFO, "Assuming default value of 100\n"); dscale = 100; } /* We don't care if the scale is 100, 200, 1000, or 2000. */ @@ -1453,7 +1455,7 @@ DefRead(inName) case DEF_END: if (!LefParseEndStatement(token, "DESIGN")) { - LefError("END statement out of context.\n"); + LefError(DEF_ERROR, "END statement out of context.\n"); keyword = -1; } break; @@ -1461,7 +1463,7 @@ DefRead(inName) if (keyword == DEF_END) break; } TxPrintf("DEF read: Processed %d lines.\n", lefCurrentLine); - LefError(NULL); /* print statement of errors, if any, and reset */ + LefError(DEF_SUMMARY, NULL); /* print statement of errors, if any, and reset */ /* Cleanup */ diff --git a/lef/lefInt.h b/lef/lefInt.h index e6568423..8f069404 100644 --- a/lef/lefInt.h +++ b/lef/lefInt.h @@ -131,7 +131,18 @@ TileType LefReadLayer(); LefMapping *defMakeInverseLayerMap(); -void LefError(char *, ...); /* Variable argument procedure requires */ - /* parameter list. */ +void LefError(int, char *, ...); /* Variable argument procedure requires */ + /* parameter list. */ + +/* Definitions for type passed to LefError() */ + +#define LEF_ERROR 0 +#define LEF_WARNING 1 +#define LEF_INFO 2 +#define LEF_SUMMARY 3 +#define DEF_ERROR 4 +#define DEF_WARNING 5 +#define DEF_INFO 6 +#define DEF_SUMMARY 7 #endif /* _LEFINT_H */ diff --git a/lef/lefRead.c b/lef/lefRead.c index a15a4202..43ef32d9 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -279,11 +279,15 @@ LefNextToken(f, ignore_eol) /* *------------------------------------------------------------ * - * LefError -- + * LefDefError -- * * Print an error message (via TxError) giving the line * number of the input file on which the error occurred. * + * "type" is one of the following (see lef.h): + * LEF_ERROR, LEF_WARNING, LEF_INFO, + * DEF_ERROR, DEF_WARNING, DEF_INFO + * * Results: * None. * @@ -294,34 +298,126 @@ LefNextToken(f, ignore_eol) */ void -LefError(char *fmt, ...) +LefError(int type, char *fmt, ...) { - static int errors = 0; + static int errors = 0, warnings = 0, messages = 0; va_list args; - if (fmt == NULL) /* Special case: report any errors and reset */ + char *lefdeftypes[] = {"LEF", "DEF", "techfile lef section"}; + + int mode, level; + char *lefdeftype; + + switch (type) { + case LEF_INFO: + mode = 0; + level = 0; + break; + case LEF_WARNING: + mode = 0; + level = 1; + break; + case LEF_ERROR: + mode = 0; + level = 2; + break; + case LEF_SUMMARY: + mode = 0; + level = -1; + break; + case DEF_INFO: + mode = 1; + level = 0; + break; + case DEF_WARNING: + mode = 1; + level = 1; + break; + case DEF_ERROR: + mode = 1; + level = 2; + break; + case DEF_SUMMARY: + mode = 1; + level = -1; + break; + } + lefdeftype = lefdeftypes[mode]; + + if ((fmt == NULL) || (level == -1)) { + /* Special case: report any errors and reset */ + if (errors) - { - TxPrintf("LEF Read: encountered %d error%s total.\n", errors, - (errors == 1) ? "" : "s"); - errors = 0; - } + TxPrintf("%s Read: encountered %d error%s total.\n", + lefdeftype, errors, (errors == 1) ? "" : "s"); + + if (warnings) + TxPrintf("%s Read: encountered %d warning%s total.\n", + lefdeftype, warnings, (warnings == 1) ? "" : "s"); + + errors = 0; + warnings = 0; + messages = 0; return; } - if (errors < LEF_MAX_ERRORS) - { - TxError("LEF Read, Line %d: ", lefCurrentLine); - va_start(args, fmt); - Vfprintf(stderr, fmt, args); - va_end(args); - TxFlushErr(); - } - else if (errors == LEF_MAX_ERRORS) - TxError("LEF Read: Further errors will not be reported.\n"); + switch (level) { - errors++; + case 2: + if (errors < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxError("%s read, Line %d (Error): ", lefdeftype, lefCurrentLine); + else + TxError("%s read (Error): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stderr, fmt, args); + va_end(args); + TxFlushErr(); + } + else if (errors == LEF_MAX_ERRORS) + TxError("%s Read: Further errors will not be reported.\n", + lefdeftype); + errors++; + break; + + case 1: + if (warnings < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxError("%s read, Line %d (Warning): ", lefdeftype, lefCurrentLine); + else + TxError("%s read (Warning): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stderr, fmt, args); + va_end(args); + TxFlushErr(); + } + else if (warnings == LEF_MAX_ERRORS) + TxError("%s read: Further warnings will not be reported.\n", + lefdeftype); + warnings++; + break; + + case 0: + if (messages < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxPrintf("%s read, Line %d (Message): ", lefdeftype, lefCurrentLine); + else + TxPrintf("%s read (Message): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stdout, fmt, args); + va_end(args); + TxFlushOut(); + } + else if (messages == LEF_MAX_ERRORS) + TxPrintf("%s read: Further messages will not be reported.\n", + lefdeftype); + messages++; + break; + } } /* @@ -368,7 +464,7 @@ LefParseEndStatement(f, match) token = LefNextToken(f, (match == NULL) ? FALSE : TRUE); if (token == NULL) { - LefError("Bad file read while looking for END statement\n"); + LefError(LEF_ERROR, "Bad file read while looking for END statement\n"); return 0; } @@ -407,7 +503,7 @@ LefParseEndStatement(f, match) * None. * * Side Effects: - * Reads input from the specified file. Prints an + * reads input from the specified file. Prints an * error message if the expected END record cannot * be found. * @@ -445,7 +541,7 @@ LefSkipSection(f, section) } } - LefError("Section %s has no END record!\n", section); + LefError(LEF_ERROR, "Section %s has no END record!\n", section); return; } @@ -623,7 +719,7 @@ LefReadLayers(f, obstruct, lreturn, rreturn) token = LefNextToken(f, TRUE); if (*token == ';') { - LefError("Bad Layer statement\n"); + LefError(LEF_ERROR, "Bad Layer statement\n"); return -1; } else @@ -670,8 +766,8 @@ LefReadLayers(f, obstruct, lreturn, rreturn) } if ((curlayer < 0) && ((!lefl) || (lefl->lefClass != CLASS_IGNORE))) { - LefError("Don't know how to parse layer \"%s\"\n", token); - LefError("Try adding this name to the LEF techfile section\n"); + LefError(LEF_ERROR, "Don't know how to parse layer \"%s\"\n", token); + LefError(LEF_ERROR, "Try adding this name to the LEF techfile section\n"); } } return curlayer; @@ -736,6 +832,7 @@ LefReadRect(f, curlayer, oscale) char *token; float llx, lly, urx, ury; static Rect paintrect; + Rect lefrect; bool needMatch = FALSE; token = LefNextToken(f, TRUE); @@ -768,16 +865,23 @@ LefReadRect(f, curlayer, oscale) if (*token != ')') goto parse_error; } if (curlayer < 0) - LefError("No layer defined for RECT.\n"); + { + LefError(LEF_ERROR, "No layer defined for RECT.\n"); + paintrect.r_xbot = paintrect.r_ybot = 0; + paintrect.r_xtop = paintrect.r_ytop = 0; + } else { /* Scale coordinates (microns to magic internal units) */ /* Need to scale grid if necessary! */ - paintrect.r_xbot = (int)roundf(llx / oscale); - paintrect.r_ybot = (int)roundf(lly / oscale); - paintrect.r_xtop = (int)roundf(urx / oscale); - paintrect.r_ytop = (int)roundf(ury / oscale); + lefrect.r_xbot = (int)roundf(llx / oscale); + lefrect.r_ybot = (int)roundf(lly / oscale); + lefrect.r_xtop = (int)roundf(urx / oscale); + lefrect.r_ytop = (int)roundf(ury / oscale); + + /* Insist on non-inverted rectangles */ + GeoCanonicalRect(&lefrect, &paintrect); /* Diagnostic */ /* @@ -791,7 +895,7 @@ LefReadRect(f, curlayer, oscale) return (&paintrect); parse_error: - LefError("Bad port geometry: RECT requires 4 values.\n"); + LefError(LEF_ERROR, "Bad port geometry: RECT requires 4 values.\n"); return (Rect *)NULL; } @@ -836,7 +940,7 @@ LefReadPolygon(f, curlayer, oscale, ppoints) if (token == NULL || *token == ';') break; if (sscanf(token, "%f", &px) != 1) { - LefError("Bad X value in polygon.\n"); + LefError(LEF_ERROR, "Bad X value in polygon.\n"); LefEndStatement(f); break; } @@ -844,12 +948,12 @@ LefReadPolygon(f, curlayer, oscale, ppoints) token = LefNextToken(f, TRUE); if (token == NULL || *token == ';') { - LefError("Missing Y value in polygon point!\n"); + LefError(LEF_ERROR, "Missing Y value in polygon point!\n"); break; } if (sscanf(token, "%f", &py) != 1) { - LefError("Bad Y value in polygon.\n"); + LefError(LEF_ERROR, "Bad Y value in polygon.\n"); LefEndStatement(f); break; } @@ -987,7 +1091,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list) keyword = Lookup(token, geometry_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1082,7 +1187,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list) case LEF_GEOMETRY_END: if (LefParseEndStatement(f, NULL) == 0) { - LefError("Geometry (PORT or OBS) END statement missing.\n"); + LefError(LEF_ERROR, "Geometry (PORT or OBS) END " + "statement missing.\n"); keyword = -1; } break; @@ -1133,12 +1239,12 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale) /* Set this label to be a port */ if (lefMacro->cd_labels == NULL) - LefError("Internal error: No labels in cell!\n"); + LefError(LEF_ERROR, "Internal error: No labels in cell!\n"); else { newlab = lefMacro->cd_lastLabel; if (strcmp(newlab->lab_text, pinName)) - LefError("Internal error: Can't find the label!\n"); + LefError(LEF_ERROR, "Internal error: Can't find the label!\n"); else /* Make this a port */ newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK; } @@ -1248,7 +1354,8 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) keyword = Lookup(token, pin_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1258,7 +1365,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_classes); if (subkey < 0) - LefError("Improper DIRECTION statement\n"); + LefError(LEF_ERROR, "Improper DIRECTION statement\n"); else pinDir = lef_class_to_bitmask[subkey]; LefEndStatement(f); @@ -1267,7 +1374,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_uses); if (subkey < 0) - LefError("Improper USE statement\n"); + LefError(LEF_ERROR, "Improper USE statement\n"); else pinUse = lef_use_to_bitmask[subkey]; LefEndStatement(f); @@ -1310,7 +1417,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) case LEF_PIN_END: if (LefParseEndStatement(f, pinname) == 0) { - LefError("Pin END statement missing.\n"); + LefError(LEF_ERROR, "Pin END statement missing.\n"); keyword = -1; } break; @@ -1404,7 +1511,7 @@ LefReadMacro(f, mname, oscale, importForeign) sprintf(newname, "%250s_%d", mname, suffix); he = HashFind(&lefDefInitHash, newname); } - LefError("Cell \"%s\" was already defined in this file. " + LefError(LEF_WARNING, "Cell \"%s\" was already defined in this file. " "Renaming this cell \"%s\"\n", mname, newname); lefMacro = DBCellLookDef(newname); if (lefMacro == NULL) @@ -1444,7 +1551,8 @@ LefReadMacro(f, mname, oscale, importForeign) keyword = Lookup(token, macro_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1470,7 +1578,7 @@ LefReadMacro(f, mname, oscale, importForeign) LefEndStatement(f); break; size_error: - LefError("Bad macro SIZE; requires values X BY Y.\n"); + LefError(LEF_ERROR, "Bad macro SIZE; requires values X BY Y.\n"); LefEndStatement(f); break; case LEF_ORIGIN: @@ -1489,7 +1597,7 @@ size_error: LefEndStatement(f); break; origin_error: - LefError("Bad macro ORIGIN; requires 2 values.\n"); + LefError(LEF_ERROR, "Bad macro ORIGIN; requires 2 values.\n"); LefEndStatement(f); break; case LEF_SYMMETRY: @@ -1549,7 +1657,7 @@ origin_error: case LEF_MACRO_END: if (LefParseEndStatement(f, mname) == 0) { - LefError("Macro END statement missing.\n"); + LefError(LEF_ERROR, "Macro END statement missing.\n"); keyword = -1; } break; @@ -1589,7 +1697,8 @@ origin_error: } else { - LefError(" Macro does not define size: computing from geometry\n"); + LefError(LEF_WARNING, " Macro does not define size: " + "computing from geometry\n"); /* Set the placement bounding box property to the current bounding box */ lefMacro->cd_flags |= CDFIXEDBBOX; @@ -1718,12 +1827,12 @@ LefAddViaGeometry(f, lefl, curlayer, oscale) if ((currect->r_xtop - currect->r_xbot != edgeSize) || (currect->r_ytop - currect->r_ybot != edgeSize)) { - LefError("Warning: Cut size for magic type \"%s\" (%d x %d) does " + LefError(LEF_WARNING, "Cut size for magic type \"%s\" (%d x %d) does " "not match LEF/DEF\n", DBTypeLongNameTbl[lefl->type], edgeSize, edgeSize); - LefError(" via cut size (%d x %d). Magic layer cut size will " - "be used!\n", + LefError(LEF_WARNING, "Via cut size (%d x %d). Magic layer " + "cut size will be used!\n", currect->r_xtop - currect->r_xbot, currect->r_ytop - currect->r_ybot); } @@ -1865,7 +1974,8 @@ LefReadLayerSection(f, lname, mode, lefl) keyword = Lookup(token, layer_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1877,7 +1987,7 @@ LefReadLayerSection(f, lname, mode, lefl) { typekey = Lookup(token, layer_type_keys); if (typekey < 0) - LefError("Unknown layer type \"%s\" in LEF file; " + LefError(LEF_WARNING, "Unknown layer type \"%s\" in LEF file; " "ignoring.\n", token); } if (lefl->lefClass != typekey) @@ -1886,7 +1996,8 @@ LefReadLayerSection(f, lname, mode, lefl) /* and so having a different TYPE is an error. */ /* Otherwise just ignore the type. */ if (typekey == CLASS_ROUTE || typekey == CLASS_VIA) - LefError("Attempt to reclassify layer %s from %s to %s\n", + LefError(LEF_ERROR, "Attempt to reclassify layer %s " + "from %s to %s\n", lname, layer_type_keys[lefl->lefClass], layer_type_keys[typekey]); } @@ -1990,7 +2101,7 @@ LefReadLayerSection(f, lname, mode, lefl) case LEF_LAYER_END: if (LefParseEndStatement(f, lname) == 0) { - LefError("Layer END statement missing.\n"); + LefError(LEF_ERROR, "Layer END statement missing.\n"); keyword = -1; } break; @@ -2096,13 +2207,15 @@ LefRead(inName, importForeign) HashInit(&LefCellTable, 32, HT_STRINGKEYS); HashInit(&lefDefInitHash, 32, HT_STRINGKEYS); oscale = CIFGetOutputScale(1000); + lefCurrentLine = 0; while ((token = LefNextToken(f, TRUE)) != NULL) { keyword = Lookup(token, sections); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -2154,7 +2267,7 @@ LefRead(inName, importForeign) LefSkipSection(f, tsave); else { - LefError("Warning: Cut type \"%s\" redefined.\n", token); + LefError(LEF_WARNING, "Cut type \"%s\" redefined.\n", token); lefl = LefRedefined(lefl, token); LefReadLayerSection(f, tsave, keyword, lefl); } @@ -2178,7 +2291,7 @@ LefRead(inName, importForeign) } else if (DBIsContact(mtype) && (keyword == LEF_SECTION_LAYER)) { - LefError("Layer %s maps to a magic contact layer; " + LefError(LEF_ERROR, "Layer %s maps to a magic contact layer; " "must be defined in lef section of techfile\n", token); LefSkipSection(f, tsave); @@ -2186,7 +2299,7 @@ LefRead(inName, importForeign) } else if (!DBIsContact(mtype) && (keyword != LEF_SECTION_LAYER)) { - LefError("Via %s maps to a non-contact magic layer; " + LefError(LEF_ERROR, "Via %s maps to a non-contact magic layer; " "must be defined in lef section of techfile\n", token); LefSkipSection(f, tsave); @@ -2209,7 +2322,8 @@ LefRead(inName, importForeign) lefl = (lefLayer *)HashGetValue(he); if (lefl && lefl->type < 0) { - LefError("Layer %s is only defined for obstructions!\n", token); + LefError(LEF_ERROR, "Layer %s is only defined for " + "obstructions!\n", token); LefSkipSection(f, tsave); break; } @@ -2265,7 +2379,7 @@ LefRead(inName, importForeign) case LEF_END: if (LefParseEndStatement(f, "LIBRARY") == 0) { - LefError("END statement out of context.\n"); + LefError(LEF_ERROR, "END statement out of context.\n"); keyword = -1; } break; @@ -2273,7 +2387,7 @@ LefRead(inName, importForeign) if (keyword == LEF_END) break; } TxPrintf("LEF read: Processed %d lines.\n", lefCurrentLine); - LefError(NULL); /* print statement of errors, if any */ + LefError(LEF_SUMMARY, NULL); /* print statement of errors, if any */ /* Cleanup */ HashKill(&LefCellTable); diff --git a/lef/lefTech.c b/lef/lefTech.c index 007ad0db..272e4302 100644 --- a/lef/lefTech.c +++ b/lef/lefTech.c @@ -115,6 +115,7 @@ LefTechInit() HashKill(&LefInfo); } HashInit(&LefInfo, 32, HT_STRINGKEYS); + lefCurrentLine = -1; } /* @@ -252,17 +253,17 @@ LefTechLine(sectionName, argc, argv) if (i == 0) { - LefError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]); + TechError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]); return TRUE; } else if ((i == 2) && (option != LEFTECH_OBS)) { - LefError("Can only define multiple types for via obstruction layers.\n"); + TechError("Can only define multiple types for via obstruction layers.\n"); return TRUE; } else if (i > 2) { - LefError("Too many types in LEF layer definition.\n"); + TechError("Too many types in LEF layer definition.\n"); return TRUE; } From 53078588aec57b02c4c8e269e9887b745a266d5e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 6 Jun 2019 14:53:07 -0400 Subject: [PATCH 2/2] Changed the size of argv[] in efReadLine() to be 128 instead of 64 because I overran the 64 array with too many resistclasses in a techfile. This really should be dynamically allocated; this requires parsing the line to count tokens and reallocating as needed (to be done). --- ext2spice/ext2spice.c | 1 + extflat/EFbuild.c | 4 ++-- extflat/EFread.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 1129300b..1aa1bfc9 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -1685,6 +1685,7 @@ topVisit(def, doStub) EFNodeName *unnumbered; sname = (EFNodeName *) HashGetValue(he); + if (sname == NULL) continue; /* Should not happen */ snode = sname->efnn_node; if (!(snode->efnode_flags & EF_PORT)) continue; diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index d6b11fd6..684168f1 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -223,8 +223,8 @@ efAdjustSubCap(def, nodeName, nodeCapAdjust) EFNode *node; HashEntry *he; - he = HashFind(&def->def_nodes, nodeName); - if (nodename = (EFNodeName *) HashGetValue(he)) + he = HashLookOnly(&def->def_nodes, nodeName); + if (he && (nodename = (EFNodeName *) HashGetValue(he))) { node = nodename->efnn_node; node->efnode_cap += (EFCapValue) nodeCapAdjust; diff --git a/extflat/EFread.c b/extflat/EFread.c index c8c4471e..81384a5c 100644 --- a/extflat/EFread.c +++ b/extflat/EFread.c @@ -174,7 +174,7 @@ efReadDef(def, dosubckt, resist, noscale, toplevel) int argc, ac, n; CellDef *dbdef; EFCapValue cap; - char line[1024], *argv[64], *name, *attrs; + char line[1024], *argv[128], *name, *attrs; int rscale = 1; /* Multiply resistances by this */ int cscale = 1; /* Multiply capacitances by this */ float lscale = 1.0; /* Multiply lambda by this */