File Coverage

blib/lib/Liberty/Parser.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Liberty::Parser;
2              
3 1     1   30994 use 5.008005;
  1         5  
  1         41  
4 1     1   6 use strict;
  1         4  
  1         35  
5 1     1   6 use warnings;
  1         6  
  1         45  
6 1     1   2936 use liberty;
  0            
  0            
7              
8             # Export
9             # {{{
10             require Exporter;
11              
12             our @ISA = qw(Exporter);
13              
14             # Items to export into callers namespace by default. Note: do not export
15             # names by default without a very good reason. Use EXPORT_OK instead.
16             # Do not simply export all your public functions/methods/constants.
17              
18             # This allows declaration use Liberty::Parser ':all';
19             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
20             # will save memory.
21             our %EXPORT_TAGS = ( 'all' => [ qw(
22            
23             ) ] );
24              
25             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
26              
27             our @EXPORT = qw(
28            
29             );
30             # }}}
31              
32             =head1 NAME
33              
34             Liberty::Parser - Parser for Synopsys Liberty(.lib).
35              
36             =head1 VERSION
37              
38             Version 0.04
39              
40             =cut
41              
42             our $VERSION = '0.04';
43              
44             our $e = 1;
45             our $e2 = 2;
46              
47              
48             =head1 SYNOPSIS
49              
50             use Liberty::Parser;
51             my $parser = new Liberty::Parser;
52             my $library_group = $parser->read_file("standard_cell.lib");
53              
54             my $lib_name = $parser->get_group_name($library_group);
55             print "Library Name: $lib_name\n";
56             print $parser->get_attr_with_value($library_group,"nom_temperature");
57              
58             =head1 DESCRIPTION
59              
60             Liberty::Parser is indeed a Perl wrapper for a Liberty Parser which is written in C from
61             Synopsys's Open Liberty Project.
62              
63             Liberty::Parser harnesses Open Libety Project with Perl through the help of SWIG (www.swig.org)
64             and implemented many handy functions to make information extracting from Liberty can
65             be easily accomplished.
66              
67             To get Liberty::Parser work, you have to download liberty_parse from Open Liberty Project.
68             Compile the C source into linked library then put the linked library at somewhere it can
69             be found through the environment variable LD_LIBRARY_PATH. Please follow the guide in the
70             INSTALLATION section of README.
71              
72             =head1 BASIC FUNTIONS
73              
74             =cut
75              
76             # new
77             # {{{
78              
79             =head2 new
80              
81             To new a Liberty::Parser object.
82              
83             =cut
84             sub new {
85             my $self=shift;
86             my $class=ref($self) || $self;
87             return bless {}, $class;
88             }
89             # }}}
90             # read_file
91             # {{{
92              
93             =head2 read_file
94              
95             read_file :*group : (string filename)
96              
97             Read the liberty format file and return a group handle.
98              
99             =cut
100             sub read_file{
101             my $self = shift;
102             my $file = shift;
103             my $gs;
104             my $g;
105             lib_PIInit(\$e);
106             lib_ReadLibertyFile("$file", \$e);
107             $gs = lib_PIGetGroups(\$e);
108             $g = lib_IterNextGroup($gs,\$e);
109             return $g;
110             }
111             # }}}
112             # locate_cell
113             # {{{
114              
115             =head2 locate_cell
116              
117             locate_cell : *group : (*group, string cell_name)
118              
119             Return the handle of group type `cell'.
120              
121             =cut
122              
123             sub locate_cell {
124             my $self = shift;
125             my $g = shift;
126             my $name = shift;
127             my $cell = lib_GroupFindGroupByName($g,$name,"cell",\$e);
128             return $cell;
129             }
130             # }}}
131             # locate_port
132             # {{{
133              
134             =head2 locate_port
135              
136             locate_port : *group : (*group, string port_name)
137             Return the handle of group type `port'.
138              
139             =cut
140             sub locate_port {
141             my $self = shift;
142             my $g = shift;
143             my $name = shift;
144             my $port = lib_GroupFindGroupByName($g,$name,"pin",\$e);
145             #print lib_PIGetErrorText($e, \$e2);
146             if($e == 9){
147             $port = lib_GroupFindGroupByName($g,$name,"bus",\$e);
148             }
149             if($e == 9){
150             print lib_PIGetErrorText($e, \$e2);
151             exit;
152             }
153             return $port;
154             }
155             # }}}
156             # locate_group
157             # {{{
158              
159             =head2 locate_group
160              
161             locate_group : *group : (*group, string group_name)
162             Return the handle of group type `cell'.
163              
164             =cut
165             sub locate_group {
166             my $self = shift;
167             my $g = shift;
168             my $name = shift;
169             my $gps = lib_GroupGetGroups($g,\$e);
170             my $ng;
171             my $gt;
172             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
173             if( $name eq $self->get_group_name($ng)){
174             return $ng;
175             }
176             } lib_IterQuit($gps, \$e);
177             die "Can't find group `$name'\n";
178             }
179             # }}}
180             # locate_group_by_type
181             # {{{
182              
183             =head2 locate_group_by_type
184              
185             $parser->locate_group_by_type($g, $type_name);
186              
187             =cut
188             sub locate_group_by_type {
189             my $self = shift;
190             my $g = shift;
191             my $type_name = shift;
192             my $gps = lib_GroupGetGroups($g,\$e);
193             my $ng;
194             my $gt;
195             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
196             if( $type_name eq $self->get_group_type($ng)){
197             return $ng;
198             }
199             } lib_IterQuit($gps, \$e);
200             return 0;
201             }
202             # }}}
203             # locate_cell_arc
204             # {{{
205              
206             =head2 locate_cell_arc
207              
208             $parser->locate_cell_arc($g, $type_name);
209              
210             =cut
211             sub locate_cell_arc {
212             my $self = shift;
213             my $g = shift;
214             my $arc_type = shift;
215             my $gps = lib_GroupGetGroups($g,\$e);
216             my $ng;
217             my $gps2;
218             my $ng2;
219             my $ee = 11;
220             my $ee2 = 22;
221              
222             # Iterate groups in cell
223             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
224             if( $self->get_group_type($ng) eq "pin"){
225             if ($self->get_simple_attr_value($ng, "direction") eq "output"){
226             $ng2 = $self->locate_group_by_type($ng,"timing");
227             my $arc_group = $self->locate_group_by_type($ng2, $arc_type);
228             if ($arc_group == 0){
229             die "can't found!\n";
230             }else{
231             return $arc_group;
232             }
233             }
234             }
235             } lib_IterQuit($gps, \$e);
236              
237             }
238             # }}}
239             # get_group_name
240             # {{{
241              
242             =head2 get_group_name
243              
244             get_group_name : string : (*group)
245             Return the group name while input a group handle.
246             Example:
247              
248             print $p->get_group_name($g_func);
249              
250             =cut
251             sub get_group_name{
252             my $self = shift;
253             my $g = shift;
254             my $names = lib_GroupGetNames($g, \$e);
255             my $name = lib_IterNextName($names,\$e);
256             if (!defined($name)){
257             $name = "";
258             }
259             return $name;
260             }
261             # }}}
262             # get_group_names
263             # {{{
264              
265             =head2 get_group_names
266              
267             get_group_names : array : (*group G)
268             Return the handle of group type `cell'. Example:
269              
270             my @j = $p->get_group_names ($f_cell);
271             dump_array(\@j);
272              
273             =cut
274             sub get_group_names {
275             my $self = shift;
276             my $g = shift;
277             my $gps = lib_GroupGetGroups($g,\$e);
278             my $ng;
279             my @name_list;
280             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
281             push @name_list, $self->get_group_name($ng);
282             } lib_IterQuit($gps, \$e);
283             return @name_list;
284             }
285             # }}}
286             # get_groups_by_type
287             # {{{
288              
289             =head2 get_groups_by_type
290              
291             Return the handle of group type `cell'. Example:
292              
293             my @j = $p->get_groups_by_type($group, $type_name);
294              
295             =cut
296             sub get_groups_by_type {
297             my $self = shift;
298             my $g = shift;
299             my $type = shift;
300             my $gps = lib_GroupGetGroups($g,\$e);
301             my $ng;
302             my @a;
303             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
304             if($type eq $self->get_group_type($ng)){
305             push @a, $ng;
306             }
307             } lib_IterQuit($gps, \$e);
308             return @a;
309             }
310             # }}}
311             # get_group_type
312             # {{{
313              
314             =head2 get_group_type
315              
316             get_group_type : string : (*group G)
317             Return the type name of the group G. Example:
318              
319             print $p->get_group_type($g);
320              
321             =cut
322             sub get_group_type {
323             my $self = shift;
324             my $g = shift;
325             my $type = lib_GroupGetGroupType($g, \$e);
326             return $type;
327             }
328             # }}}
329             # get_attr_name
330             # {{{
331              
332             =head2 get_attr_name
333              
334             get_attr_name : string : (*attr A)
335             Return the attribute name while input a attribute handle.
336              
337             =cut
338             sub get_attr_name{
339             my $self = shift;
340             my $a = shift;
341             return lib_AttrGetName($a, \$e);
342             }
343             # }}}
344             # get_attr_type
345             # {{{
346              
347             =head2 get_attr_type
348              
349             Return the attribute type while input a attribute handle.
350              
351             get_attr_type : string : (*attr A)
352              
353             =cut
354             sub get_attr_type {
355             my $self = shift;
356             my $a = shift;
357             my $type = lib_AttrGetAttrType($a, \$e);
358             return $type;
359             }
360             # }}}
361             # get_value_type
362             # {{{
363              
364             =head2 get_value_type
365              
366             get_value_type : string : (*attr)
367              
368             Return the value type of attribute A.
369              
370             =cut
371             sub get_value_type {
372             my $self = shift;
373             my $a = shift;
374             return lib_SimpleAttrGetValueType($a, \$e);
375             }
376             # }}}
377             # get_simple_attr_value
378             # {{{
379              
380             =head2 get_simple_attr_value
381              
382             $parser->get_simple_attr_value($group, $attr_name);
383              
384             =cut
385             sub get_simple_attr_value {
386             my $self = shift;
387             my $g = shift;
388             my $attr_name = shift;
389             my $at = lib_GroupFindAttrByName($g,$attr_name,\$e);
390             return lib_SimpleAttrGetStringValue($at, \$e);
391             }
392             # }}}
393             # get_attr_with_value
394             # {{{
395              
396             =head2 get_attr_with_value
397              
398             get_attr_with_value : string : (*group, string attr_name)
399             Return a string with attriubte name and attribute value.
400              
401             =cut
402             sub get_attr_with_value {
403             my $self = shift;
404             my $g = shift;
405             my $aname = shift;
406             my $print_op;
407             my $ats = lib_GroupGetAttrs($g, \$e);
408             my $at = lib_GroupFindAttrByName($g,$aname,\$e);
409             my $atype = $self->get_attr_type($at);
410             my $indent = "";
411             my $indent2 = " ".$indent;
412             my $indent3 = " ".$indent;
413             my $eg = "";
414             my $vtype;
415             my $print_content;
416              
417             my $is_var = $self->is_var($at);
418             if($is_var){
419             $print_op = " =";
420             }else{
421             $print_op = " :";
422             }
423              
424             # Simple attribute
425             if ($atype == $liberty::SI2DR_SIMPLE) {
426             $vtype = $self->get_value_type($at);
427             # STRING
428             if($vtype == $liberty::SI2DR_STRING){
429             $eg .= $print_op." \"" . lib_SimpleAttrGetStringValue($at,\$e) . "\";\n";
430             # FLOAT64
431             }elsif($vtype == $liberty::SI2DR_FLOAT64){
432             $eg .= $print_op." ".lib_SimpleAttrGetFloat64Value($at,\$e)." ;\n";
433             # INT32
434             }elsif($vtype == $liberty::SI2DR_INT32){
435             $eg .= $print_op." ".lib_SimpleAttrGetInt32Value($at,\$e)." ;\n";
436             # EXPR
437             }elsif($vtype == $liberty::SI2DR_EXPR){
438             $eg .= "expr\n";
439             die;
440             # BOOLEAN
441             }elsif($vtype == $liberty::SI2DR_BOOLEAN){
442             if(lib_SimpleAttrGetBooleanValue($at,\$e)){
443             $print_content = "true";
444             }else{
445             $print_content = "false";
446             }
447             $eg .= " ".$print_op." ".$print_content." ;\n";
448             }
449             # Complex attribute
450             }elsif($atype == $liberty::SI2DR_COMPLEX){
451             my $vals = lib_ComplexAttrGetValues($at,\$e);
452             my $first = 1;
453             $eg .= " ( ";
454              
455             while(1){
456             my $cplex = lib_IterNextComplex($vals, \$e);
457             my $vt = lib_ComplexValGetValueType($cplex, \$e);
458              
459             # STRING
460             if($vt == $liberty::SI2DR_STRING) {
461             my $str6 = lib_ComplexValGetStringValue($cplex, \$e);
462             if(!$first){
463             $eg .= ",";
464             $eg .= "\\\n ";
465             $eg .= $indent3." "."\"".$str6."\"";
466             }else{
467             $eg .= "\"$str6\"";
468             }
469             # FLOAT64
470             } elsif($vt == $liberty::SI2DR_FLOAT64) {
471             my $f1 = lib_ComplexValGetFloat64Value($cplex, \$e);
472             $eg .= $f1;
473             } elsif($vt == $liberty::SI2DR_INT32) {
474             $eg .= "Boolean\n";
475             } elsif($vt == $liberty::SI2DR_BOOLEAN) {
476             $eg .= "String\n";
477             } elsif($vt == $liberty::SI2DR_EXPR) {
478             $eg .= "Expr\n";
479             } else{ last; }
480             $first = 0;
481             }
482             $eg .= ");\n";
483             }
484             return $aname.$eg;
485             }
486             # }}}
487             # get_lookup_table_index_1
488             # {{{
489              
490             =head2 get_lookup_table_index_1
491              
492             input1:
493             input2:
494             return: 2D array
495             Ex:
496             $parser->get_lookup_table_index($group);
497              
498             =cut
499             sub get_lookup_table_index_1 {
500             my $self = shift;
501             my $g = shift;
502              
503             my $ats = lib_GroupGetAttrs($g, \$e);
504             my $at = lib_IterNextAttr($ats, \$e); #index_1
505              
506             my $cplex;
507             my $str;
508             my $vt;
509             my $vals = lib_ComplexAttrGetValues($at,\$e);
510             my @tmp;
511             my @aoa;
512             $cplex = lib_IterNextComplex($vals, \$e);
513             $str = lib_ComplexValGetStringValue($cplex, \$e);
514             $str =~ s/\s//g;
515             @tmp = split(/,/, $str);
516              
517             return @tmp;
518             }
519             # }}}
520             # get_lookup_table_index_2
521             # {{{
522              
523             =head2 get_lookup_table_index_2
524              
525             input1:
526             input2:
527             return: 2D array
528             Ex:
529             $parser->get_lookup_table_index_2($group);
530              
531             =cut
532             sub get_lookup_table_index_2 {
533             my $self = shift;
534             my $g = shift;
535              
536             my $ats = lib_GroupGetAttrs($g, \$e);
537             my $at = lib_IterNextAttr($ats, \$e); #index_1
538             $at = lib_IterNextAttr($ats, \$e); #index_2
539              
540             my $cplex;
541             my $str;
542             my $vt;
543             my $vals = lib_ComplexAttrGetValues($at,\$e);
544             my @tmp;
545             my @aoa;
546             $cplex = lib_IterNextComplex($vals, \$e);
547             $str = lib_ComplexValGetStringValue($cplex, \$e);
548             $str =~ s/\s//g;
549             @tmp = split(/,/, $str);
550              
551             return @tmp;
552             }
553             # }}}
554             # get_lookup_table
555             # {{{
556              
557             =head2 get_lookup_table
558              
559             input1:
560             input2:
561             return: 2D array
562             Ex:
563             $parser->get_lookup_table($group);
564              
565             =cut
566             sub get_lookup_table {
567             my $self = shift;
568             my $g = shift;
569              
570             my $ats = lib_GroupGetAttrs($g, \$e);
571             my $at = lib_IterNextAttr($ats, \$e); #index_1
572             $at = lib_IterNextAttr($ats, \$e); #index_2
573             $at = lib_IterNextAttr($ats, \$e); #value
574              
575             my $cplex;
576             my $str;
577             my $vt;
578             my $vals = lib_ComplexAttrGetValues($at,\$e);
579             my @tmp;
580             my @aoa;
581             while(1){
582             $cplex = lib_IterNextComplex($vals, \$e);
583             $vt = lib_ComplexValGetValueType($cplex, \$e);
584             if ($vt==0) {
585             last;
586             }else{
587             $str = lib_ComplexValGetStringValue($cplex, \$e);
588             $str =~ s/\s//g;
589             @tmp = split(/,/, $str);
590             push @aoa, [@tmp];
591             }
592             }
593             return @aoa;
594             }
595             # }}}
596             # get_lookup_table_array
597             # {{{
598              
599             =head2 get_lookup_table_center
600              
601             input1: timing type group
602             input2: cell_rise, cell_fall...
603             return: number
604             Ex:
605             $rise = $parser->get_lookup_table_array($timing_group, "cell_rise");
606              
607             =cut
608             sub get_lookup_table_array {
609             my $self = shift;
610             my $g = shift;
611             my $gtype = shift;
612             my $arc_group = $self->locate_group_by_type($g, $gtype);
613             if ($arc_group == 0){
614             return "N/A";
615             }else{
616             my @a_2D = $self->get_lookup_table($arc_group);
617             return @a_2D;
618             }
619             }
620             # }}}
621             # get_lookup_table_center
622             # {{{
623              
624             =head2 get_lookup_table_center
625              
626             input1: timing type group
627             input2: cell_rise, cell_fall...
628             return: number
629             Ex:
630             $rise = $parser->get_lookup_table_center($timing_group, "cell_rise");
631              
632             =cut
633             sub get_lookup_table_center {
634             my $self = shift;
635             my $g = shift;
636             my $gtype = shift;
637             my $arc_group = $self->locate_group_by_type($g, $gtype);
638             if ($arc_group == 0){
639             return "N/A";
640             }else{
641             my @a_2D = $self->get_lookup_table($arc_group);
642             return $a_2D[3][3];
643             }
644             }
645             # }}}
646             # check_related_pin
647             # {{{
648              
649             =head2 check_related_pin
650              
651             input1: a reference to timing group
652             input2: pin name as string
653             return: 1 or 0
654             Ex:
655             $parser->check_related_pin($timing_group, $pin_name);
656              
657             =cut
658             sub check_related_pin {
659             my $self = shift;
660             my $g = shift;
661             my $pname = shift;
662              
663             my $at = lib_GroupFindAttrByName($g,"related_pin",\$e);
664             my $related_pin = lib_SimpleAttrGetStringValue($at, \$e);
665              
666             if ($related_pin eq $pname){
667             return 1;
668             }else{
669             return 0;
670             }
671             }
672             # }}}
673             # check_group_type
674             # {{{
675              
676             =head2 check_group_type
677              
678             input: pin, timing, cell_rise, cell_fall, ...
679             return: 1 or 0
680             Ex:
681             $parser->check_group_type($group, "pin");
682              
683             =cut
684             sub check_group_type {
685             my $self = shift;
686             my $g = shift;
687             my $ctype = shift;
688             my $gt = lib_GroupGetGroupType($g,\$e);
689             if ($gt eq $ctype){
690             return 1;
691             }else{
692             return 0;
693             }
694             }
695             # }}}
696             # print_attrs
697             # {{{
698              
699             =head2 print_attrs
700              
701             print_attrs : void : (*group G)
702             Print all attributes of a group G.
703              
704             =cut
705             sub print_attrs {
706             my $self = shift;
707             my $g = shift;
708             my $ats = lib_GroupGetAttrs($g, \$e);
709             my $at;
710             while (!lib_ObjectIsNull (($at = lib_IterNextAttr($ats, \$e)), \$e2)) {
711             print lib_AttrGetName($at, \$e), "\n";
712             } lib_IterQuit($ats, \$e);
713             }
714             # }}}
715             # print_timing_arc
716             # {{{
717              
718             =head2 print_timing_arc
719              
720             Print timing arc of group G(must be a pin type group.) Example:
721              
722             $parser->print_timing_arc($pin_group);
723              
724             =cut
725             sub print_timing_arc {
726             my $self = shift;
727             my $g = shift;
728             my $gps = lib_GroupGetGroups($g,\$e);
729             my $pin_name = $self->get_group_name($g);
730             my $ng;
731             my $gt;
732             my $at;
733             my $related_pin;
734             my $timing_type;
735             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
736             if($self->check_group_type($ng, "timing")) {
737             $related_pin = $self->get_simple_attr_value($ng, "related_pin");
738             $timing_type = $self->get_simple_attr_value($ng, "timing_type");
739             print "$pin_name <- $related_pin : $timing_type\n";
740             }
741             } lib_IterQuit($gps, \$e);
742             }
743             # }}}
744             # print_groups
745             # {{{
746              
747             =head2 print_groups
748              
749             print_groups : void : (*group G)
750             Print groups contained in group G in format "type:name". Example:
751              
752             $p->print_groups($g);
753              
754             =cut
755              
756             sub print_groups {
757             my $self = shift;
758             my $g = shift;
759             my $gps = lib_GroupGetGroups($g,\$e);
760             my $ng;
761             my $gt;
762             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
763             $gt = lib_GroupGetGroupType($ng,\$e);
764             my $name = $self->get_group_name($ng);
765             print "$gt: $name \n";
766             } lib_IterQuit($gps, \$e);
767             }
768              
769             # }}}
770             # get_cell_delay
771             # {{{
772              
773             =head2 get_cell_delay
774              
775             $parser->get_cell_delay($pin_group);
776              
777             =cut
778              
779             sub get_cell_delay {
780             my $self = shift;
781             my $g = shift;
782             my $gps = lib_GroupGetGroups($g,\$e);
783             my $ng;
784             my $arc_group;
785             my $gname = $self->get_group_name($g);
786             my $delay = "N/A";
787             my $pin = "N/A";
788             my $rise = "N/A";
789             my $fall = "N/A";
790             my @delay = ();
791              
792             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
793             if ($self->check_group_type($ng,"timing")){
794             $pin = $self->get_simple_attr_value($ng, "related_pin");
795             $rise = $self->get_lookup_table_center($ng, "cell_rise");
796             $fall = $self->get_lookup_table_center($ng, "cell_fall");
797             push @delay, "$gname <- $pin, rise: $rise, fall: $fall";
798             }
799             } lib_IterQuit($gps, \$e);
800              
801             return @delay;
802              
803             }
804              
805             # }}}
806             # is_var
807             # {{{
808              
809             =head2 is_var
810              
811             is_var :
812             Return the handle of group type `cell'.
813              
814             =cut
815             sub is_var{
816             my $self = shift;
817             my $a = shift;
818             return lib_SimpleAttrGetIsVar($a, \$e);
819             }
820             # }}}
821              
822             =head1 COMPLEX FUNTIONS
823              
824             =cut
825              
826             # extract_group
827             # {{{
828              
829             =head2 extract_group
830              
831             extract_group : string : (*group G, int indent)
832             Return the whole content of the group G.
833              
834             =cut
835             sub extract_group{
836             my $self = shift;
837             my $g = shift;
838             my $pre_indent = shift;
839             my $at;
840             my $vtype;
841             my $is_var;
842             my $print_op;
843             my $print_content;
844             my $indent = $pre_indent;
845             my $indent2 = " ".$pre_indent;
846             my $indent3 = " ".$pre_indent;
847             my $eg = "";
848              
849             # type, name
850             $eg .= $indent.$self->get_group_type($g)." (".$self->get_group_name($g). ") {\n";
851              
852             # attribute
853             $eg .= $self->all_attrs($g,$indent);
854              
855             # print the groups
856             my $ng;
857             my $gt;
858             my $gps = lib_GroupGetGroups($g,\$e);
859             while( !lib_ObjectIsNull($ng = lib_IterNextGroup($gps,\$e), \$e2)){
860             $eg .= $self->extract_group($ng,$indent2);
861             } lib_IterQuit($gps, \$e);
862              
863             $eg .= $indent."}\n";
864             return $eg;
865             }
866             # }}}
867             # extract_group_1
868             # {{{
869              
870             =head2 extract_group_1
871              
872             extract_group_1 : string : (*group G, int indent)
873             Return the "surface" of the group G.
874              
875             =cut
876              
877             sub extract_group_1{
878             my $self = shift;
879             my $g = shift;
880             my $pre_indent = shift;
881             my $at;
882             my $vtype;
883             my $is_var;
884             my $print_op;
885             my $print_content;
886             my $indent = $pre_indent;
887             my $indent2 = " ".$pre_indent;
888             my $indent3 = " ".$pre_indent;
889             my $eg = "";
890              
891             # type, name
892             $eg .= $indent.$self->get_group_type($g)." (".$self->get_group_name($g). ") {\n";
893              
894             $eg .= $self->all_attrs($g,$indent);
895              
896             return $eg;
897             }
898             # }}}
899             # all_attrs
900             # {{{
901              
902             =head2 all_attrs
903              
904             all_attrs : string : (*group G, int indent)
905             Return the handle of group type `cell'.
906              
907             =cut
908             sub all_attrs {
909             my $self = shift;
910             my $g = shift;
911             my $pre_indent = shift;
912             my $is_var;
913             my $print_op;
914             my $print_content;
915             my $vtype;
916             my $at;
917             my $indent = $pre_indent;
918             my $indent2 = " ".$pre_indent;
919             my $indent3 = " ".$pre_indent;
920             my $eg = "";
921              
922              
923             # print Attribute
924             my $ats = lib_GroupGetAttrs($g, \$e);
925             while (!lib_ObjectIsNull (($at = lib_IterNextAttr($ats, \$e)), \$e2)) {
926             my $atype = $self->get_attr_type($at);
927             my $aname = $self->get_attr_name($at);
928             if($aname eq "default_operating_conditions"){
929             next;
930             }else{
931             $eg .= $indent2.$aname;
932             }
933              
934             $is_var = $self->is_var($at);
935             if($is_var){
936             $print_op = " =";
937             }else{
938             $print_op = " :";
939             }
940              
941             # Simple attribute
942             if ($atype == $liberty::SI2DR_SIMPLE) {
943             $vtype = $self->get_value_type($at);
944             # STRING
945             if($vtype == $liberty::SI2DR_STRING){
946             $eg .= $print_op." \"" . lib_SimpleAttrGetStringValue($at,\$e) . "\";\n";
947             # FLOAT64
948             }elsif($vtype == $liberty::SI2DR_FLOAT64){
949             $eg .= $print_op." ".lib_SimpleAttrGetFloat64Value($at,\$e)." ;\n";
950             # INT32
951             }elsif($vtype == $liberty::SI2DR_INT32){
952             $eg .= $print_op." ".lib_SimpleAttrGetInt32Value($at,\$e)." ;\n";
953             # EXPR
954             }elsif($vtype == $liberty::SI2DR_EXPR){
955             $eg .= "expr\n";
956             die;
957             # BOOLEAN
958             }elsif($vtype == $liberty::SI2DR_BOOLEAN){
959             if(lib_SimpleAttrGetBooleanValue($at,\$e)){
960             $print_content = "true";
961             }else{
962             $print_content = "false";
963             }
964             $eg .= " ".$print_op." ".$print_content." ;\n";
965             }
966             # Complex attribute
967             }elsif($atype == $liberty::SI2DR_COMPLEX){
968             my $vals = lib_ComplexAttrGetValues($at,\$e);
969             my $first = 1;
970             $eg .= " ( ";
971              
972             while(1){
973             my $cplex = lib_IterNextComplex($vals, \$e);
974             my $vt = lib_ComplexValGetValueType($cplex, \$e);
975              
976             # STRING
977             if($vt == $liberty::SI2DR_STRING) {
978             my $str6 = lib_ComplexValGetStringValue($cplex, \$e);
979             if(!$first){
980             $eg .= ",";
981             $eg .= "\\\n ";
982             $eg .= $indent3." "."\"".$str6."\"";
983             }else{
984             $eg .= "\"$str6\"";
985             }
986             # FLOAT64
987             } elsif($vt == $liberty::SI2DR_FLOAT64) {
988             my $f1 = lib_ComplexValGetFloat64Value($cplex, \$e);
989             $eg .= $f1;
990             # Boolean
991             } elsif($vt == $liberty::SI2DR_INT32) {
992             $eg .= "Boolean\n";
993             die;
994             # String
995             } elsif($vt == $liberty::SI2DR_BOOLEAN) {
996             $eg .= "String\n";
997             die;
998             # Expr
999             } elsif($vt == $liberty::SI2DR_EXPR) {
1000             $eg .= "Expr\n";
1001             die;
1002             } else{ last; }
1003             $first = 0;
1004             }
1005             $eg .= ");\n";
1006             }
1007             } lib_IterQuit($ats, \$e);
1008              
1009             # print Defines
1010             my $deft;
1011             my $def;
1012             my $defs = lib_GroupGetDefines($g, \$e);
1013             while (!lib_ObjectIsNull (($def = lib_IterNextDefine($defs, \$e)), \$e2)) {
1014             my $deftype = lib_DefineGetValueType($def,\$e);
1015             if ($deftype == $liberty::SI2DR_STRING){
1016             $deft = "string";
1017             }elsif($deftype == $liberty::SI2DR_FLOAT64){
1018             $deft = "float";
1019             }elsif($deftype == $liberty::SI2DR_INT32){
1020             $deft = "integer";
1021             }elsif($deftype == $liberty::SI2DR_BOOLEAN){
1022             $deft = "boolean";
1023             }
1024             my $defg = lib_DefineGetAllowedGroupName($def,\$e);
1025             my $defn = lib_DefineGetName($def,\$e);
1026              
1027             $eg .= $indent2."define(".$defn.", ".$defg.", ".$deft.");\n";
1028             } lib_IterQuit($defs, \$e);
1029              
1030             return $eg;
1031             }
1032             # }}}
1033              
1034             =head1 PRIMITIVE FUNCTIONS
1035              
1036             lib_PICreateGroup
1037             lib_GroupCreateAttr
1038             lib_AttrGetAttrType
1039             lib_AttrGetName
1040             lib_ComplexAttrAddInt32Value
1041             lib_ComplexAttrAddStringValue
1042             lib_ComplexAttrAddBooleanValue
1043             lib_ComplexAttrAddFloat64Value
1044             lib_ComplexAttrAddExprValue
1045             lib_ComplexAttrGetValues
1046             lib_IterNextComplex
1047             lib_ComplexValGetValueType
1048             lib_ComplexValGetInt32Value
1049             lib_ComplexValGetFloat64Value
1050             lib_ComplexValGetStringValue
1051             lib_ComplexValGetBooleanValue
1052             lib_ComplexValGetExprValue
1053             lib_SimpleAttrGetValueType
1054             lib_SimpleAttrGetInt32Value
1055             lib_SimpleAttrGetFloat64Value
1056             lib_SimpleAttrGetStringValue
1057             lib_SimpleAttrGetBooleanValue
1058             lib_SimpleAttrGetExprValue
1059             lib_SimpleAttrSetInt32Value
1060             lib_SimpleAttrSetBooleanValue
1061             lib_SimpleAttrSetFloat64Value
1062             lib_SimpleAttrSetStringValue
1063             lib_SimpleAttrSetExprValue
1064             lib_SimpleAttrGetIsVar
1065             lib_SimpleAttrSetIsVar
1066             lib_ExprDestroy
1067             lib_CreateExpr
1068             lib_CreateBooleanValExpr
1069             lib_CreateDoubleValExpr
1070             lib_CreateStringValExpr
1071             lib_CreateIntValExpr
1072             lib_CreateBinaryOpExpr
1073             lib_CreateUnaryOpExpr
1074             lib_ExprToString
1075             lib_ExprGetType
1076             lib_ValExprGetValueType
1077             lib_IntValExprGetInt
1078             lib_DoubleValExprGetDouble
1079             lib_BooleanValExprGetBoolean
1080             lib_StringValExprGetString
1081             lib_OpExprGetLeftExpr
1082             lib_OpExprGetRightExpr
1083             lib_GroupCreateDefine
1084             lib_DefineGetInfo
1085             lib_DefineGetName
1086             lib_DefineGetAllowedGroupName
1087             lib_DefineGetValueType
1088             lib_GroupCreateGroup
1089             lib_GroupGetGroupType
1090             lib_GroupGetComment
1091             lib_GroupSetComment
1092             lib_AttrGetComment
1093             lib_AttrSetComment
1094             lib_DefineGetComment
1095             lib_DefineSetComment
1096             lib_GroupAddName
1097             lib_GroupDeleteName
1098             lib_PIFindGroupByName
1099             lib_GroupFindGroupByName
1100             lib_GroupFindAttrByName
1101             lib_GroupFindDefineByName
1102             lib_PIFindDefineByName
1103             lib_PIGetGroups
1104             lib_GroupGetGroups
1105             lib_GroupGetNames
1106             lib_GroupGetAttrs
1107             lib_GroupGetDefines
1108             lib_IterNextGroup
1109             lib_IterNextName
1110             lib_IterNextAttr
1111             lib_IterNextDefine
1112             lib_IterQuit
1113             lib_ObjectDelete
1114             lib_PIGetErrorText
1115             lib_PIGetNullId
1116             lib_PIInit
1117             lib_PIQuit
1118             lib_ObjectGetObjectType
1119             lib_ObjectGetOwner
1120             lib_ObjectIsNull
1121             lib_ObjectIsSame
1122             lib_ObjectIsUsable
1123             lib_ObjectSetFileName
1124             lib_ObjectSetLineNo
1125             lib_ObjectGetLineNo
1126             lib_ObjectGetFileName
1127             lib_ReadLibertyFile
1128             lib_WriteLibertyFile
1129             lib_CheckLibertyLibrary
1130             lib_PIGetTraceMode
1131             lib_PIUnSetTraceMode
1132             lib_PISetTraceMode
1133             lib_PISetDebugMode
1134             lib_PIUnSetDebugMode
1135             lib_PIGetDebugMode
1136             lib_PISetNocheckMode
1137             lib_PIUnSetNocheckMode
1138             lib_PIGetNocheckMode
1139             lib_GroupMoveAfter
1140             lib_GroupMoveBefore
1141              
1142              
1143             =head1 SEE ALSO
1144              
1145             =head2 OpenSource Liberty Project
1146              
1147             http://www.opensourceliberty.org
1148              
1149             =head1 AUTHOR
1150              
1151             yorkwu, Eyorkwuo@gmail.comE
1152              
1153             =head1 COPYRIGHT AND LICENSE
1154              
1155             This library is free software; you can redistribute it and/or modify
1156             it under the same terms as Perl itself, either Perl version 5.8.5 or,
1157             at your option, any later version of Perl 5 you may have available.
1158              
1159              
1160             =cut
1161              
1162             1;
1163             # vim:fdm=marker