1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #include <stdio.h>
34 #include <unistd.h>
35 
36 #include <boost/algorithm/string/predicate.hpp>
37 #include <list>
38 #include <string>
39 
40 #include "lefiDebug.hpp"
41 #include "lefiUtil.hpp"
42 #include "lefin.h"
43 #include "lefrReader.hpp"
44 #include "lefzlib.hpp"
45 #include "utl/Logger.h"
46 
47 namespace odb {
48 
antennaCB(lefrCallbackType_e c,double value,lefiUserData ud)49 static int antennaCB(lefrCallbackType_e c, double value, lefiUserData ud)
50 {
51   lefin* lef = (lefin*) ud;
52 
53   switch (c) {
54     case lefrAntennaInputCbkType:
55       lef->antenna(lefin::ANTENNA_INPUT_GATE_AREA, value);
56       break;
57     case lefrAntennaInoutCbkType:
58       lef->antenna(lefin::ANTENNA_INOUT_DIFF_AREA, value);
59       break;
60     case lefrAntennaOutputCbkType:
61       lef->antenna(lefin::ANTENNA_OUTPUT_DIFF_AREA, value);
62       break;
63     case lefrInputAntennaCbkType:
64       lef->antenna(lefin::ANTENNA_INPUT_SIZE, value);
65       break;
66     case lefrOutputAntennaCbkType:
67       lef->antenna(lefin::ANTENNA_OUTPUT_SIZE, value);
68       break;
69     case lefrInoutAntennaCbkType:
70       lef->antenna(lefin::ANTENNA_INOUT_SIZE, value);
71       break;
72     default:
73       break;
74   }
75 
76   return 0;
77 }
78 
arrayBeginCB(lefrCallbackType_e,const char * name,lefiUserData ud)79 static int arrayBeginCB(lefrCallbackType_e /* unused: c */,
80                         const char* name,
81                         lefiUserData ud)
82 {
83   lefin* lef = (lefin*) ud;
84   lef->arrayBegin(name);
85   return 0;
86 }
87 
arrayCB(lefrCallbackType_e,lefiArray * a,lefiUserData ud)88 static int arrayCB(lefrCallbackType_e /* unused: c */,
89                    lefiArray* a,
90                    lefiUserData ud)
91 {
92   lefin* lef = (lefin*) ud;
93   lef->array(a);
94   return 0;
95 }
96 
arrayEndCB(lefrCallbackType_e,const char * name,lefiUserData ud)97 static int arrayEndCB(lefrCallbackType_e /* unused: c */,
98                       const char* name,
99                       lefiUserData ud)
100 {
101   lefin* lef = (lefin*) ud;
102   lef->arrayEnd(name);
103   return 0;
104 }
105 
busBitCharsCB(lefrCallbackType_e,const char * busBit,lefiUserData ud)106 static int busBitCharsCB(lefrCallbackType_e /* unused: c */,
107                          const char* busBit,
108                          lefiUserData ud)
109 {
110   lefin* lef = (lefin*) ud;
111   lef->busBitChars(busBit);
112   return 0;
113 }
114 
caseSensCB(lefrCallbackType_e,int caseSense,lefiUserData ud)115 static int caseSensCB(lefrCallbackType_e /* unused: c */,
116                       int caseSense,
117                       lefiUserData ud)
118 {
119   lefin* lef = (lefin*) ud;
120   lef->caseSense(caseSense);
121   return 0;
122 }
123 
clearanceCB(lefrCallbackType_e,const char * name,lefiUserData ud)124 static int clearanceCB(lefrCallbackType_e /* unused: c */,
125                        const char* name,
126                        lefiUserData ud)
127 {
128   lefin* lef = (lefin*) ud;
129   lef->clearance(name);
130   return 0;
131 }
132 
dividerCB(lefrCallbackType_e,const char * name,lefiUserData ud)133 static int dividerCB(lefrCallbackType_e /* unused: c */,
134                      const char* name,
135                      lefiUserData ud)
136 {
137   lefin* lef = (lefin*) ud;
138   lef->divider(name);
139   return 0;
140 }
141 
noWireExtCB(lefrCallbackType_e,const char * name,lefiUserData ud)142 static int noWireExtCB(lefrCallbackType_e /* unused: c */,
143                        const char* name,
144                        lefiUserData ud)
145 {
146   lefin* lef = (lefin*) ud;
147   lef->noWireExt(name);
148   return 0;
149 }
150 
noiseMarCB(lefrCallbackType_e,lefiNoiseMargin * noise,lefiUserData ud)151 static int noiseMarCB(lefrCallbackType_e /* unused: c */,
152                       lefiNoiseMargin* noise,
153                       lefiUserData ud)
154 {
155   lefin* lef = (lefin*) ud;
156   lef->noiseMargin(noise);
157   return 0;
158 }
159 
edge1CB(lefrCallbackType_e,double value,lefiUserData ud)160 static int edge1CB(lefrCallbackType_e /* unused: c */,
161                    double value,
162                    lefiUserData ud)
163 {
164   lefin* lef = (lefin*) ud;
165   lef->edge1(value);
166   return 0;
167 }
168 
edge2CB(lefrCallbackType_e,double value,lefiUserData ud)169 static int edge2CB(lefrCallbackType_e /* unused: c */,
170                    double value,
171                    lefiUserData ud)
172 {
173   lefin* lef = (lefin*) ud;
174   lef->edge2(value);
175   return 0;
176 }
177 
edgeScaleCB(lefrCallbackType_e,double value,lefiUserData ud)178 static int edgeScaleCB(lefrCallbackType_e /* unused: c */,
179                        double value,
180                        lefiUserData ud)
181 {
182   lefin* lef = (lefin*) ud;
183   lef->edgeScale(value);
184   return 0;
185 }
186 
noiseTableCB(lefrCallbackType_e,lefiNoiseTable * noise,lefiUserData ud)187 static int noiseTableCB(lefrCallbackType_e /* unused: c */,
188                         lefiNoiseTable* noise,
189                         lefiUserData ud)
190 {
191   lefin* lef = (lefin*) ud;
192   lef->noiseTable(noise);
193   return 0;
194 }
195 
correctionCB(lefrCallbackType_e,lefiCorrectionTable * corr,lefiUserData ud)196 static int correctionCB(lefrCallbackType_e /* unused: c */,
197                         lefiCorrectionTable* corr,
198                         lefiUserData ud)
199 {
200   lefin* lef = (lefin*) ud;
201   lef->correction(corr);
202   return 0;
203 }
204 
dielectricCB(lefrCallbackType_e,double dielectric,lefiUserData ud)205 static int dielectricCB(lefrCallbackType_e /* unused: c */,
206                         double dielectric,
207                         lefiUserData ud)
208 {
209   lefin* lef = (lefin*) ud;
210   lef->dielectric(dielectric);
211   return 0;
212 }
213 
irdropBeginCB(lefrCallbackType_e,void * ptr,lefiUserData ud)214 static int irdropBeginCB(lefrCallbackType_e /* unused: c */,
215                          void* ptr,
216                          lefiUserData ud)
217 {
218   lefin* lef = (lefin*) ud;
219   lef->irdropBegin(ptr);
220   return 0;
221 }
222 
irdropCB(lefrCallbackType_e,lefiIRDrop * irdrop,lefiUserData ud)223 static int irdropCB(lefrCallbackType_e /* unused: c */,
224                     lefiIRDrop* irdrop,
225                     lefiUserData ud)
226 {
227   lefin* lef = (lefin*) ud;
228   lef->irdrop(irdrop);
229   return 0;
230 }
231 
irdropEndCB(lefrCallbackType_e,void * ptr,lefiUserData ud)232 static int irdropEndCB(lefrCallbackType_e /* unused: c */,
233                        void* ptr,
234                        lefiUserData ud)
235 {
236   lefin* lef = (lefin*) ud;
237   lef->irdropEnd(ptr);
238   return 0;
239 }
240 
layerCB(lefrCallbackType_e,lefiLayer * layer,lefiUserData ud)241 static int layerCB(lefrCallbackType_e /* unused: c */,
242                    lefiLayer* layer,
243                    lefiUserData ud)
244 {
245   lefin* lef = (lefin*) ud;
246   lef->layer(layer);
247   return 0;
248 }
249 
macroBeginCB(lefrCallbackType_e,const char * name,lefiUserData ud)250 static int macroBeginCB(lefrCallbackType_e /* unused: c */,
251                         const char* name,
252                         lefiUserData ud)
253 {
254   lefin* lef = (lefin*) ud;
255   lef->macroBegin(name);
256   return 0;
257 }
258 
macroCB(lefrCallbackType_e,lefiMacro * macro,lefiUserData ud)259 static int macroCB(lefrCallbackType_e /* unused: c */,
260                    lefiMacro* macro,
261                    lefiUserData ud)
262 {
263   lefin* lef = (lefin*) ud;
264   lef->macro(macro);
265   return 0;
266 }
267 
macroEndCB(lefrCallbackType_e,const char * name,lefiUserData ud)268 static int macroEndCB(lefrCallbackType_e /* unused: c */,
269                       const char* name,
270                       lefiUserData ud)
271 {
272   lefin* lef = (lefin*) ud;
273   lef->macroEnd(name);
274   return 0;
275 }
276 
manufacturingCB(lefrCallbackType_e,double num,lefiUserData ud)277 static int manufacturingCB(lefrCallbackType_e /* unused: c */,
278                            double num,
279                            lefiUserData ud)
280 {
281   lefin* lef = (lefin*) ud;
282   lef->manufacturing(num);
283   return 0;
284 }
285 
maxStackViaCB(lefrCallbackType_e,lefiMaxStackVia * max,lefiUserData ud)286 static int maxStackViaCB(lefrCallbackType_e /* unused: c */,
287                          lefiMaxStackVia* max,
288                          lefiUserData ud)
289 {
290   lefin* lef = (lefin*) ud;
291   lef->maxStackVia(max);
292   return 0;
293 }
294 
minFeatureCB(lefrCallbackType_e,lefiMinFeature * min,lefiUserData ud)295 static int minFeatureCB(lefrCallbackType_e /* unused: c */,
296                         lefiMinFeature* min,
297                         lefiUserData ud)
298 {
299   lefin* lef = (lefin*) ud;
300   lef->minFeature(min);
301   return 0;
302 }
303 
nonDefaultCB(lefrCallbackType_e,lefiNonDefault * def,lefiUserData ud)304 static int nonDefaultCB(lefrCallbackType_e /* unused: c */,
305                         lefiNonDefault* def,
306                         lefiUserData ud)
307 {
308   lefin* lef = (lefin*) ud;
309   lef->nonDefault(def);
310   return 0;
311 }
312 
obstructionCB(lefrCallbackType_e,lefiObstruction * obs,lefiUserData ud)313 static int obstructionCB(lefrCallbackType_e /* unused: c */,
314                          lefiObstruction* obs,
315                          lefiUserData ud)
316 {
317   lefin* lef = (lefin*) ud;
318   lef->obstruction(obs);
319   return 0;
320 }
321 
pinCB(lefrCallbackType_e,lefiPin * pin,lefiUserData ud)322 static int pinCB(lefrCallbackType_e /* unused: c */,
323                  lefiPin* pin,
324                  lefiUserData ud)
325 {
326   lefin* lef = (lefin*) ud;
327   lef->pin(pin);
328   return 0;
329 }
330 
propDefBeginCB(lefrCallbackType_e,void * ptr,lefiUserData ud)331 static int propDefBeginCB(lefrCallbackType_e /* unused: c */,
332                           void* ptr,
333                           lefiUserData ud)
334 {
335   lefin* lef = (lefin*) ud;
336   lef->propDefBegin(ptr);
337   return 0;
338 }
339 
propDefCB(lefrCallbackType_e,lefiProp * prop,lefiUserData ud)340 static int propDefCB(lefrCallbackType_e /* unused: c */,
341                      lefiProp* prop,
342                      lefiUserData ud)
343 {
344   lefin* lef = (lefin*) ud;
345   lef->propDef(prop);
346   return 0;
347 }
348 
propDefEndCB(lefrCallbackType_e,void * ptr,lefiUserData ud)349 static int propDefEndCB(lefrCallbackType_e /* unused: c */,
350                         void* ptr,
351                         lefiUserData ud)
352 {
353   lefin* lef = (lefin*) ud;
354   lef->propDefEnd(ptr);
355   return 0;
356 }
357 
siteCB(lefrCallbackType_e,lefiSite * site,lefiUserData ud)358 static int siteCB(lefrCallbackType_e /* unused: c */,
359                   lefiSite* site,
360                   lefiUserData ud)
361 {
362   lefin* lef = (lefin*) ud;
363   lef->site(site);
364   return 0;
365 }
366 
spacingBeginCB(lefrCallbackType_e,void * ptr,lefiUserData ud)367 static int spacingBeginCB(lefrCallbackType_e /* unused: c */,
368                           void* ptr,
369                           lefiUserData ud)
370 {
371   lefin* lef = (lefin*) ud;
372   lef->spacingBegin(ptr);
373   return 0;
374 }
375 
spacingCB(lefrCallbackType_e,lefiSpacing * spacing,lefiUserData ud)376 static int spacingCB(lefrCallbackType_e /* unused: c */,
377                      lefiSpacing* spacing,
378                      lefiUserData ud)
379 {
380   lefin* lef = (lefin*) ud;
381   lef->spacing(spacing);
382   return 0;
383 }
384 
spacingEndCB(lefrCallbackType_e,void * ptr,lefiUserData ud)385 static int spacingEndCB(lefrCallbackType_e /* unused: c */,
386                         void* ptr,
387                         lefiUserData ud)
388 {
389   lefin* lef = (lefin*) ud;
390   lef->spacingEnd(ptr);
391   return 0;
392 }
393 
timingCB(lefrCallbackType_e,lefiTiming * timing,lefiUserData ud)394 static int timingCB(lefrCallbackType_e /* unused: c */,
395                     lefiTiming* timing,
396                     lefiUserData ud)
397 {
398   lefin* lef = (lefin*) ud;
399   lef->timing(timing);
400   return 0;
401 }
402 
unitsCB(lefrCallbackType_e,lefiUnits * unit,lefiUserData ud)403 static int unitsCB(lefrCallbackType_e /* unused: c */,
404                    lefiUnits* unit,
405                    lefiUserData ud)
406 {
407   lefin* lef = (lefin*) ud;
408   lef->units(unit);
409   return 0;
410 }
411 
useMinSpacingCB(lefrCallbackType_e,lefiUseMinSpacing * spacing,lefiUserData ud)412 static int useMinSpacingCB(lefrCallbackType_e /* unused: c */,
413                            lefiUseMinSpacing* spacing,
414                            lefiUserData ud)
415 {
416   lefin* lef = (lefin*) ud;
417   lef->useMinSpacing(spacing);
418   return 0;
419 }
420 
versionCB(lefrCallbackType_e,double num,lefiUserData ud)421 static int versionCB(lefrCallbackType_e /* unused: c */,
422                      double num,
423                      lefiUserData ud)
424 {
425   lefin* lef = (lefin*) ud;
426   lef->version(num);
427   return 0;
428 }
429 
viaCB(lefrCallbackType_e,lefiVia * via,lefiUserData ud)430 static int viaCB(lefrCallbackType_e /* unused: c */,
431                  lefiVia* via,
432                  lefiUserData ud)
433 {
434   lefin* lef = (lefin*) ud;
435   lef->via(via);
436   return 0;
437 }
438 
viaRuleCB(lefrCallbackType_e,lefiViaRule * rule,lefiUserData ud)439 static int viaRuleCB(lefrCallbackType_e /* unused: c */,
440                      lefiViaRule* rule,
441                      lefiUserData ud)
442 {
443   lefin* lef = (lefin*) ud;
444   lef->viaRule(rule);
445   return 0;
446 }
447 
doneCB(lefrCallbackType_e,void * ptr,lefiUserData ud)448 static int doneCB(lefrCallbackType_e /* unused: c */,
449                   void* ptr,
450                   lefiUserData ud)
451 {
452   lefin* lef = (lefin*) ud;
453   lef->done(ptr);
454   return 0;
455 }
456 
errorCB(const char * msg)457 static void errorCB(const char* msg)
458 {
459   lefin* lef = (lefin*) lefrGetUserData();
460   lef->errorTolerant(219, "Error: {}", msg);
461 }
462 
warningCB(const char * msg)463 static void warningCB(const char* msg)
464 {
465   lefin* lef = (lefin*) lefrGetUserData();
466   lef->warning(220, msg);
467 }
468 
lineNumberCB(int line)469 static void lineNumberCB(int line)
470 {
471   lefin* lef = (lefin*) lefrGetUserData();
472   lef->lineNumber(line);
473 }
474 
lefin_parse(lefin * lef,utl::Logger * logger,const char * file_name)475 bool lefin_parse(lefin* lef, utl::Logger* logger, const char* file_name)
476 {
477   // sets the parser to be case sensitive...
478   // default was supposed to be the case but false...
479   // lefrSetCaseSensitivity(true);
480   lefrSetAntennaInputCbk(antennaCB);
481   lefrSetAntennaInoutCbk(antennaCB);
482   lefrSetAntennaOutputCbk(antennaCB);
483   lefrSetArrayBeginCbk(arrayBeginCB);
484   lefrSetArrayCbk(arrayCB);
485   lefrSetArrayEndCbk(arrayEndCB);
486   lefrSetBusBitCharsCbk(busBitCharsCB);
487   lefrSetCaseSensitiveCbk(caseSensCB);
488   lefrSetClearanceMeasureCbk(clearanceCB);
489   lefrSetDividerCharCbk(dividerCB);
490   lefrSetNoWireExtensionCbk(noWireExtCB);
491   lefrSetNoiseMarginCbk(noiseMarCB);
492   lefrSetEdgeRateThreshold1Cbk(edge1CB);
493   lefrSetEdgeRateThreshold2Cbk(edge2CB);
494   lefrSetEdgeRateScaleFactorCbk(edgeScaleCB);
495   lefrSetNoiseTableCbk(noiseTableCB);
496   lefrSetCorrectionTableCbk(correctionCB);
497   lefrSetDielectricCbk(dielectricCB);
498   lefrSetIRDropBeginCbk(irdropBeginCB);
499   lefrSetIRDropCbk(irdropCB);
500   lefrSetIRDropEndCbk(irdropEndCB);
501   lefrSetLayerCbk(layerCB);
502   lefrSetLibraryEndCbk(doneCB);
503   lefrSetMacroBeginCbk(macroBeginCB);
504   lefrSetMacroCbk(macroCB);
505   lefrSetMacroEndCbk(macroEndCB);
506   lefrSetManufacturingCbk(manufacturingCB);
507   lefrSetMaxStackViaCbk(maxStackViaCB);
508   lefrSetMinFeatureCbk(minFeatureCB);
509   lefrSetNonDefaultCbk(nonDefaultCB);
510   lefrSetObstructionCbk(obstructionCB);
511   lefrSetPinCbk(pinCB);
512   lefrSetPropBeginCbk(propDefBeginCB);
513   lefrSetPropCbk(propDefCB);
514   lefrSetPropEndCbk(propDefEndCB);
515   lefrSetSiteCbk(siteCB);
516   lefrSetSpacingBeginCbk(spacingBeginCB);
517   lefrSetSpacingCbk(spacingCB);
518   lefrSetSpacingEndCbk(spacingEndCB);
519   lefrSetTimingCbk(timingCB);
520   lefrSetUnitsCbk(unitsCB);
521   lefrSetUseMinSpacingCbk(useMinSpacingCB);
522   lefrSetVersionCbk(versionCB);
523   lefrSetViaCbk(viaCB);
524   lefrSetViaRuleCbk(viaRuleCB);
525   lefrSetInputAntennaCbk(antennaCB);
526   lefrSetOutputAntennaCbk(antennaCB);
527   lefrSetInoutAntennaCbk(antennaCB);
528   lefrSetLogFunction(errorCB);
529   lefrSetWarningLogFunction(warningCB);
530   lefrSetLineNumberFunction(lineNumberCB);
531 
532   // Available callbacks not registered - FIXME??
533   // lefrSetDensityCbk
534   // lefrSetExtensionCbk
535   // lefrSetFixedMaskCbk
536   // lefrSetMacroClassTypeCbk
537   // lefrSetMacroFixedMaskCbk
538   // lefrSetMacroForeignCbk
539   // lefrSetMacroOriginCbk
540   // lefrSetMacroSiteCbk
541   // lefrSetMacroSizeCbk
542 
543   lefrSetDeltaNumberLines(1000000);
544   lefrInit();
545   int res;
546   if (boost::algorithm::ends_with(file_name, ".gz")) {
547     auto zfile = lefGZipOpen(file_name, "r");
548     if (zfile == NULL) {
549       logger->warn(
550           utl::ODB, 270, "error: Cannot open zipped LEF file {}", file_name);
551       return false;
552     }
553     res = lefrReadGZip(zfile, file_name, (void*) lef);
554     lefGZipClose(zfile);
555   } else {
556     FILE* file = fopen(file_name, "r");
557     if (file == NULL) {
558       logger->warn(utl::ODB, 240, "error: Cannot open LEF file {}", file_name);
559       return false;
560     }
561     res = lefrRead(file, file_name, (void*) lef);
562     fclose(file);
563   }
564   lefrClear();
565 
566   if (res)
567     return false;
568 
569   return true;
570 }
571 
lefin_get_current_line()572 int lefin_get_current_line()
573 {
574   return lefrLineNumber();
575 }
576 
577 }  // namespace odb
578