| Here's the perl script (attached). I tried to upload it to the Runtime_Differences page, but it looks like I can only update .gif/.jpeg files. Any advice about where to put it? I think I got all the cases: - if the class name already has lz. , no change - if the class name is a class defined in the input, then add lz. (?) [requires two passes] - if the class name is class for a LFC tagname, convert it to tagname and add lz. (new LzView => lz.view) I coded my list from WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java - if the class name is a known laszlo class, then add lz. I have a fixed list embedded in the script, generated via find WEB-INF/lps | xargs grep class - new global[*] is converted to new lz[*] - otherwise, no change (this includes Object, Array, ...). Let me know if there are any changes, should be easy to modify. Script includes a testcase to try all these situations. - Don |
#!/usr/bin/perl # Copyright 2008 Laszlo Systems. Use according to license terms. # # convert_instantiation.pl # Helps to convert 4.1 lzs programs that use deprecated form # of 'new'. For example: # # 'new LzText' is converted to 'new lz.text' # # See usage message. # # Warnings: # # - PLEASE BACK UP your entire work directory before starting. # # - Please compare the end result of each changed file with the # version before changing (filename.bak) and verify that the # changes make sense. # # Should work with Perl 5 or greater. # tested on OSX 10.5.3 with perl v5.8.8 # Author: Don Anderson
# The only 'native' classes that you might say `new *` or `x instanceof *` about are:
#
# Object, Array, String, Number, or Boolean.
#
#So we should be able to add to the conversion script that if you see `new *` or `x instanceof *` and * does not start with lz. and is not one of the five native classes above, you should rewrite it to lz.*.
#
#We also need to cover the case `new global[*]` needs to become `new lz[*]`.
#
#Icing on the cake would be to replace instances of the LFC class names with their tagname, e.g., (LzView becomes lz.view).
#
# This list is derived from
# WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java
#
%lzxname = (
LzNode => "node",
LzView => "view",
LzText => "text",
LzInputText => "inputtext",
LzCanvas => "canvas",
LzScript => "script",
LzAnimatorGroup => "animatorgroup",
LzAnimator => "animator",
LzLayout => "layout",
LzState => "state",
LzCommand => "command",
LzSelectionManager => "selectionmanager",
LzDataSelectionManager => "dataselectionmanager",
LzDatapointer => "datapointer",
LzDataProvider => "dataprovider",
LzDatapath => "datapath",
LzDataset => "dataset",
LzDatasource => "datasource",
LzHTTPDataProvider => "lzhttpdataprovider",
LzLibrary => "import",
);
# This list of known classes in Laszlo
# TODO: we might want a better way to maintain this list.
# This list was generated via:
# $ cd WEB-INF/lps
# $ find . -type f -print | grep 'lzs$' | \
# xargs grep '^[ ]*class[ ]' | \
# sed -e 's/[ ][ ]*/ /' \
# -e 's/.*:[ ]*class[ ]//' \
# -e 's/ .*//' | sort > /tmp/classes
%lzsclassname = (
AnonDatasetGenerator => "",
ColorUtilsClass => "",
LzAlwaysExpr => "",
LzAudioKernel => "",
LzAudioService => "",
LzBrowserKernel => "",
LzBrowserKernel => "",
LzBrowserKernel => "",
LzBrowserService => "",
LzCSSStyleClass => "",
LzCSSStyleDeclaration => "",
LzCSSStyleRule => "",
LzCSSStyleSheet => "",
LzCommand => "",
LzConstraintExpr => "",
LzContextMenu => "",
LzContextMenuItem => "",
LzContextMenuItemKernel => "",
LzContextMenuItemKernel => "",
LzContextMenuItemKernel => "",
LzContextMenuKernel => "",
LzContextMenuKernel => "",
LzContextMenuKernel => "",
LzDataAttrBind => "",
LzDataElement => "",
LzDataNode => "",
LzDataProvider => "",
LzDataRequest => "",
LzDataSelectionManager => "",
LzDataText => "",
LzDatapointer => "",
LzDictionary => "",
LzEventable => "",
LzFont => "",
LzFontManagerClass => "",
LzHTTPDataProvider => "",
LzHTTPDataRequest => "",
LzIdleService => "",
LzInitExpr => "",
LzLibrary => "",
LzLibraryCleanup => "",
LzLibraryLoader => "",
LzLoader => "",
LzMediaLoader => "",
LzMessage => "",
LzOnceExpr => "",
LzParam => "",
LzParsedPath => "",
LzRefNode => "",
LzSelectionManager => "",
LzStyleAttr => "",
LzStyleAttrBinder => "",
LzStyleExpr => "",
LzStyleIdent => "",
LzStyleSheet => "",
LzTimerService => "",
LzTrackService => "",
LzUtilsClass => "",
LzValueExpr => "",
LzViewLinkage => "",
__LzHttpDatasetPoolClass => "",
__LzLeak => "",
__LzLeaks => "",
);
use File::Basename;
use File::Copy;
use Getopt::Std;
################
my $VERSION = "1.0.0";
my $PROG = basename($0);
my $USAGE = <<END;
Usage: perl convert_instantiation.pl [ options ] filename...
Options:
-d debuglevel
get debugging info for development
-t
create output for simple tests in /tmp/convtest
-v
show version number and exit
For each file, a backup file is made (filename.bak) and the file will
be converted, with the result put into filename.
Examples:
# Convert all the lzx files in the directory, doing all conversions.
\$ perl convert_instantiation.pl *.lzs
END
################
##
# Other global variables
##
$DEBUGLEVEL=0; # set to non-zero to get successive amounts of debug out
$curfile = "unknown file"; # track current file for error messages
##
# debug(level, string);
# debugln(level, string);
# Show the string if the level is less or equal to
# the current debug level. debug(1, '...') is more likely
# to appear, and debug(9, '...') least likely.
##
sub debug {
my $level = $_[0];
my $str = $_[1];
if ($level <= $DEBUGLEVEL) {
print STDOUT $str;
}
}
sub debugln {
debug($_[0], $_[1] . "\n");
}
##
# debugentry(level, funcname, @_);
# Show the function entry with args if level is <= current debug level.
##
sub debugentry {
my $n = $#_;
my $argstr = "";
my $i = 2;
while ($i <= $n) {
if ($i != 2) {
$argstr .= ", ";
}
$argstr .= $_[$i];
$i++;
}
debugln($_[0], $_[1] . "(" . $argstr . ")");
}
##
# warning(string)
# Show a warning to user.
##
sub warning {
print STDERR "$curfile: Warning: " . $_[0] . "\n";
}
##
# create_test(filename);
# Put a test file into place.
##
sub create_test {
my $file = $_[0];
unlink($file);
open OUT, ">$file" || die("Cannot create $file");
# basic tests, also with '' delimiter
print OUT
"// file to convert\n" .
"new something\n" .
"new LzView // want lz.view\n" .
" y = new node\n" .
" class myclass extends foo { }\n" .
"do_not_convert = newsome\n\n" .
"y = n instanceof z\n" .
"already_converted = instanceof lz.xyz\n" .
"y = n instanceof Boolean\n" .
"y = n instanceof LzView // want lz.view\n" .
"y = n instanceof view" .
"y = n instanceof myclass // want lz.myclass\n" .
"y = new myotherclass // want lz.myotherclass\n" .
"y = new global[*] // want lz[*]\n" .
"y = new somethingelse[*]\n" .
"y = n instanceof LzParam // want lz.LzParam\n" .
"y = n instanceof LzView // want lz.view\n" .
"y = new LzView(new Integer(new LzNode(), new LzView)) // 3 subs\n" .
"class myotherclass { }\n";
close OUT;
print STDOUT "Testing $file\n";
}
##
# file_cannot_exist(filename)
# Complain and die if the file exists.
##
sub file_cannot_exist {
my $file = $_[0];
if ( -f "$file" ) {
print STDERR "$PROG: $file already exists, please rename/remove it and run again\n";
exit(1);
}
}
##
# add_lz_prefix(classnm)
#
##
sub add_lz_prefix() {
my $nm = $_[0];
if (exists $lzxname{$nm}) {
return 'lz.' . $lzxname{$nm};
}
if (exists $lzsclassname{$nm}) {
return 'lz.' . $nm;
}
return $nm; # false
}
##
# track_class(nm)
# Do all conversions for the file.
##
sub track_class {
my $line = $_[0];
if ($line =~ /\s*class\s+(\w+)\b/) {
# register that we know about this class
$lzsclassname{$1} = "";
debugln(1, "CLASS match: $1");
}
}
##
# emit_content(HANDLE, string)
# Emits the content to the handle, applying some basic text transforms.
##
sub emit_content {
my $save = $_;
my $FH = $_[0];
$_ = $_[1];
while (/(.*)\b(new|instanceof)(\s+)(lz[.])?([_a-zA-Z0-9]+)\b(.*)/) {
debugln(3, "Line: $_");
debugln(3, "MATCH: $1, $2, $3, $4, $5, $6");
my($first, $keyword, $space, $optlz, $classnm, $last) = ($1, $2, $3, $4, $5, $6);
my $sub = "$optlz$classnm";
# Special case - handle 'new global[*]' => 'new lz[*]'
if ($keyword eq 'new' && $optlz eq '' && $classnm eq 'global') {
debugln(4, "match new global: $last");
if ($last =~ /^\s*\[\*\]/) {
$sub = "lz";
}
}
elsif ($optlz eq '') {
$sub = &add_lz_prefix($classnm);
}
# We insert @ around the keyword so we won't match it again.
# This allows us to successively match nested
# (e.g. 'new class1(new class2())') or sequential
# (e.g. 'new class1(), new class2()') items.
# We remove the @ after we've applied substitutions to the whole line.
$_ = "[EMAIL PROTECTED]@$space$sub$last";
debugln(3, "Modified: $_");
}
s/[EMAIL PROTECTED]@/new/g;
s/[EMAIL PROTECTED]@/instanceof/g;
# After matching, the newline may be lost.
# Add it again here so everything comes out even.
if ($_ !~ "\n") {
$_ .= "\n";
}
debugln(3, " EMIT CONTENT: " . $_);
print $FH $_ ;
$_ = $save;
return $inmethod;
}
##
# convert_file(filename)
# Do all conversions for the file.
##
sub convert_file {
my $file = $_[0];
my $inmethod=0;
my $event;
my $name;
debugentry(1, "convert_file", @_);
$curfile = $file;
copy("$file", "$file.bak") || die("Cannot copy to $file.bak");
# Two pass algorithm.
# First take note of all 'class' declarations
open(IN, "<$file") || die("Cannot open $file");
while (<IN>) {
track_class($_);
}
close(IN);
# Second, convert the files
open(IN, "<$file") || die("Cannot open $file");
unlink("$file.tmp");
open(OUT, ">$file.tmp") || die("Cannot create $file.tmp");
while (<IN>) {
emit_content(OUT, $_);
}
close(OUT);
close(IN);
move("$file.tmp", "$file") || die("Cannot create $file");
print STDOUT "Converted $file\n";
}
##
# Main program
# parse arguments and dispatch work to convert_file.
##
my $file;
my %options;
$ok = getopts("d:tx:v", \%options);
if (!$ok) {
print STDERR "$USAGE";
exit(1);
}
$DEBUGLEVEL = $options{d} || '0';
if ($options{v}) {
print STDOUT "$PROG: version $VERSION\n";
exit(0);
}
if ($options{t}) {
create_test("/tmp/convtest");
convert_file("/tmp/convtest");
exit(0);
}
if ($#ARGV < 0) {
print STDERR "$USAGE";
exit(1);
}
foreach $file (@ARGV) {
if (! -f $file) {
}
file_cannot_exist("$file.bak");
}
foreach $file (@ARGV) {
if (! -f $file ) {
print STDERR "$PROG: $file does not exist, skipping\n";
}
else {
convert_file($file);
}
}
On Jun 30, 2008, at 3:01 PM, P T Withington wrote:
-- Don Anderson Java/C/C++, Berkeley DB, systems consultant voice: 617-547-7881 email: [EMAIL PROTECTED] www: http://www.ddanderson.com |
