rwdlanguage 0.01
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Readme.txt +475 -0
- data/bin/rwdlanguage +19 -0
- data/code/01rwdcore/01rwdcore.rb +29 -0
- data/code/01rwdcore/02helptexthashbegin.rb +16 -0
- data/code/01rwdcore/03helptexthash.rb +21 -0
- data/code/01rwdcore/jumplinkcommand.rb +36 -0
- data/code/01rwdcore/openhelpwindow.rb +38 -0
- data/code/01rwdcore/returntomain.rb +10 -0
- data/code/01rwdcore/rundocuments.rb +10 -0
- data/code/01rwdcore/runeditconfiguration.rb +10 -0
- data/code/01rwdcore/runhelpabout.rb +15 -0
- data/code/01rwdcore/runopentinkerdocument.rb +7 -0
- data/code/01rwdcore/runtab.rb +15 -0
- data/code/01rwdcore/rwdtinkerversion.rb +22 -0
- data/code/01rwdcore/rwdwindowreturn.rb +9 -0
- data/code/01rwdcore/selectiontab.rb +11 -0
- data/code/01rwdcore/setuphelpaboutoptions.rb +15 -0
- data/code/01rwdcore/setuptinkerdocuments.rb +7 -0
- data/code/01rwdcore/test_cases.rb +158 -0
- data/code/01rwdcore/test_harness.rb +20 -0
- data/code/01rwdcore/uploadreturns.rb +65 -0
- data/code/dd0viewphoto/dd0viewphoto.rb +5 -0
- data/code/superant.com.language/0uninstallapplet.rb +22 -0
- data/code/superant.com.language/googlelang.rb +25 -0
- data/code/superant.com.language/helptexthashload.rb +22 -0
- data/code/superant.com.language/loadconfigurationrecord.rb +22 -0
- data/code/superant.com.language/loadconfigurationvariables.rb +14 -0
- data/code/superant.com.language/openhelpwindow.rb +24 -0
- data/code/superant.com.language/rubySteak.rb +40 -0
- data/code/superant.com.language/runappletwindow.rb +12 -0
- data/code/superant.com.language/runrwdshellwindow.rb +12 -0
- data/code/superant.com.language/runrwdwordsbackwindow.rb +10 -0
- data/code/superant.com.language/rwdtinkerversion.rb +10 -0
- data/code/superant.com.language/saveconfigurationrecord.rb +20 -0
- data/code/superant.com.language/test_cases.rb +20 -0
- data/code/superant.com.rwdtinkerbackwindow/changelocale.rb +84 -0
- data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +169 -0
- data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +38 -0
- data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +20 -0
- data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
- data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +55 -0
- data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +14 -0
- data/code/superant.com.rwdtinkerbackwindow/listzips.rb +37 -0
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +24 -0
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -0
- data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
- data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +40 -0
- data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
- data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +46 -0
- data/code/superant.com.rwdtinkerbackwindow/removeappletvariables.rb +52 -0
- data/code/superant.com.rwdtinkerbackwindow/runremoteinstall.rb +11 -0
- data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +15 -0
- data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +13 -0
- data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/showlocaleoptions.rb +9 -0
- data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +23 -0
- data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +24 -0
- data/code/superant.com.rwdtinkerbackwindow/viewlogfile.rb +16 -0
- data/code/superant.com.thesaurus/clearhttpview3.rb +9 -0
- data/code/superant.com.thesaurus/listwordlookup.rb +37 -0
- data/code/superant.com.thesaurus/runappletwindow.rb +12 -0
- data/code/superant.com.words/dictlookup.rb +20 -0
- data/code/superant.com.words/runrwdwordsbackwindow.rb +10 -0
- data/code/superant.com.words/rwdtinkerversion.rb +10 -0
- data/code/zz0applicationend/zz0end.rb +5 -0
- data/configuration/rwdtinker.dist +15 -0
- data/configuration/rwdwlanguage.dist +21 -0
- data/configuration/tinkerwin2variables.dist +23 -0
- data/gui/00coreguibegin/applicationguitop.rwd +9 -0
- data/gui/frontwindow0/cc0openphoto.rwd +22 -0
- data/gui/frontwindowselections/00selectiontabbegin.rwd +11 -0
- data/gui/frontwindowselections/jumplinkcommands.rwd +15 -0
- data/gui/frontwindowselections/wwselectionend.rwd +3 -0
- data/gui/frontwindowtdocuments/00documentbegin.rwd +6 -0
- data/gui/frontwindowtdocuments/tinkerdocuments.rwd +14 -0
- data/gui/frontwindowtdocuments/zzdocumentend.rwd +8 -0
- data/gui/helpaboutbegin/zzzrwdlasttab.rwd +6 -0
- data/gui/helpaboutbegin/zzzzhelpscreenstart.rwd +3 -0
- data/gui/helpaboutbegin/zzzzzzhelpabouttab.rwd +15 -0
- data/gui/helpaboutzend/helpscreenend.rwd +3 -0
- data/gui/helpaboutzend/zhelpscreenstart2.rwd +3 -0
- data/gui/helpaboutzend/zzzzhelpabout2.rwd +15 -0
- data/gui/helpaboutzend/zzzzhelpscreen2end.rwd +3 -0
- data/gui/tinkerbackwindows/superant.com.language/1appname.rwd +4 -0
- data/gui/tinkerbackwindows/superant.com.language/22google.rwd +38 -0
- data/gui/tinkerbackwindows/superant.com.language/44germany.rwd +19 -0
- data/gui/tinkerbackwindows/superant.com.language/67viewconfiguration.rwd +27 -0
- data/gui/tinkerbackwindows/superant.com.language/77jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.language/z9end.rwd +6 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +41 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +30 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/75rwdlogfile.rwd +20 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80localechanger.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/81jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
- data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
- data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
- data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
- data/gui/tinkerbackwindows/superant.com.versionwindow/helpaboutwindow.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.words/1appname.rwd +4 -0
- data/gui/tinkerbackwindows/superant.com.words/1dictionary.rwd +19 -0
- data/gui/tinkerbackwindows/superant.com.words/4thesaurus.rwd +36 -0
- data/gui/tinkerbackwindows/superant.com.words/77jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.words/z9end.rwd +6 -0
- data/gui/zzcoreguiend/yy9rwdend.rwd +4 -0
- data/init.rb +179 -0
- data/installed/rwdwlanguage.inf +24 -0
- data/installed/temp.rb +1 -0
- data/lang/en/rwdcore/en.po +197 -0
- data/lang/en/rwdlanguage/en.po +32 -0
- data/lang/es/rwdcore/es.po +184 -0
- data/lang/es/rwdlanguage/en.po +32 -0
- data/lang/fr/rwdcore/fr.po +169 -0
- data/lang/fr/rwdlanguage/en.po +32 -0
- data/lang/hi/rwdcore/hi.po +173 -0
- data/lang/hi/rwdlanguage/en.po +32 -0
- data/lang/ja/rwdcore/ja.po +171 -0
- data/lang/ja/rwdlanguage/en.po +32 -0
- data/lang/nl/rwdcore/nl.po +169 -0
- data/lang/nl/rwdlanguage/en.po +32 -0
- data/lib/dict.rb +438 -0
- data/lib/g_translate.rb +43 -0
- data/lib/g_translate/client.rb +84 -0
- data/lib/g_translate/translator.rb +57 -0
- data/lib/ger-eng.txt +111283 -0
- data/lib/oothesaurus.rb +76 -0
- data/lib/rconftool.rb +387 -0
- data/lib/rwd/browser.rb +123 -0
- data/lib/rwd/ftools.rb +174 -0
- data/lib/rwd/mime.rb +328 -0
- data/lib/rwd/net.rb +877 -0
- data/lib/rwd/ruby.rb +889 -0
- data/lib/rwd/rwd.rb +1425 -0
- data/lib/rwd/sgml.rb +236 -0
- data/lib/rwd/thread.rb +63 -0
- data/lib/rwd/tree.rb +371 -0
- data/lib/rwd/xml.rb +101 -0
- data/lib/rwdthemes/default.rwd +317 -0
- data/lib/rwdthemes/pda.rwd +72 -0
- data/lib/rwdthemes/windowslike.rwd +171 -0
- data/lib/rwdtinker/rwdcodedir.rb +56 -0
- data/lib/rwdtinker/rwdguidir.rb +57 -0
- data/lib/rwdtinker/rwdlangdir.rb +60 -0
- data/lib/rwdtinker/rwdtinkertools.rb +25 -0
- data/lib/zip/ioextras.rb +155 -0
- data/lib/zip/stdrubyext.rb +111 -0
- data/lib/zip/tempfile_bugfixed.rb +195 -0
- data/lib/zip/zip.rb +1847 -0
- data/lib/zip/zipfilesystem.rb +609 -0
- data/lib/zip/ziprequire.rb +90 -0
- data/rwd_files/HowTo_Language.txt +179 -0
- data/rwd_files/HowTo_Tinker.txt +515 -0
- data/rwd_files/HowTo_TinkerWin2.txt +202 -0
- data/rwd_files/Readme.txt +57 -0
- data/rwd_files/RubyWebDialogs.html +6 -0
- data/rwd_files/Tinkerhelptexthash.txt +84 -0
- data/rwd_files/favicon.ico +0 -0
- data/rwd_files/log/rwdtinker.log +726 -0
- data/rwd_files/rdoc-style.css +175 -0
- data/rwd_files/rwdapplications.html +76 -0
- data/rwd_files/rwdlanguagehelpfiles.txt +34 -0
- data/rwd_files/tinker.png +0 -0
- data/rwdconfig.dist +24 -0
- data/rwdlanguage.rb +1 -0
- data/tests/RubyGauge.rb +179 -0
- data/tests/checkdepends.sh +4 -0
- data/tests/cleancnf.sh +6 -0
- data/tests/makedist-rwdwlanguage.rb +56 -0
- data/tests/makedist.rb +66 -0
- data/tests/rdep.rb +354 -0
- data/tests/totranslate.lang +93 -0
- data/zips/rwdwcalc-0.63.zip +0 -0
- data/zips/rwdwfoldeditor-0.08.zip +0 -0
- data/zips/rwdwhypernote-0.16.zip +0 -0
- data/zips/rwdwlanguage-0.01.zip +0 -0
- data/zips/rwdwmovies-0.98.zip +0 -0
- data/zips/rwdwruby-1.08.zip +0 -0
- data/zips/temp.rb +1 -0
- data/zips/tinkerbellw-0.04.zip +0 -0
- data/zips/wrubyslippers-1.08.zip +0 -0
- metadata +246 -0
data/lib/oothesaurus.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
# The Open Office Thesaurus object. Create a new object with idx file and
|
3
|
+
# main database file name and search words with "lookup".
|
4
|
+
# Works with OO Thesaurus files 2.x
|
5
|
+
# by kesiev at http://www.kesiev.com/
|
6
|
+
|
7
|
+
class OOThesaurus
|
8
|
+
|
9
|
+
def dosearch(the,history,word,add,filepathidx,filepathdat)
|
10
|
+
a = []
|
11
|
+
if add then history.push(word) end
|
12
|
+
word=word
|
13
|
+
#$itemslist.clear
|
14
|
+
rt=the.lookup(word,filepathidx,filepathdat)
|
15
|
+
if rt.length>0
|
16
|
+
rt.each { |ent|
|
17
|
+
ent.each_with_index { |line,i|
|
18
|
+
# a=itemslist.append
|
19
|
+
a[0]=(i!=0 ? "\t" : "" )+ line
|
20
|
+
}
|
21
|
+
}
|
22
|
+
else
|
23
|
+
# a=$itemslist.append
|
24
|
+
a[0]="No hits."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def lookup(word,idxfile,datfile)
|
30
|
+
Dir.chdir($progdir)
|
31
|
+
if $DEBUG
|
32
|
+
$stderr.puts "in lookup\n"
|
33
|
+
$stderr.puts idxfile.to_s
|
34
|
+
end
|
35
|
+
seek=-1
|
36
|
+
ret=[]
|
37
|
+
if File::exist?(idxfile) && File::exist?(datfile)
|
38
|
+
|
39
|
+
open(idxfile,"r").each { |f|
|
40
|
+
f.each { |line|
|
41
|
+
line=line.split("|")
|
42
|
+
if line[0]==word
|
43
|
+
seek=line[1].to_i
|
44
|
+
break
|
45
|
+
end
|
46
|
+
}
|
47
|
+
}
|
48
|
+
ret=[]
|
49
|
+
ret2 = []
|
50
|
+
if seek!=-1
|
51
|
+
open(datfile,"r") { |a|
|
52
|
+
a.seek(seek)
|
53
|
+
data=a.gets.split("|")
|
54
|
+
data[1].to_i.times {
|
55
|
+
ret << a.gets.strip.split("|")
|
56
|
+
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
ret
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
def back(history)
|
71
|
+
if word=history.pop then
|
72
|
+
#$box.text=word
|
73
|
+
dosearch(false)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/lib/rconftool.rb
ADDED
@@ -0,0 +1,387 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# Copyright (c) 2005 Brian Candler
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to
|
7
|
+
# deal in the Software without restriction, including without limitation the
|
8
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
9
|
+
# sell copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
21
|
+
# IN THE SOFTWARE.
|
22
|
+
|
23
|
+
##########################################################################
|
24
|
+
# rconftool is a reimplementation of Sam Varshavchik's sysconftool in Ruby.
|
25
|
+
# See http://www.courier-mta.org/sysconftool/ for details of the original.
|
26
|
+
# Its purpose is to keep configuration files "fresh" when upgrading an
|
27
|
+
# application from one version to another, ensuring that all necessary
|
28
|
+
# settings are present and obsolete ones removed.
|
29
|
+
#
|
30
|
+
# rconftool can be called as a library function or from the command line. It
|
31
|
+
# can also install groups of files recursively from one directory tree into
|
32
|
+
# another.
|
33
|
+
##########################################################################
|
34
|
+
|
35
|
+
require 'fileutils'
|
36
|
+
|
37
|
+
module Rconftool
|
38
|
+
VERSION = "0.1"
|
39
|
+
class NoVersionLine < RuntimeError; end
|
40
|
+
|
41
|
+
# This module function installs a single source (.dist) file to a target
|
42
|
+
# location, having first merged in any compatible settings from the
|
43
|
+
# target file if it existed previously [if it does not exist, any settings
|
44
|
+
# from 'oldfile' are used instead]
|
45
|
+
#
|
46
|
+
# If the distfile is not in sysconftool format (i.e. doesn't have a
|
47
|
+
# ##VERSION: header within the first 20 lines), then for safety it is only
|
48
|
+
# installed if the target file does not already exist. No attempt at data
|
49
|
+
# merging is made in that case.
|
50
|
+
|
51
|
+
def self.install(distfile, targetfile=nil, oldfile=nil, opt={})
|
52
|
+
debug = opt[:debug] || $stdout
|
53
|
+
|
54
|
+
targetfile ||= distfile
|
55
|
+
if opt[:strip_regexp]
|
56
|
+
targetfile = targetfile.sub(opt[:strip_regexp], '')
|
57
|
+
oldfile = oldfile.sub(opt[:strip_regexp], '') if oldfile
|
58
|
+
end
|
59
|
+
if opt[:add_suffix]
|
60
|
+
targetfile = targetfile + opt[:add_suffix]
|
61
|
+
oldfile = oldfile + opt[:add_suffix] if oldfile
|
62
|
+
end
|
63
|
+
raise Errno::EEXIST, "#{distfile}: dist and target filenames are the same" if distfile == targetfile
|
64
|
+
|
65
|
+
# Read in the source (.dist) file
|
66
|
+
begin
|
67
|
+
src = ConfigFile.new(distfile)
|
68
|
+
rescue NoVersionLine
|
69
|
+
# Fallback behaviour when installing a file which is not in sysconftool
|
70
|
+
# format: we install the file only if it doesn't already exist
|
71
|
+
if File.exist?(targetfile)
|
72
|
+
debug << "#{targetfile}: already exists, skipping\n"
|
73
|
+
return
|
74
|
+
end
|
75
|
+
return if opt[:noclobber]
|
76
|
+
copyfrom = (oldfile and File.exist?(oldfile)) ? oldfile : distfile
|
77
|
+
if File.symlink?(copyfrom)
|
78
|
+
File.symlink(File.readlink(copyfrom), targetfile)
|
79
|
+
debug << "#{targetfile}: symlink copied from #{copyfrom}\n"
|
80
|
+
else
|
81
|
+
FileUtils.cp copyfrom, targetfile, :preserve=>true
|
82
|
+
debug << "#{targetfile}: copied from #{copyfrom}\n"
|
83
|
+
end
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
# OK, so we have a sysconftool file to install. Read in the existing
|
88
|
+
# target file, or if that does not exist, the oldfile
|
89
|
+
begin
|
90
|
+
old = ConfigFile.new
|
91
|
+
old.read(targetfile)
|
92
|
+
rescue NoVersionLine
|
93
|
+
# That's OK; the old target will be renamed to .bak
|
94
|
+
rescue Errno::ENOENT
|
95
|
+
begin
|
96
|
+
target_missing = true
|
97
|
+
old.read(oldfile) if oldfile
|
98
|
+
rescue Errno::ENOENT, NoVersionLine
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Same VERSION? No merge is required
|
103
|
+
if src.version == old.version and not opt[:force]
|
104
|
+
if target_missing
|
105
|
+
FileUtils.cp oldfile, targetfile, :preserve=>true
|
106
|
+
debug << "#{targetfile}: same VERSION, copied from #{oldfile}\n"
|
107
|
+
return
|
108
|
+
end
|
109
|
+
debug << "#{targetfile}: same VERSION, no change\n"
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
# Merge in old settings (note: any settings which are in targetfile but
|
114
|
+
# not in distfile will be silently dropped)
|
115
|
+
debug << "#{targetfile}:\n"
|
116
|
+
src.settings[1..-1].each do |src_setting|
|
117
|
+
name = src_setting.name
|
118
|
+
old_setting = old[name]
|
119
|
+
unless old_setting
|
120
|
+
debug << " #{name}: new\n"
|
121
|
+
next
|
122
|
+
end
|
123
|
+
if old_setting.version == src_setting.version
|
124
|
+
if $DEBUG
|
125
|
+
$stderr.puts "old setting: #{old_setting.version}"
|
126
|
+
$stderr.puts "src setting: #{src_setting.version}"
|
127
|
+
end
|
128
|
+
debug << " #{name}: unchanged\n"
|
129
|
+
src_setting.add_comment("\n DEFAULT SETTING from #{distfile}:\n")
|
130
|
+
src_setting.add_comment(src_setting.content)
|
131
|
+
src_setting.content = old_setting.content
|
132
|
+
next
|
133
|
+
end
|
134
|
+
# Otherwise, must install updated setting and comment out
|
135
|
+
# the current setting for reference
|
136
|
+
debug << " #{name}: UPDATED\n"
|
137
|
+
src_setting.add_comment("\n Previous setting (inserted by rconftool):\n\n")
|
138
|
+
src_setting.add_comment(old_setting.content)
|
139
|
+
end
|
140
|
+
|
141
|
+
return if opt[:noclobber]
|
142
|
+
|
143
|
+
# Write out the new file and carry forward permissions
|
144
|
+
begin
|
145
|
+
tempfile = targetfile+".new#{$$}"
|
146
|
+
src.write(tempfile)
|
147
|
+
st = File.stat(distfile)
|
148
|
+
begin
|
149
|
+
File.chown(st.uid, st.gid, tempfile)
|
150
|
+
rescue Errno::EPERM
|
151
|
+
end
|
152
|
+
File.chmod(st.mode, tempfile)
|
153
|
+
File.rename(targetfile, targetfile+".bak") unless target_missing
|
154
|
+
File.rename(tempfile, targetfile)
|
155
|
+
rescue
|
156
|
+
File.delete(tempfile) rescue nil
|
157
|
+
raise
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
HEADER_ID = '__header__'
|
162
|
+
|
163
|
+
# Object to represent a single setting
|
164
|
+
|
165
|
+
class Setting
|
166
|
+
attr_reader :name, :version
|
167
|
+
attr_accessor :content
|
168
|
+
|
169
|
+
def initialize(name, version)
|
170
|
+
@name = name.gsub(/\s+/,'')
|
171
|
+
@version = version.gsub(/s+/,'')
|
172
|
+
@comment = ""
|
173
|
+
@content = ""
|
174
|
+
@in_content = false
|
175
|
+
end
|
176
|
+
def <<(str)
|
177
|
+
@in_content = true unless /\A#/ =~ str
|
178
|
+
if @in_content
|
179
|
+
@content << str
|
180
|
+
else
|
181
|
+
@comment << str
|
182
|
+
end
|
183
|
+
end
|
184
|
+
# Add text to 'comment' portion of setting, prefixing each line with '#'
|
185
|
+
def add_comment(str)
|
186
|
+
@comment << str.gsub(/^/,'#')
|
187
|
+
end
|
188
|
+
def to_s
|
189
|
+
return "#{@comment}#{@content}" if @name == HEADER_ID
|
190
|
+
return "##NAME: #{@name}:#{@version}\n#{@comment}#{@content}"
|
191
|
+
end
|
192
|
+
end # class Setting
|
193
|
+
|
194
|
+
# Object to represent an entire configuration file. It consists of
|
195
|
+
# an array of Setting objects, with the first one having a special name
|
196
|
+
# (__header__). We also keep a hash of setting name => setting object
|
197
|
+
# to enable us to find a particular setting quickly.
|
198
|
+
|
199
|
+
class ConfigFile
|
200
|
+
attr_reader :version, :settings
|
201
|
+
|
202
|
+
def initialize(filename=nil)
|
203
|
+
read(filename) if filename
|
204
|
+
end
|
205
|
+
|
206
|
+
# fetch a setting by name
|
207
|
+
def [](item)
|
208
|
+
@settings_hash[item]
|
209
|
+
end
|
210
|
+
|
211
|
+
def read(filename)
|
212
|
+
@version = nil
|
213
|
+
curr_setting = Setting.new(HEADER_ID,'')
|
214
|
+
@settings = [curr_setting]
|
215
|
+
@settings_hash = {}
|
216
|
+
|
217
|
+
File.open(filename) do |f|
|
218
|
+
# VERSION header must occur within first 20 lines
|
219
|
+
20.times do
|
220
|
+
line = f.gets
|
221
|
+
break unless line
|
222
|
+
linetmp = line.chop + "\r\n"
|
223
|
+
curr_setting << linetmp
|
224
|
+
if line =~ /\A##VERSION:/
|
225
|
+
@version = line.chop
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
raise NoVersionLine, "#{filename}: No VERSION line found" unless @version
|
230
|
+
|
231
|
+
while line = f.gets
|
232
|
+
unless line =~ /\A##NAME:(.*):(.*)/
|
233
|
+
linetmp = line.chop + "\r\n"
|
234
|
+
curr_setting << linetmp
|
235
|
+
next
|
236
|
+
end
|
237
|
+
curr_setting = Setting.new($1,$2)
|
238
|
+
@settings << curr_setting
|
239
|
+
@settings_hash[curr_setting.name] = curr_setting
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def write(filename)
|
245
|
+
File.open(filename,"w") do |f|
|
246
|
+
@settings.each do |s|
|
247
|
+
stmp = s.to_s.chop + "\r\n"
|
248
|
+
f << stmp
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end # class ConfigFile
|
253
|
+
|
254
|
+
# Yield directory contents recursively, without doing chdir(). Note
|
255
|
+
# that yielded pathnames are relative to the base directory given;
|
256
|
+
# so that, for example, you can simulate 'cp -r /foo/bar/ /baz/' by
|
257
|
+
# recurse_dir("/foo/bar") { |n| copy("/foo/bar/"+n,"/baz/"+n) unless
|
258
|
+
# File.directory?("/foo/bar/"+n) }
|
259
|
+
# Current behaviour is that if a directory is a symlink, we follow it.
|
260
|
+
# (Perhaps the block we yield should return true/false?)
|
261
|
+
|
262
|
+
def self.recurse_dir(base)
|
263
|
+
base = base+File::SEPARATOR unless base[-1,1] == File::SEPARATOR
|
264
|
+
dirs = ['']
|
265
|
+
while dir = dirs.pop
|
266
|
+
yield dir unless dir == ''
|
267
|
+
Dir.foreach(base+dir) do |n|
|
268
|
+
next if n == '.' || n == '..'
|
269
|
+
target = dir + n
|
270
|
+
if File.directory?(base+target)
|
271
|
+
dirs << target+File::SEPARATOR
|
272
|
+
next
|
273
|
+
end
|
274
|
+
yield target
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
class Processor
|
280
|
+
attr_reader :o
|
281
|
+
|
282
|
+
# Parse command-line options and set the @o options hash
|
283
|
+
|
284
|
+
def initialize(argv=nil)
|
285
|
+
require 'optparse'
|
286
|
+
|
287
|
+
@o = { :strip_regexp => /\.dist\z/ }
|
288
|
+
return unless argv
|
289
|
+
opts = OptionParser.new do |opts|
|
290
|
+
opts.banner = "rconftool version #{VERSION}"
|
291
|
+
opts.separator "Usage: #{$0} [options]"
|
292
|
+
opts.separator ""
|
293
|
+
opts.separator "Specific options:"
|
294
|
+
|
295
|
+
opts.on("-n", "--noclobber", "Dummy run") do
|
296
|
+
@o[:noclobber] = true
|
297
|
+
end
|
298
|
+
opts.on("-f", "--force", "Update files even if VERSION is same") do
|
299
|
+
@o[:force] = true
|
300
|
+
end
|
301
|
+
opts.on("-q", "--quiet", "No progress reporting") do
|
302
|
+
@o[:debug] = ""
|
303
|
+
end
|
304
|
+
opts.on("--targetdir DIR", "Where to write merged config files") do |dir|
|
305
|
+
@o[:targetdir] = dir
|
306
|
+
end
|
307
|
+
opts.on("--olddir DIR", "If file does not exist in targetdir,",
|
308
|
+
"try to merge from here") do |dir|
|
309
|
+
@o[:olddir] = dir
|
310
|
+
end
|
311
|
+
opts.on("--[no-]recursive", "Traverse directories recursively") do |v|
|
312
|
+
@o[:recursive] = v
|
313
|
+
end
|
314
|
+
opts.on("--strip-suffix FOO", "Remove suffix FOO from target filenames",
|
315
|
+
"(default .dist)") do |suffix|
|
316
|
+
@o[:strip_regexp] = /#{Regexp.escape(suffix)}\z/
|
317
|
+
end
|
318
|
+
opts.on("-a", "--add-suffix FOO", "Add suffix FOO to target filenames") do |suffix|
|
319
|
+
@o[:add_suffix] = suffix
|
320
|
+
end
|
321
|
+
|
322
|
+
opts.on_tail("-?", "--help", "Show this message") do
|
323
|
+
puts opts
|
324
|
+
exit
|
325
|
+
end
|
326
|
+
end
|
327
|
+
opts.parse!(argv)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Process a list of files, [src1,src2,...]. If recursive mode has been
|
331
|
+
# enabled, then subdirectories of destdir are created as necessary
|
332
|
+
# when 'src' is a directory, and the mode/ownership of these newly
|
333
|
+
# created directories is copied from the original.
|
334
|
+
|
335
|
+
def run(files)
|
336
|
+
done_work = false
|
337
|
+
files.each do |f|
|
338
|
+
if not File.directory?(f)
|
339
|
+
dst = old = nil
|
340
|
+
dst = @o[:targetdir] + File::SEPARATOR + File.basename(f) if @o[:targetdir]
|
341
|
+
old = @o[:olddir] + File::SEPARATOR + File.basename(f) if @o[:olddir]
|
342
|
+
Rconftool::install(f, dst, old, @o)
|
343
|
+
elsif not @o[:recursive]
|
344
|
+
raise Errno::EISDIR, "#{f} (not copied). Need --recursive?"
|
345
|
+
else
|
346
|
+
Rconftool::recurse_dir(f) do |nf|
|
347
|
+
src = f + File::SEPARATOR + nf
|
348
|
+
dst = old = nil
|
349
|
+
dst = @o[:targetdir] + File::SEPARATOR + nf if @o[:targetdir]
|
350
|
+
old = @o[:olddir] + File::SEPARATOR + nf if @o[:olddir]
|
351
|
+
if File.directory?(src)
|
352
|
+
if dst and not File.directory?(dst)
|
353
|
+
orig = File.stat(src)
|
354
|
+
Dir.mkdir(dst, orig.mode)
|
355
|
+
begin
|
356
|
+
File.chown(orig.uid, orig.gid, dst)
|
357
|
+
rescue Errno::EPERM
|
358
|
+
end
|
359
|
+
end
|
360
|
+
else
|
361
|
+
Rconftool::install(src, dst, old, @o)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
done_work = true
|
366
|
+
end
|
367
|
+
unless done_work
|
368
|
+
$stderr.puts "Usage: #{$0} [options] src1 src2 ...\n"+
|
369
|
+
"Try #{$0} --help for more information\n"
|
370
|
+
exit 1
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end # class Processor
|
374
|
+
|
375
|
+
end # module Rconftool
|
376
|
+
|
377
|
+
# Run from command line?
|
378
|
+
if __FILE__ == $0
|
379
|
+
|
380
|
+
begin
|
381
|
+
s = Rconftool::Processor.new(ARGV)
|
382
|
+
s.run(ARGV)
|
383
|
+
rescue Exception => e
|
384
|
+
$stderr.puts "#{$0}: #{e}"
|
385
|
+
end
|
386
|
+
|
387
|
+
end
|