📄 obj2ptr
字号:
#!/usr/local/bin/perl## obj2ptr# Copyright (C) 1997 Norio Katayama## This library is free software; you can redistribute it and/or# modify it under the terms of the GNU Library General Public# License as published by the Free Software Foundation; either# version 2 of the License, or (at your option) any later version.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Library General Public License for more details.## You should have received a copy of the GNU Library General Public# License along with this library; if not, write to the Free# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.## 06/08/96 katayama@rd.nacsis.ac.jp# $Id: obj2ptr,v 1.4 1997/06/02 12:31:18 katayama Exp $#($program = $0) =~ s|^.*/||;$usage = <<"EOF";Usage: $program objHdrFileEOF ;if(@ARGV != 1) { die $usage;}$objHdrFile = $ARGV[0];## obtain class names#($objClass = $objHdrFile) =~ s|^.*/||;$objClass =~ s|\.[^\.]+$||;unless(($ptrHdrFile = $objHdrFile) =~ s/Obj\.hh/.hh/) { die("$program: object header file name must end with `Obj.hh', stopped");}($ptrSrcFile = $ptrHdrFile) =~ s/\.hh/\.cc/;($ptrClass = $ptrHdrFile) =~ s|^.*/||;$ptrClass =~ s|\.[^\.]+$||;## obtain public fields#open(HANDLE, $objHdrFile) || die("$program: cannot open `$objHdrFile'.\n");while(<HANDLE>) { s/\n$//; if(/^class\s+$objClass[\s:]/) { # # obtain super class # s/^class\s+$objClass\s*:\s*//; if(/^public\s+([A-Za-z_][A-Za-z_0-9]*)\s+\{$/) { $objSuperClass = $1; if($objSuperClass eq "HnObject") { $ptrSuperClass = 'HnPointer'; } elsif($objSuperClass =~ /^(.*)Obj$/) { $ptrSuperClass = $1; } else { die("$program: unexpected super class `$objSuperClass', ". "stopped"); } } &parseClass; } elsif(/^\/\*\{$/) { &getPreamble; }}close(HANDLE);&generateHdrFile;&generateSrcFile;exit 0;## get preamble#sub getPreamble { while(<HANDLE>) { s/\n$//; if(/^\}\*\/$/) { return 1; } else { push(@preambles, $_); } } die("$program: cannot find the end of the preamble, stopped");}## parse class#sub parseClass { local($inPublic); while(<HANDLE>) { s/\n$//; if(/^public:$/) { $inPublic = 1; } elsif(/^private:$/) { $inPublic = 0; } elsif(/^\};$/) { return 1; } elsif($inPublic) { if(/^\s*$objClass\s*\(/) { &getConstructor; } elsif(/\(/) { &getFunction; } elsif(/^\/\*\{$/) { &getEmbedded; } else { push(@fields, $_); } } } die("$program: cannot find the end of the class definition, stopped");}## get constructor#sub getConstructor { # find close parenthesis while(!/\)/) { push(@fields, $_); $_ = <HANDLE>; s/\n$//; } s/([^\)]*\))\s*//; push(@fields, "$1;"); # find open brace or semi-colon while(!/\{/ && !/;/) { $_ = <HANDLE>; s/\n$//; } # # remove inline # if(/\{/) { # find balanced close brace do { if(s/^[^\{\}]*\{[^\{\}]*//) { $level ++; } elsif(s/^[^\{\}]*\}[^\{\}]*//) { $level --; } else { $_ .= <HANDLE>; s/\n$//; } } while($level != 0); }}## get function #sub getFunction { # remove the keyword `virtual' s/^(\s*)virtual\s+/$1/; # find close parenthesis while(!/\)/) { push(@fields, $_); $_ = <HANDLE>; s/\n$//; } # remove the pure specifier s/\)\s*=\s*0\s*;/);/; # find open brace or semi-colon while(!/\{/ && !/;/) { push(@fields, $_); $_ = <HANDLE>; s/\n$//; } # # remove inline # if(/\{/) { s/([^\{]+)\s+\{/\{/; push(@fields, "$1;"); # find balanced close brace do { if(s/^[^\{\}]*\{[^\{\}]*//) { $level ++; } elsif(s/^[^\{\}]*\}[^\{\}]*//) { $level --; } else { $_ .= <HANDLE>; s/\n$//; } } while($level != 0); } else { push(@fields, $_); }}## get embedded#sub getEmbedded { while(<HANDLE>) { s/\n$//; if(/^\}\*\/$/) { return 1; } else { push(@embedded, $_); } } die("$program: cannot find the end of the embedded declaration, stopped");}## generate header file#sub generateHdrFile { local(@fields) = @fields; local($sec, $min, $hour, $mday, $mon, $year) = (localtime)[0..5]; local($when) = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec); open(HANDLE, ">$ptrHdrFile") || die("$program: cannot open `$ptrHdrFile', stopped"); print HANDLE <<"EOF";/* * $ptrHdrFile * * DO NOT EDIT THIS FILE! * * This file is automatically generated by $program. * $when */#ifndef _${ptrClass}_hh#define _${ptrClass}_hh#include "$ptrSuperClass.hh"EOF if(@preambles) { foreach(@preambles) { print HANDLE $_, "\n"; } print HANDLE "\n"; } print HANDLE <<"EOF";/* * $ptrClass */class $ptrClass: public $ptrSuperClass {private: friend class $objClass; $ptrClass(const $objClass *ptr) { HnPointer::assign((HnObject *)ptr); } $objClass *getObject(void) const { return ($objClass *)HnPointer::getObject(); }public: static const $ptrClass null; $ptrClass(void) {}public:EOF if(@embedded != 0) { foreach(@embedded) { print HANDLE $_, "\n"; } print HANDLE "\n"; } foreach(@fields) { if(s/^(\s*)$objClass\s*\(/ friend $ptrClass\n${1}new_$ptrClass\(/) { # constructor print HANDLE $_, "\n"; } elsif(/^\s*~$objClass\s*\(/) { # ignore destructor } else { print HANDLE $_, "\n"; } } if($ptrClass eq "HnString") { print HANDLE <<"EOF"; HnString toString(void) const { if(isInvalid()) return "HnString::null"; else return *this; }EOF } print HANDLE <<"EOF";};/* * ${ptrClass}Array */class ${ptrClass}Array: public HnPointer {private: friend class ${ptrClass}ArrayObj; ${ptrClass}Array(const ${ptrClass}ArrayObj *ptr) { HnPointer::assign((HnObject *)ptr); } ${ptrClass}ArrayObj *getObject(void) const { return (${ptrClass}ArrayObj *)HnPointer::getObject(); }public: static const ${ptrClass}Array null; ${ptrClass}Array(void) {}public: /* constructors */ friend ${ptrClass}Array new_${ptrClass}Array(void); friend ${ptrClass}Array new_${ptrClass}Array(const ${ptrClass}Array &ptr); /* clear, append, insert, and remove */ void clear(void); void append(const $ptrClass &ptr); void append(const ${ptrClass}Array &ptr); void insert(const $ptrClass &ptr, int index); $ptrClass remove(int index); void set(const $ptrClass &ptr, int index); void swap(int i, int j); /* length and get */ int length(void) const; $ptrClass &get(int i) const; $ptrClass &operator[](int i) const { return get(i); } /* utilities */ void push(const $ptrClass &ptr) { append(ptr); } $ptrClass pop(void) { return remove(length() - 1); } HnBool equals(const ${ptrClass}Array &ptr) const; int indexOf(const $ptrClass &ptr, int fromIndex) const; int indexOf(const $ptrClass &ptr) const { return indexOf(ptr, 0); } HnString toString(void) const;};#endif /* _${ptrClass}_hh */EOF close(HANDLE); 1;}## generate source file#sub generateSrcFile { local(@fields) = @fields; local($sec, $min, $hour, $mday, $mon, $year) = (localtime)[0..5]; local($when) = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec); open(HANDLE, ">$ptrSrcFile") || die("$program: cannot open `$ptrSrcfile', stopped"); print HANDLE <<"EOF";/* * $ptrSrcFile * * DO NOT EDIT THIS FILE! * * This file is automatically generated by $program. * $when */#include "$ptrHdrFile"#include "$objHdrFile"/* * $ptrClass */const $ptrClass $ptrClass::null;EOF ; while(@fields) { # remove comment $_ = shift(@fields); next if(/\/\//); if(/\/\*/) { while(!/\*\//) { $_ = shift(@fields); } $_ = shift(@fields); } # find open parenthesis if(/\(/) { # find close parenthesis while(!/\)/) { $_ .= shift(@fields); } # find semi-colon while(!/;/) { $_ .= shift(@fields); } &generateStub($_); } } &generateArray; close(HANDLE); 1;}## generate stub#sub generateStub { if(@_ != 1) { die("$program: generateStub() requires one argument, stopped"); } local($returnType, $methodName, $qualifier); $_ = @_[0]; # return type and method name if(s/\s*([^\(]*[^A-Za-z_~])(operator[^A-Za-z_~\(][^\(]*)\(//) { ($returnType = $1) =~ s/\s*$//; ($methodName = $2) =~ s/\s*$//; } elsif(s/\s*([^\(]*[^A-Za-z_0-9~])([A-Za-z_~][A-Za-z_0-9]*)\s*\(//) { ($returnType = $1) =~ s/\s*$//; ($methodName = $2) =~ s/\s*$//; } else { die("$program: cannot find function name at `$_', stopped"); } # parameters @params = (); while(s/\s*([^,\)]+),//) { push(@params, $1); } unless(s/\s*([^,\)]+)\)//) { die("$program: cannot find parameter list at `$_', stopped"); } push(@params, $1); # qualifier if(s/\s*([^\s].*)\s*;//) { $qualifier = $1; } # variables if(@params == 1 && $params[0] eq "void") { @variables = (); } else { @variables = (); foreach(@params) { if(/[^=]*[^A-Za-z_\d~]([A-Za-z_~][A-Za-z_\d]*)(\[\])?(\s*=.*)?$/) { push(@variables, $1); } else { die("$program: cannot find variable at `$_', stopped"); } } } if($methodName eq "$objClass") { &generateConstructorStub; } elsif($methodName eq "~$objClass") { # ignore } elsif($methodName eq "equals") { &generateEqualsStub; } elsif($methodName eq "toString") { &generateToStringStub; } elsif($methodName =~ /^operator/) { &generateOperatorStub; } elsif($returnType =~ s/^static\s+//) { &generateClassMethodStub; } else { &generateNormalStub; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -