Annotation of sbbs/src/xpdev/genpack.pl, revision 1.1

1.1     ! root        1: #!/usr/bin/perl
        !             2: 
        !             3: if($#ARGV != 2) {
        !             4:        print <<ENDOFUSAGE;
        !             5: Usage: $0 infile.h outhead.h outprog.c
        !             6: 
        !             7: ENDOFUSAGE
        !             8:        exit(1);
        !             9: }
        !            10: 
        !            11: my ($infile, $outhead, $outc) = @ARGV;
        !            12: open IN,'<',$infile;
        !            13: 
        !            14: while (<IN>) {
        !            15:        $header .= $_;
        !            16: }
        !            17: close IN;
        !            18: 
        !            19: my $defs='';
        !            20: my $protos='';
        !            21: my $functions='';
        !            22: 
        !            23: my $count = 0;
        !            24: my @structs = ();
        !            25: while($header =~ m/struct\s+([^\s\r\n]*)[\s\r\n]+{([^}]*)}/gs) {
        !            26:        my($name, $def) = ($1,$2);
        !            27:        my ($packcode, $unpackcode, $size, @ints) = parse_defs($name, $def);
        !            28:        if(defined $size) {
        !            29:                $count++;
        !            30:                push @structs,"+ $name";
        !            31:                $defs .= $size;
        !            32:                $protos .= "int pack_$name\_struct(char *buf, struct $name *data);\n";
        !            33:                $protos .= "int unpack_$name\_struct(struct $name *data, char *buf);\n";
        !            34:                $functions .= "int pack_$name\_struct(char *buf, struct $name *data)\n";
        !            35:                $functions .= "{\n";
        !            36:                $functions .= "\tchar\t*p;\n";
        !            37:                if($#ints >= 0) {
        !            38:                        $functions .= "\tint\t\t".join(', ',@ints).";\n";
        !            39:                }
        !            40:                $functions .="\n\tp = buf;\n";
        !            41:                $functions .= $packcode;
        !            42:                $functions .="\n\treturn((int)(p-buf));\n}\n\n";
        !            43:                $functions .= "int unpack_$name\_struct(struct $name *data, char *buf)\n";
        !            44:                $functions .= "{\n";
        !            45:                $functions .= "\tchar\t*p;\n";
        !            46:                if($#ints >= 0) {
        !            47:                        $functions .= "\tint\t\t".join(', ',@ints).";\n";
        !            48:                }
        !            49:                $functions .="\n\tp = buf;\n";
        !            50:                $functions .= $unpackcode;
        !            51:                $functions .="\n\treturn((int)(p-buf));\n}\n\n";
        !            52:        }
        !            53:        else {
        !            54:                push @structs,"! $name";
        !            55:        }
        !            56: }
        !            57: 
        !            58: if($count) {
        !            59:        open HEAD,'>',$outhead;
        !            60:        open C,'>',$outc;
        !            61: 
        !            62:        print HEAD "/* Generated by genpack.pl from $infile on ".(scalar localtime(time))." */\n\n";
        !            63:        my $macro = uc($outhead);
        !            64:        $macro=~s/[^A-Z0-9]/_/g;
        !            65:        print HEAD '#ifndef _INCLUDED_',$macro,"\n";
        !            66:        print HEAD '#define _INCLUDED_',$macro,"\n\n";
        !            67:        print HEAD "#include \"$infile\"\n#include \"xpendian.h\"\n\n";
        !            68:        print HEAD "/* *_SIZE macros are the packed buffer size requred */\n";
        !            69:        print HEAD $defs;
        !            70:        print HEAD "\n/* Function prototypes */\n";
        !            71:        print HEAD "#if defined(__cplusplus)\nextern \"C\" {\n#endif\n";
        !            72:        print HEAD $protos;
        !            73:        print HEAD "#if defined(__cplusplus)\n}\n#endif";
        !            74:        print HEAD "\n\n";
        !            75:        print HEAD "#endif /* Do not add anything after this line! */\n";
        !            76:        close HEAD;
        !            77: 
        !            78:        open C,'>',$outc;
        !            79:        print HEAD "/* Generated by genpack.pl from $infile on ".(scalar localtime(time))." */\n\n";
        !            80:        print C "#include \"$outhead\"\n\n";
        !            81:        print C $functions;
        !            82:        print C "\n";
        !            83:        close C;
        !            84: 
        !            85:        print "$count structures read successfully\n+ indicates functions were created\n! indicates a failure\n\n";
        !            86:        print join("\n", @structs),"\n";
        !            87: }
        !            88: else {
        !            89:        print "No structures imported... files not created.\n";
        !            90: }
        !            91: 
        !            92: sub parse_defs
        !            93: {
        !            94:        my ($sname, $defs)=@_;
        !            95: 
        !            96:        my $packcode='';
        !            97:        my $unpackcode='';
        !            98:        my %vars=();
        !            99:        my %sizes=();
        !           100: 
        !           101:        # Remove comments
        !           102:        $defs=~s|/\*.*?\*/||gs;
        !           103:        my @lines=split(/[\r\n]+/, $defs);
        !           104:        foreach my $line (@lines) {
        !           105:                my ($p, $u);
        !           106:                my @newvars;
        !           107:                my $this_size=0;
        !           108:                chomp $line;
        !           109:                next if($line =~ /^\s*$/);
        !           110:                if($line =~ m/^\s*((?:char)|(?:BYTE)|(?:INT16)|(?:WORD)|(?:INT32)|(?:DWORD)|(?:float))\s+([^\s]+)\s*;\s*$/) {
        !           111:                        my ($type, $name) = ($1, $2);
        !           112:                        ($p, $u, @newvars) = parse_line(\%sizes, $type, $name, 0);
        !           113:                }
        !           114:                elsif($line =~ m/^\s*struct\s+([^\s]+)\s+([^\s]+)\s*;\s*$/) {
        !           115:                        my ($struct, $name) = ($1, $2);
        !           116:                        ($p, $u, @newvars) = parse_line(\%sizes, $struct, $name, 1);
        !           117:                }
        !           118:                else {
        !           119:                        print "Cannot parse: $line\n";
        !           120:                        return();
        !           121:                }
        !           122:                if(!defined $u) {
        !           123:                        return();
        !           124:                }
        !           125:                @vars{@newvars}=@newvars;
        !           126:                $packcode .= $p;
        !           127:                $unpackcode .= $u;
        !           128:        }
        !           129:        my $sizedef = '#define '.uc($sname)."_SIZE\t(";
        !           130:        foreach my $key (keys %sizes) {
        !           131:                if(defined $sizes{$key}{count} && !defined $sizes{$key}{multiplier}) {
        !           132:                        if($sizes{$key}{count} == 1) {
        !           133:                                $sizedef .= "$key + ";
        !           134:                        }
        !           135:                        else {
        !           136:                                $sizedef .= "($key * $sizes{$key}{count}) + ";
        !           137:                        }
        !           138:                }
        !           139:                elsif(!defined $sizes{$key}{count} && defined $sizes{$key}{multiplier}) {
        !           140:                        $sizes{$key}{multiplier} = substr($sizes{$key}{multiplier}, 0, -3);
        !           141:                        $sizedef .= "($key * ($sizes{$key}{multiplier})) + ";
        !           142:                }
        !           143:                elsif(defined $sizes{$key}{count} && defined $sizes{$key}{multiplier}) {
        !           144:                        $sizes{$key}{multiplier} = substr($sizes{$key}{multiplier}, 0, -3);
        !           145:                        $sizedef .= "($key * ($sizes{$key}{count} + $sizes{$key}{multiplier})) + ";
        !           146:                }
        !           147:        }
        !           148:        $sizedef = substr($sizedef, 0, -3) . ")\n";
        !           149:        return($packcode, $unpackcode, $sizedef, sort keys %vars);
        !           150: }
        !           151: 
        !           152: sub parse_line
        !           153: {
        !           154:        my ($sizes, $type, $name, $struct) = @_;
        !           155:        my $tabs = "\t";
        !           156:        my $end = '';
        !           157:        my %vars=();
        !           158:        my $nextint='i';
        !           159:        my ($packcode, $unpackcode);
        !           160:        my $sizekey;
        !           161: 
        !           162:        if($struct) {
        !           163:                $sizekey = uc($type).'_SIZE';
        !           164:        }
        !           165:        else {
        !           166:                $sizekey = "sizeof($type)";
        !           167:        }
        !           168:        if($name =~ /\[/) {             # Handle arrays!
        !           169:                while($name =~ s/\[([^\]]+)\]/;$nextint;/) {
        !           170:                        my $size = $1;
        !           171:                        $packcode .= $tabs."for($nextint = 0; $nextint < $size; $nextint++) {\n";
        !           172:                        $unpackcode .= $tabs."for($nextint = 0; $nextint < $size; $nextint++) {\n";
        !           173:                        $sizes->{$sizekey}{multiplier} .= "$size * ";
        !           174:                        $end = "$tabs}\n$end";
        !           175:                        $tabs .= "\t";
        !           176:                        $vars{$nextint}=1;
        !           177:                        $nextint=chr(ord($nextint)+1);
        !           178:                }
        !           179:                $sizes->{$sizekey}{multiplier} = substr($sizes->{$sizekey}{multiplier}, 0, -3);
        !           180:                $sizes->{$sizekey}{multiplier} .= ' + ';
        !           181:                $name =~ s/;(.);/[$1]/g;
        !           182:        }
        !           183:        else {
        !           184:                $sizes->{$sizekey}{count}++;
        !           185:        }
        !           186:        $name = "data->$name";
        !           187:        my ($p, $u) = pack_line($type, $name, $struct, $tabs);
        !           188:        $p = "$packcode$p$end";
        !           189:        $u = "$unpackcode$u$end";
        !           190:        return($p, $u, sort keys %vars);
        !           191: }
        !           192: 
        !           193: sub pack_line
        !           194: {
        !           195:        my ($type, $name, $struct, $tabs)=@_;
        !           196:        my $packcode = '';
        !           197:        my $unpackcode = '';
        !           198: 
        !           199:        # ie: *(INT32)p = LE_LONG($name);
        !           200:        if(!$struct) {
        !           201:                if($type eq 'char') {
        !           202:                        $packcode .= $tabs."*p = $name;\n";
        !           203:                        $packcode .= $tabs."p++;\n";
        !           204:                        $unpackcode .= $tabs."$name = *p;\n";
        !           205:                        $unpackcode .= $tabs."p++;\n";
        !           206:                }
        !           207:                elsif($type eq 'BYTE') {
        !           208:                        $packcode .= $tabs."*(BYTE *)p = $name;\n";
        !           209:                        $packcode .= $tabs."p++;\n";
        !           210:                        $unpackcode .= $tabs."$name = *(BYTE *)p;\n";
        !           211:                        $unpackcode .= $tabs."p++;\n";
        !           212:                }
        !           213:                elsif($type eq 'INT16') {
        !           214:                        $packcode .= $tabs."*(INT16 *)p = LE_SHORT($name);\n";
        !           215:                        $packcode .= $tabs."p += sizeof(INT16);\n";
        !           216:                        $unpackcode .= $tabs."$name = LE_SHORT(*(INT16 *)p);\n";
        !           217:                        $unpackcode .= $tabs."p += sizeof(INT16);\n";
        !           218:                }
        !           219:                elsif($type eq 'WORD') {
        !           220:                        $packcode .= $tabs."*(WORD *)p = LE_SHORT($name);\n";
        !           221:                        $packcode .= $tabs."p += sizeof(WORD);\n";
        !           222:                        $unpackcode .= $tabs."$name = LE_SHORT(*(WORD *)p);\n";
        !           223:                        $unpackcode .= $tabs."p += sizeof(WORD);\n";
        !           224:                }
        !           225:                elsif($type eq 'INT32') {
        !           226:                        $packcode .= $tabs."*(INT32 *)p = LE_LONG($name);\n";
        !           227:                        $packcode .= $tabs."p += sizeof(INT32);\n";
        !           228:                        $unpackcode .= $tabs."$name = LE_LONG(*(INT32 *)p);\n";
        !           229:                        $unpackcode .= $tabs."p += sizeof(INT32);\n";
        !           230:                }
        !           231:                elsif($type eq 'DWORD') {
        !           232:                        $packcode .= $tabs."*(DWORD *)p = LE_LONG($name);\n";
        !           233:                        $packcode .= $tabs."p += sizeof(DWORD);\n";
        !           234:                        $unpackcode .= $tabs."$name = LE_LONG(*(DWORD *)p);\n";
        !           235:                        $unpackcode .= $tabs."p += sizeof(DWORD);\n";
        !           236:                }
        !           237:                elsif($type eq 'float') {
        !           238:                        $packcode .= $tabs."*(DWORD *)p = LE_LONG(*((DWORD *)&($name)));\n";
        !           239:                        $packcode .= $tabs."p += sizeof(float);\n";
        !           240:                        $unpackcode .= $tabs."*(((DWORD *)&($name))) = LE_LONG(*(DWORD *)p);\n";
        !           241:                        $unpackcode .= $tabs."p += sizeof(DWORD);\n";
        !           242:                }
        !           243:                else {
        !           244:                        print "Unhandled type: $type\n";
        !           245:                        return(undef, undef);
        !           246:                }
        !           247:        }
        !           248:        else {
        !           249:                $packcode .= $tabs."p += pack_$type\_struct(p, &($name));\n";
        !           250:                $unpackcode .= $tabs."p += unpack_$type\_struct(&($name), p);\n";
        !           251:        }
        !           252: 
        !           253:        return($packcode, $unpackcode);
        !           254: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.