From d886bfe475b06aa677f1024449925241a06e77f4 Mon Sep 17 00:00:00 2001 From: tadam Date: Sat, 26 Dec 2009 19:23:13 +0000 Subject: [PATCH] Add initial draft of fvwm-convert-2.6 In preparation for making 2.5.X stable, this script should help cement that by taking a stab at converting a 2.4.X version file to something 2.5.X (and hence 2.6.X in the future) can understand. I have no doubts it is not yet complete. --- AUTHORS | 1 + ChangeLog | 8 + NEWS | 5 + bin/fvwm-convert-2.6.1.in | 94 +++++++++- bin/fvwm-convert-2.6.in | 443 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 546 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 899e8ee7a..99f8f6d7f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -23,6 +23,7 @@ Make style matching honour a window's visible name (c.f. $[w.visiblename]) Added "bindings" option to PrintInfo command useful for debugging. Force windows on-screen where applicable when using "PositionPlacement UnderMouse". +Wrote initial version of the fvwm-convert-2.6 script. Bug fixes. Serge (gentoosiast) Koksharov: diff --git a/ChangeLog b/ChangeLog index 1192129b9..84b855882 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-12-26 Thomas Adam + * NEWS: + * AUTHORS: + * bin/fvwm-convert-2.6.in: + * bin/fvwm-convert-2.6.1.in: + First pass at a fvwm-convert-2.6 script to convert fvwm-2.4 syntax + files. + 2009-12-19 Thomas Adam * libs/Flocale.c (FlocaleEncodeString): Pre-initialise "len2" to zero, to avoid GCC warning during compilation. diff --git a/NEWS b/NEWS index 4031e74f9..94ee6e982 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ Note, the changes for the last STABLE release start with release ------------------------------------------------------------------- Changes in beta release 2.5.29 (not released yet) +* New features: + + - Added new fvwm-convert-2.6 script to convert older fvwm 2.4.x config + files. + * Bug fixes: - Fixed the InitialMapCommand style from running when FVWM is restarting. diff --git a/bin/fvwm-convert-2.6.1.in b/bin/fvwm-convert-2.6.1.in index b29ac448f..9527fca67 100644 --- a/bin/fvwm-convert-2.6.1.in +++ b/bin/fvwm-convert-2.6.1.in @@ -1,13 +1,99 @@ .\" @(#)@PACKAGE@-@VERSION@ @RELDATELONG@ .TH fvwm-convert-2.6 1 "@RELDATELONG@ (@VERSION@)" Fvwm "Fvwm Modules" .SH NAME -fvwm-convert-2.6 \- convert fvwm 2.4.x configuration file to fvwm 2.6.x style +fvwm-convert-2.6 \- convert fvwm 2.4.x configuration file to fvwm 2.6 style .SH SYNOPSIS .B fvwm-convert-2.6 -.RI [ source ] +.RI source .RI [ dest ] .SH DESCRIPTION .B fvwm-convert-2.6 -is ... +converts an fvwm 2.4.x configuration file into a fvwm 2.6 +file with compatible syntax. It is not suitable to convert older 2.x +configuration files. Please use +.B fvwm-convert-2.2 +to convert these to the 2.2.x format first, and then if necessary +.B fvwm-convert-2.4 +.PP +By default, +.B fvwm-convert-2.6 +won't look for a given config file. This must be specified as the first +parameter to +.B fvwm-convert-2.6 +Different source and destination files may be given. +If the destination file already exists, this program exits. +If no destination file is given, then the filename is +the same name as the source file with the suffix ".converted" +added. Without an absolute path given as the destination path to the +destination file, the program will create the destination file in the CWD. +.PP +.B fvwm-convert-2.6 +makes the following changes: +.TP 4 +.B Style lines +In fvwm 2.4, most style options could be negated from their counterparts +using NoFoo -- fvwm-convert-2.6 corrects this by now using !Foo. +.TP 4 +.B ModulePath +In fvwm 2.4 and beyond, the ModulePath is compiled into fvwm. +.B fvwm-convert-2.6 +removes any ModulePath commands it finds. +If you are using your own modules, (not the ones that come with fvwm), +you will have to fix your configuration file after using +.BR fvwm-convert-2.6 . +.TP 4 +.B Conditional command syntax +In fvwm 2.4, the conditional command options were whitespace-separated -- +they should now be comma-separated instead. In addition, the older syntax +to Next and Prev of using [*] to denote all windows has been removed +entirely. Both these checks and conversions are done on function commands, +key/mouse bindings. +.TP 4 +.B WindowShadeSteps +In fvwm 2.4, the WindowShadeSteps command is replaced by the +WindowShadeSteps Style option. +.B fvwm-convert-2.6 +makes this change. +.TP 4 +.B FvwmTheme +In fvwm 2.6, the FvwmTheme module is replaced by a series of Colorset +commands. Whilst +.B fvwm-convert-2.6 +will try and make this change, it is still recommended that this is checked +after conversion. +.TP 4 +.B EdgeResistance +In fvwm 2.6, the EdgeResistance command is has been split to include an +additional style option for EdgeMoveResistance. +.B fvwm-convert-2.6 +makes any changes necessary. +.TP 4 +.B StartFunction / RestartFunction / InitFunction +In fvwm 2.6, the need for using InitFunction and/or RestartFunction is +redundant when StartFunction is read at both of these times. +.B fvwm-convert-2.6 +attempts to convert this. +.TP 4 +.B Read +Any files +.B fvwm-convert-2.6 +can detect and open will be converted automatically, else a warning is +printed to STDERR. +.TP 4 +.SH BUGS + +.I InitFunction +and +.I RestartFunction +and hence +.I StartFunction +are printed at the end of the files -- this slight reordering might put some +comments before in an odd spot. + +Continuation lines (those commands spanning multiple lines ending in a '\\') +are not handled correctly. + +Bug reports can be sent to the fvwm-workers mailing list (see the +.IR FAQ ). .SH AUTHOR -fvwm-workers +Thomas Adam . diff --git a/bin/fvwm-convert-2.6.in b/bin/fvwm-convert-2.6.in index 65fe31741..f6711f780 100644 --- a/bin/fvwm-convert-2.6.in +++ b/bin/fvwm-convert-2.6.in @@ -2,7 +2,9 @@ # -*-perl-*- # Convert .fvwm2rc from 2.4.x format to 2.6.x format. - +# +# Original author: Thomas Adam Dec. 2009 +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -17,3 +19,442 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +use strict; +use Cwd; + +# Global array for all our converted lines. +my @converted_lines = (); + +# Global softref for addtofunc continuations. +my $last_func_ref; +my %converted_funcs = (); + +# Global for additional files... +my @additional_files = (); + +# Convert conditional command syntax correctly. +sub __convert_conditionals +{ + my( $cond ) = @_; + my( $line ) = $cond->[-1]; + + $line = "$1 ". join( ', ', split( /\s+/, $2 ) ) . " $3" if $line =~ + /(all|current|direction|next|none|prev|pick|thiswindow|windowid)\s*(\(.*?\))(.*)/i; + + $cond->[-1] = $line; +} + +# Process the files specified and output them to a destination file. +sub process_files +{ + my( $files ) = @_; + + no strict "refs"; + foreach my $f ( @$files ) + { + my( $s, $d ) = @$f; + + if( (!defined $d or $d eq '') or + ! -e "$s.converted" ) + { + $d = "$s.converted"; + } elsif( -e $d ) { + die "Destination file: $d exists\n"; + } + + open( my $in_file, '<', $s ) or die + "Unable to open source file: $!\n"; + + while( <$in_file> ) + { + chomp; + dispatch_line($_); + } + + write_out_file($d); + @converted_lines = (); + %converted_funcs = (); + } +} + +# Convert style syntax over where applicable. +sub convert_styles +{ + my( $line ) = @_; + my @converted; + + # At the very least, we can cheat and just negate everything. Whilst it + # isn't deprecated yet, it will be -- so it won't hurt to do it here. + + # Split the line out first of all, between the "Style foo" part, and the + # actual styles being applied. + my( @style_parts ) = ($line =~ /^(style\s+\"??[\w+*?]\"??)(.*)$/i); + + # Convert the second part over. + foreach( split( /\s*,\s*/, $style_parts[1] ) ) + { + # FIXME -- this should be flagged up as bugs in FVWM. + s/(?:No)(.*)/\!$1/ unless $_ =~ /nopposition/i; + push @converted, $_; + } + + push @converted_lines, $style_parts[0] . join(', ', + @converted); +} + +# Buckshot approach at turning fvwmthemes into colorsets. Can't really do +# much more than this, but at least gives the user something to go on. +sub convert_fvwmtheme +{ + my( $line ) = @_; + + $line =~ s/^\*fvwmtheme\s*:?//i; + $line = undef if $line =~ /modulesynchronous.*?fvwmtheme/i; + + push @converted_lines, $line; +} + +# Comment out the modulepath line -- grr. +sub handle_modulepath +{ + my( $line ) = @_; + $line = "# " . $line; + + push( @converted_lines, $line ); +} + +# This should have happened in the fvwm-2.4 convert script, but handle it +# here anyway. +sub convert_windowshadesteps +{ + my( $line ) = @_; + $line =~ /(\d+)p?/ ? + $line = "Style * WindowShadeSteps $1" : + $line = "Style * " . $line; + + push( @converted_lines, $line ); +} + +sub convert_edge_resistance +{ + my( $line ) = @_; + + # This gets converted into two parts. One is the EdgeResistance + # command, the other is a style line. + # + # We could only ever have had two numbers as arguments to + # EdgeResistance. + my( $edge_res_arg, $move_res_arg ) = + ( $line =~ /edgeresistance\s*(\d+)\s*(\d+)/i ); + + push( @converted_lines, + qq| + EdgeResistance $edge_res_arg + Style * EdgeMoveResistance $move_res_arg| ); +} + +sub convert_snapattraction +{ + my( $line ) = @_; + + push( @converted_lines, "Style * " . $line ); +} + +sub convert_key_mouse_bindings +{ + my( $line ) = @_; + my @components = split( /\s+/, $line, 5 ); + + # Take the last component. We no longer care for "[*]" as conditional + # command parameters. But we shouldn't really put another conditional + # in its place, so we'll just remove it. + $components[-1] =~ s/\[\*\]//; + + # Also, conditional commands should now be separated with commas and not + # whitespace, so try and fix these up where we can. It's not the + # intention we'll catch them all, but at least try and do so based on + # where they're likely to be used. + __convert_conditionals(\@components); + + push( @converted_lines, join ' ', @components ); +} + +sub handle_continuation +{ + no strict "refs"; # Yes, yes... + my( $line ) = @_; + + return if !defined $last_func_ref || $last_func_ref eq ''; + + eval { &{$last_func_ref}($line) }; + + warn "$@\n" if $@; +} + +sub handle_read_file +{ + my( $line ) = @_; + my @read_parts = split( /\s+/, $line ); + # Crudely try and work out if the file is readable, and if it is add it + # to the list of further files to convert. + # + # This won't handle having to interpolate out any env vars set via + # SetEnv, or worse yet, outside of FVWM's environment. The user will + # just have to run this script on that file manually. + my $fname = $read_parts[1]; + return unless defined $fname and $fname ne ''; + + if( -e $fname ) + { + push( @additional_files, [$fname] ); + + # We're done. + return; + } + + # If we have this: + # + # Read foo + # + # Or this: + # + # Read $./foo + # + # Then we assume FVWM_USERDIR ("$HOME/.fvwm/"), and if that file can't + # be found there, try CWD, and if that fails we just give up. + + # Canonicalise the starting point by removing "$." -- we can guess what + # it ought to be replaced with. + $fname =~ s/^\$\.\/?//; + + if( -e "$ENV{FVWM_USERDIR}/$fname" ) + { + push( @additional_files, + ["$ENV{FVWM_USERDIR}/$fname"] ); + return; + } + + if( -e "$ENV{HOME}/.fvwm/$fname" ) + { + push( @additional_files, + ["$ENV{HOME}/.fvwm/$fname"] ); + return; + } + + my $cwd_path = getcwd(); + + if( -e "$cwd_path/$fname" ) + { + push( @additional_files, [$fname] ); + return; + } + + warn "Unable to follow: $line\n"; +} + +sub check_func_definition +{ + my( $line ) = @_; + + if( $line !~ /^addtofunc\s+(?:start|init|restart)function.*/i ) + { + $last_func_ref = ''; + } +} + +sub convert_initfunc +{ + my( $line ) = @_; + $last_func_ref = "convert_initfunc"; + + if( $line =~ /addtofunc\s+initfunction\s+\"??[icmhd]{1}\"??\s+.*/i || + $line =~ /addtofunc\s+initfunction\s*/i ) + { + $line =~ s/addtofunc\s+initfunction\s*//i; + } + + $line =~ s/^\s*\+//; + + return if !defined $line || $line eq ''; + + # What we need to do now is convert this from: + # + # + I Foo + # + # to: + # + # + I Test (Init) Foo + + my @func_cmd = split( /\s+/, $line, 3 ); + unshift( @func_cmd, '' ) unless @func_cmd > 2; + + # Remove any quotes around the action type --- they're not needed + # anymore. + $func_cmd[1] =~ s/\"//g; + $func_cmd[1] .= q| Test (Init) |; + + # Run the command through the conditional function to ensure we + # handle those correctly. + __convert_conditionals( \@func_cmd ); + + push( @{ $converted_funcs{initfunction} }, join ' ', @func_cmd ); +} + +sub convert_restartfunc +{ + my( $line ) = @_; + $last_func_ref = "convert_restartfunc"; + + # We treat this exactly like startfunction. + if( $line =~ /addtofunc\s+restartfunction\s+\"??[icmhd]{1}\"??\s+.*/i ) + { + # Split this string. We can throw away the "AddToFunc" part as this + # is irrelevant. But we want the following result: + # ( 'I', 'Some Command' ) + $line =~ s/addtofunc\s+restartfunction\s*//i; + } + + $line =~ s/addtofunc\s+restartfunction\s*//i; + + return if $line eq ''; + + # Remove the continuation prefix as we can add this in when writing out + # the function definitions later. + $line =~ s/^\s*\+//; + + my @func_cmd = split( /\s+/, $line, 2 ); + $func_cmd[1] =~ s/\"//g; + + # Run the command through the conditional function to ensure we + # handle those correctly. + __convert_conditionals( \@func_cmd ); + + push( @{ $converted_funcs{startfunction} }, join ' ', @func_cmd ); +} + +sub convert_startfunc +{ + my( $line ) = @_; + + # Now, it's possible that we have something like this: + # + # AddToFunc StartFunction I Some Command + # + # Extract the command part, add it to the hash for our functions, and + # flag the fact we're dealing with StartFunction at this point for any + # continuation lines (+ I Foo) since we can't determine the context of + # them without such a thing. + + if( $line =~ /addtofunc\s+startfunction\s+\"??[icmhd]{1}\"??\s+.*/i ) + { + # Split this string. We can throw away the "AddToFunc" part as this + # is irrelevant. But we want the following result: + # ( 'I', 'Some Command' ) + $line =~ s/addtofunc\s+startfunction\s*//i; + } + $line =~ s/addtofunc\s+startfunction\s*//i; + + # Remove the continuation prefix as we can add this in when writing out + # the function definitions later. + $line =~ s/^\s*\+//; + + return if !defined $line || $line eq ''; + + my @func_cmd = split( /\s+/, $line, 2 ); + $func_cmd[1] =~ s/\"//g; + + # Run the command through the conditional function to ensure we + # handle those correctly. + __convert_conditionals( \@func_cmd ); + + push( @{ $converted_funcs{startfunction} }, join ' ', @func_cmd ); + $last_func_ref = "convert_startfunc"; +} + +sub write_out_file +{ + my( $dest_file ) = @_; + open( my $f, '>', $dest_file ) or + die "Couldn't open $dest_file: $!\n"; + + # Write out most of the file. + print $f join( "\n", @converted_lines ); + + # Write out the functions. + print $f qq|\n\nDestroyFunc StartFunction\nAddToFunc StartFunction\n|; + + # Put the Init stuff before anything else. + for( @{ $converted_funcs{initfunction} }, + @{ $converted_funcs{startfunction } } ) + { + print $f "+ $_\n"; + } + + close( $f ); +} + +sub dispatch_line +{ + my( $line ) = @_; + + if( $line =~ /^style/i ) + { + print "Converting style lines...\n"; + convert_styles($line); + } elsif( $line =~ /^\s*\*fvwmtheme:??/i ) { + print "Converting FvwmTheme lines...\n"; + convert_fvwmtheme($line); + } elsif( $line =~ /^\s*modulepath\s*/i ) { + print "Shooting the user for ever having changed ModulePath...\n"; + handle_modulepath( $line ); + } elsif( $line =~ /^\s*windowshadesteps.*/i ) { + convert_windowshadesteps($line); + } elsif( $line =~ /^\s*module(?:synchronous)?.*?fvwmtheme$/i ) { + convert_fvwmtheme($line); + } elsif( $line =~ /^\s*edgeresistance\s*\d+\s*\d+/i ) { + print "Converting EdgeResistance lines...\n"; + convert_edge_resistance($line); + } elsif( $line =~ /^\s*key|mouse/i ) { + print "Converting key/mouse bindings...\n"; + convert_key_mouse_bindings($line); + } elsif( $line =~ /^\s*snap(?:attraction|grid)/i ) { + print "Converting SnapAttraction...\n"; + convert_snapattraction( $line ); + } elsif( $line =~ /^\s*addtofunc\s+initfunction/i ) { + print "Converting InitFunction...\n"; + convert_initfunc( $line ); + } elsif( $line =~ /^\s*addtofunc\s+startfunction.*/i ) { + print "Converting StartFunction ...\n"; + convert_startfunc( $line ); + } elsif( $line =~ /^\s*addtofunc\s+restartfunction/i ) { + print "Converting RestartFunction...\n"; + convert_restartfunc( $line ); + } elsif( $line =~ /^\s*addtofunc\s+\w+.*/i ) { + check_func_definition( $line ); + } elsif( $line =~ /^\s*\+\s*\"??[ichmd]{1}\s*\"??\s+.*/i ) { + handle_continuation( $line ); + } elsif( $line =~ /^\s*read\s*[\/\w]+/i ) { + print "Following Read Command( $line ) ...\n"; + handle_read_file( $line ); + } else { + # Could be a comment, or a continuation, or simply something we + # don't need to convert. As far as continuation lines are + # concerned, these are kept in order just by pushing them onto the + # array --- but converting continuation lines is tricky since we'd + # need to determine the context of the continuation. I can't be + # bothered. + push( @converted_lines, $_ ); + } +} + +sub usage +{ + print "fvwm-convert-2.6 source-file destination-file\n"; + exit; +} + +usage() unless $#ARGV == 1; + +my @files = [@ARGV]; +process_files( \@files ); +process_files( \@additional_files ) if scalar @additional_files; -- 2.11.4.GIT