phpdocr 0.1.1
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/COPYING +676 -0
- data/NEWS +8 -0
- data/README +11 -0
- data/phpdocr +546 -0
- data/phpdocr.1 +102 -0
- metadata +66 -0
data/NEWS
ADDED
data/README
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
phpdocr is a simple way to access PHP documentation from php.net from the
|
2
|
+
command-line.
|
3
|
+
|
4
|
+
It will download, prettify, and output PHP documentation for the
|
5
|
+
function/class/.. that was supplied on the command-line, much like perldoc(1)
|
6
|
+
does for perl(1) and ri does for ruby(1). Unless you explicitly tell it not to,
|
7
|
+
phpdocr will also cache the documentation locally for fast retrieval in the
|
8
|
+
future.
|
9
|
+
|
10
|
+
phpdocr will send its output to your PAGER (if it is set, otherwise it will
|
11
|
+
default to less).
|
data/phpdocr
ADDED
@@ -0,0 +1,546 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# phpdocr
|
3
|
+
# Copyright (C) Eskild Hustvedt 2009
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# Fetch from rubygems if available
|
19
|
+
begin
|
20
|
+
require 'rubygems'
|
21
|
+
rescue LoadError
|
22
|
+
puts '(rubygems appears to be missing, will attempt to continue anyway)'
|
23
|
+
end
|
24
|
+
# Command-line parsing
|
25
|
+
require 'getoptlong'
|
26
|
+
# To run the prettifier
|
27
|
+
require 'open3'
|
28
|
+
# To create a temporary file with HTML
|
29
|
+
require 'tempfile'
|
30
|
+
# CGI is used for escaping
|
31
|
+
require 'cgi'
|
32
|
+
# www-mechanize is used for fetching from HTTP
|
33
|
+
begin
|
34
|
+
require 'mechanize'
|
35
|
+
rescue LoadError
|
36
|
+
puts
|
37
|
+
puts 'You appear to be missing the "mechanize" rubygem.'
|
38
|
+
puts 'phpdocr needs this to be able to fetch data from php.net'
|
39
|
+
puts 'Please install the mechanize rubygem using your OS package manager'
|
40
|
+
puts 'or using the "gem" utility.'
|
41
|
+
puts
|
42
|
+
puts 'Package examples:'
|
43
|
+
puts 'Fedora: yum install rubygem-mechanize'
|
44
|
+
puts 'Debian/Ubuntu: aptitude install libwww-mechanize-ruby'
|
45
|
+
puts 'Generic/all: gem install mechanize'
|
46
|
+
exit(1)
|
47
|
+
end
|
48
|
+
# For creating the cache dir if needed
|
49
|
+
require 'fileutils'
|
50
|
+
# Application version
|
51
|
+
$version = '0.1.1'
|
52
|
+
# Bool, true if we should include the user notes section
|
53
|
+
$includeUserNotes = false
|
54
|
+
# Verbose mode (true/false)
|
55
|
+
$verbose = false
|
56
|
+
# Cache enabled?
|
57
|
+
$cache = true
|
58
|
+
# php.net mirror
|
59
|
+
$mirror = 'php.net'
|
60
|
+
|
61
|
+
# Purpose: Print formatted --help output
|
62
|
+
# Usage: printHelp('-shortoption', '--longoption', 'description');
|
63
|
+
# Description will be reformatted to fit within a normal terminal
|
64
|
+
def printHelp (short,long,description)
|
65
|
+
maxlen = 80
|
66
|
+
optionlen = 20
|
67
|
+
# Check if the short/long are LONGER than optionlen, if so, we need
|
68
|
+
# to do some additional magic to take up only $maxlen.
|
69
|
+
# The +1 here is because we always add a space between them, no matter what
|
70
|
+
if (short.length + long.length + 1) > optionlen
|
71
|
+
optionlen = short.length + long.length + 1;
|
72
|
+
end
|
73
|
+
|
74
|
+
generatedDesc = ''
|
75
|
+
currdesc = ''
|
76
|
+
|
77
|
+
description.split(/ /).each do |part|
|
78
|
+
if(generatedDesc.length > 0)
|
79
|
+
if (currdesc.length + part.length + 1 + 20) > maxlen
|
80
|
+
generatedDesc.concat("\n")
|
81
|
+
currdesc = ''
|
82
|
+
else
|
83
|
+
currdesc.concat(' ')
|
84
|
+
generatedDesc.concat(' ')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
currdesc.concat(part)
|
88
|
+
generatedDesc.concat(part)
|
89
|
+
end
|
90
|
+
if !(generatedDesc.length > 0)
|
91
|
+
raise("Option mismatch")
|
92
|
+
end
|
93
|
+
generatedDesc.split(/\n/).each do |descr|
|
94
|
+
printf("%-4s %-15s %s\n",short,long,descr)
|
95
|
+
short = ''; long = ''
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Purpose: Print the help output
|
100
|
+
def Help ()
|
101
|
+
puts "phpdocr "+$version.to_s
|
102
|
+
puts ""
|
103
|
+
puts "Usage: phpdocr [OPTIONS] [FUNCTION/CLASS/SEARCH STRING/..]"
|
104
|
+
puts ""
|
105
|
+
printHelp('-h','--help','Display this help text')
|
106
|
+
printHelp('-u','--comments','Include the user comments part of the documentation in output')
|
107
|
+
printHelp('-n','--no-cache','Disable the local doc cache (~/.phpdocr/)')
|
108
|
+
printHelp('-v','--verbose','Enable verbose mode')
|
109
|
+
printHelp('-m','--mirror','Use the supplied mirror of php.net')
|
110
|
+
printHelp('','--version','Output the phpdocr version and exit')
|
111
|
+
printHelp('','--man','Show the phpdocr manpage')
|
112
|
+
end
|
113
|
+
|
114
|
+
# Purpose: Output a string if in verbose mode
|
115
|
+
def vputs (str)
|
116
|
+
if $verbose
|
117
|
+
puts(str)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Purpose: Show the manpage
|
122
|
+
def showManPage ()
|
123
|
+
if ! inPath('man')
|
124
|
+
puts
|
125
|
+
puts "You don't appear to have the 'man' program installed."
|
126
|
+
puts "Please install it, then re-run phpdocr --man"
|
127
|
+
exit(0)
|
128
|
+
end
|
129
|
+
mySelf = File.expand_path($0)
|
130
|
+
while File.symlink?(mySelf)
|
131
|
+
mySelf = File.readlink(mySelf)
|
132
|
+
end
|
133
|
+
sourceDir = '.'
|
134
|
+
if mySelf != nil
|
135
|
+
sourceDir = File.dirname(mySelf)
|
136
|
+
end
|
137
|
+
dirs = [sourceDir]
|
138
|
+
if ENV['MANPATH']
|
139
|
+
dirs.concat(ENV['MANPATH'].split(':'))
|
140
|
+
end
|
141
|
+
dirs.push('./')
|
142
|
+
dirs.each do |dir|
|
143
|
+
[ 'phpdocr.1','man1/phpdocr.1','man1/phpdocr.1.gz','man1/phpdocr.1.bz2','man1/phpdocr.1.lzma'].each do |manFile|
|
144
|
+
if File.exists?(dir+'/'+manFile)
|
145
|
+
exec('man',dir+'/'+manFile)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
puts
|
150
|
+
puts 'phpdocr failed to locate its manpage.'
|
151
|
+
puts 'Run the following command to view it:'
|
152
|
+
puts '\curl -s "http://github.com/zerodogg/phpdocr/raw/master/phpdocr.1" | groff -T utf8 -man | \less'
|
153
|
+
end
|
154
|
+
|
155
|
+
# Purpose: Print debugging info
|
156
|
+
def debugInfo ()
|
157
|
+
puts "phpdocr "+$version.to_s
|
158
|
+
begin
|
159
|
+
if inPath('md5sum')
|
160
|
+
outStr = nil
|
161
|
+
out = IO.popen('md5sum '+File.expand_path($0))
|
162
|
+
outStr = out.readline
|
163
|
+
outStr.sub!(/\s+.*$/,'')
|
164
|
+
puts('md5sum: '+outStr)
|
165
|
+
end
|
166
|
+
rescue
|
167
|
+
puts('(exception while generating md5sum: '+$!+')')
|
168
|
+
end
|
169
|
+
prettifierCmd = prettifier('path',false)
|
170
|
+
if prettifierCmd == nil
|
171
|
+
prettifierCmd = '(missing)'
|
172
|
+
else
|
173
|
+
prettifierCmd = String.new(prettifierCmd.join(' '))
|
174
|
+
end
|
175
|
+
puts 'Prettifier: '+prettifierCmd
|
176
|
+
exit(0)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Fetch a URL and return its contents
|
180
|
+
def getURL (url)
|
181
|
+
begin
|
182
|
+
www = WWW::Mechanize.new
|
183
|
+
vputs('Downloading '+url)
|
184
|
+
return www.get(url).body
|
185
|
+
rescue
|
186
|
+
return ''
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Purpose: Check for a file in path
|
191
|
+
def inPath(exec)
|
192
|
+
ENV['PATH'].split(/:/).each do |part|
|
193
|
+
if File.executable?(part+'/'+exec) and not File.directory?(part+'/'+exec)
|
194
|
+
return true
|
195
|
+
end
|
196
|
+
end
|
197
|
+
return false
|
198
|
+
end
|
199
|
+
|
200
|
+
# Purpose: Detect and run a prettifier
|
201
|
+
def prettifier (path, missingIsFatal = true)
|
202
|
+
# Links family, they use basically the same syntax, but we append
|
203
|
+
# -no-references for elinks.
|
204
|
+
if inPath('elinks')
|
205
|
+
return [ 'elinks','-force-html','-no-references','-dump',path ]
|
206
|
+
end
|
207
|
+
['links2', 'links' ].each do |links|
|
208
|
+
if inPath(links)
|
209
|
+
return [ links,'-force-html','-dump',path ]
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# w3m
|
214
|
+
if inPath('w3m')
|
215
|
+
return ['w3m','-dump','-T','text/html',path]
|
216
|
+
end
|
217
|
+
|
218
|
+
# html2text
|
219
|
+
if inPath('html2text')
|
220
|
+
return ['html2text','-style','pretty',path ]
|
221
|
+
end
|
222
|
+
|
223
|
+
# Finally, try lynx
|
224
|
+
if inPath('lynx')
|
225
|
+
return ['lynx','-dump','-force_html',path ]
|
226
|
+
end
|
227
|
+
|
228
|
+
if missingIsFatal
|
229
|
+
# If we found none, then give up
|
230
|
+
puts
|
231
|
+
puts "Failed to locate any HTML parser. Please install one of the following,"
|
232
|
+
puts "and then re-run phpdocr: elinks, links2, links, w3m, html2text, lynx"
|
233
|
+
exit(1)
|
234
|
+
else
|
235
|
+
return nil
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Purpose: Convert links
|
240
|
+
def convertLinks (list)
|
241
|
+
result = ''
|
242
|
+
|
243
|
+
rmlastA = false
|
244
|
+
first = true
|
245
|
+
|
246
|
+
list.split(/</).each do |line|
|
247
|
+
if line =~ /^a[^>]+href="\w/
|
248
|
+
currlink = String.new(line)
|
249
|
+
# Remove the href
|
250
|
+
currlink.sub!(/^a[^>]+href="/,'')
|
251
|
+
# Remove whatever is after the href
|
252
|
+
currlink.sub!(/".*$/,'')
|
253
|
+
# Remove '#' links
|
254
|
+
currlink.sub!(/#.*$/,'')
|
255
|
+
# Parse away .php and function declarations
|
256
|
+
currlink.sub!(/\.php$/,'')
|
257
|
+
currlink.sub!(/^function\./,'')
|
258
|
+
# Remove other HTML
|
259
|
+
line.sub!(/^[^>]+>/,'')
|
260
|
+
# Add new content
|
261
|
+
line = String.new('['+currlink+'] '+line)
|
262
|
+
rmlastA = true
|
263
|
+
# Remove the a> if rmlastA is true
|
264
|
+
elsif line =~ /\/a>/ and rmlastA
|
265
|
+
line.sub!(/^\/a>/,'')
|
266
|
+
rmlastA = false
|
267
|
+
elsif first
|
268
|
+
first = false
|
269
|
+
else
|
270
|
+
line = '<'+line
|
271
|
+
end
|
272
|
+
result.concat(line)
|
273
|
+
end
|
274
|
+
return result
|
275
|
+
end
|
276
|
+
|
277
|
+
# Purpose: Attempt to fetch suggestions
|
278
|
+
def fetchSuggestions (data)
|
279
|
+
final = []
|
280
|
+
hadStart = false
|
281
|
+
no = 0
|
282
|
+
data.split(/\n/).each do |line|
|
283
|
+
if line =~ /result list start/
|
284
|
+
hadStart = true
|
285
|
+
elsif hadStart == false
|
286
|
+
next
|
287
|
+
elsif line =~ /result list end/
|
288
|
+
break
|
289
|
+
else
|
290
|
+
no += 1
|
291
|
+
# Kill all HTML
|
292
|
+
line.gsub!(/<[^>]+>/,'')
|
293
|
+
if line =~ /\S/
|
294
|
+
final.push(line)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
if hadStart && final != nil
|
299
|
+
return final
|
300
|
+
else
|
301
|
+
return nil
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Purpose: Display the contents of the supplied string inside the users PAGER
|
306
|
+
def pager(contents)
|
307
|
+
# Detect the pager
|
308
|
+
pager = ENV['PAGER']
|
309
|
+
if pager == '' || pager == nil
|
310
|
+
pager = 'less'
|
311
|
+
end
|
312
|
+
|
313
|
+
# Write data to the pager
|
314
|
+
input = IO.popen(pager,'w')
|
315
|
+
begin
|
316
|
+
input.puts(contents)
|
317
|
+
input.close
|
318
|
+
rescue
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# Purpose: Look up something on the website
|
323
|
+
def lookupWeb (name, fetchPattern = true, prevSearch = nil)
|
324
|
+
# fetchPattern means we should run a serach
|
325
|
+
stringC = String.new(name)
|
326
|
+
if fetchPattern == true
|
327
|
+
stringC = CGI.escape(name)
|
328
|
+
url = 'http://'+$mirror+'/manual-lookup.php?pattern='+name
|
329
|
+
else
|
330
|
+
# Otherwise, attempt a direct page
|
331
|
+
if ! stringC =~ /\.php$/
|
332
|
+
stringC.concat('.php')
|
333
|
+
end
|
334
|
+
url = 'http://'+$mirror+'/manual/en/'+stringC+'.php'
|
335
|
+
end
|
336
|
+
# Retrieve data
|
337
|
+
data = getURL(url)
|
338
|
+
# True if this is within the normally returned page
|
339
|
+
hadFirst = false
|
340
|
+
# True if we have had the UDM statement
|
341
|
+
hadUDM = false
|
342
|
+
# The result on normal pages
|
343
|
+
result = ''
|
344
|
+
# The result on index-like pages
|
345
|
+
indexResult = ''
|
346
|
+
# Parse it
|
347
|
+
data.split(/\n/).each do |line|
|
348
|
+
if hadFirst
|
349
|
+
if ! $includeUserNotes && line =~ /(User Contributed Notes|<div id="usernotes">)/
|
350
|
+
break
|
351
|
+
end
|
352
|
+
result.concat(line)
|
353
|
+
elsif line =~ /class="refentry"/ || line =~ /<h3\s*class="title">Description/ || line =~ /<div\s*class="refnamediv">/
|
354
|
+
hadFirst = true
|
355
|
+
end
|
356
|
+
if hadUDM
|
357
|
+
if line =~ /<h1 class="title">/
|
358
|
+
indexResult = String.new(line)
|
359
|
+
else
|
360
|
+
indexResult.concat(line)
|
361
|
+
end
|
362
|
+
elsif line =~ /UdmComment/
|
363
|
+
hadUDM = true
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
# If we got no useful data, try again if possible, else output failure
|
368
|
+
if ! hadFirst && ! hadUDM
|
369
|
+
# If this was a fetchPattern run, try a direct one
|
370
|
+
if fetchPattern
|
371
|
+
return lookupWeb(name,false,data)
|
372
|
+
else
|
373
|
+
# This was a direct one, output errors
|
374
|
+
puts
|
375
|
+
puts 'Could not find '+name+' in PHP documentation'
|
376
|
+
# If we have a previous search value, attempt to fetch suggestions from it
|
377
|
+
if prevSearch != nil
|
378
|
+
suggest = fetchSuggestions(prevSearch)
|
379
|
+
# If we have suggestions, output them.
|
380
|
+
if suggest != nil
|
381
|
+
puts "\n"
|
382
|
+
puts "Perhaps you were looking for one of these?"
|
383
|
+
while suggest.length > 0
|
384
|
+
printf("%-20s %-20s %-20s %-20s\n",suggest[0],suggest[1],suggest[2],suggest[3])
|
385
|
+
4.times { suggest.shift }
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
return
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
# If we 'hadFirst', then result contains what we want, otherwise use
|
394
|
+
# indexResult
|
395
|
+
if hadFirst
|
396
|
+
result = convertLinks(result)
|
397
|
+
else
|
398
|
+
result = convertLinks(indexResult)
|
399
|
+
end
|
400
|
+
|
401
|
+
# Write the data to a temporary file so the prettifier can
|
402
|
+
# read it there (not all of them support reading from STDIN)
|
403
|
+
tmp = Tempfile.new('phpdocr')
|
404
|
+
tmp.puts('<html><body>'+result+'</body></html>')
|
405
|
+
tmp.flush
|
406
|
+
cmd = prettifier(tmp.path)
|
407
|
+
# Get the output
|
408
|
+
Open3.popen3(*cmd) { |stdin, stdout, stderr|
|
409
|
+
result = stdout.gets(nil)
|
410
|
+
}
|
411
|
+
|
412
|
+
# Close and remove the temporary file
|
413
|
+
tmp.close(true)
|
414
|
+
|
415
|
+
# Append the url we used to the result
|
416
|
+
result.concat("\nRetrieved from "+url)
|
417
|
+
|
418
|
+
return result
|
419
|
+
end
|
420
|
+
|
421
|
+
# Purpose: Prepare the cache dir
|
422
|
+
def prepCacheDir (name)
|
423
|
+
cacheDir = ENV['HOME']+'/.phpdocr/'
|
424
|
+
if ! File.directory?(cacheDir)
|
425
|
+
if File.exists?(cacheDir)
|
426
|
+
puts cacheDir+': exists but is not a directory, caching disabled.'
|
427
|
+
$cache = false
|
428
|
+
return nil
|
429
|
+
end
|
430
|
+
FileUtils.mkpath(cacheDir)
|
431
|
+
end
|
432
|
+
name.gsub!(/\//,'')
|
433
|
+
filePrefix = 'cache.'
|
434
|
+
if $includeUserNotes
|
435
|
+
filePrefix = 'cache.withNotes.'
|
436
|
+
end
|
437
|
+
return cacheDir+filePrefix+name
|
438
|
+
end
|
439
|
+
|
440
|
+
# Purpose: Look something up in the cache
|
441
|
+
def lookupCache (name)
|
442
|
+
cacheFile = prepCacheDir(name)
|
443
|
+
if cacheFile == nil
|
444
|
+
return
|
445
|
+
end
|
446
|
+
|
447
|
+
if File.exists?(cacheFile)
|
448
|
+
file = File.open(cacheFile)
|
449
|
+
vputs('Loaded information for '+name+' from the cache')
|
450
|
+
return file.gets(nil)
|
451
|
+
end
|
452
|
+
|
453
|
+
return nil
|
454
|
+
end
|
455
|
+
|
456
|
+
# Purpose: Write something to the cache
|
457
|
+
def writeToCache (name,data)
|
458
|
+
cacheFile = prepCacheDir(name)
|
459
|
+
if cacheFile == nil
|
460
|
+
return
|
461
|
+
end
|
462
|
+
file = File.open(cacheFile,'w')
|
463
|
+
file.puts(data)
|
464
|
+
file.close
|
465
|
+
end
|
466
|
+
|
467
|
+
# Purpose: Look something up
|
468
|
+
def lookup(name)
|
469
|
+
result = nil
|
470
|
+
sourceWasWeb = false
|
471
|
+
if $cache
|
472
|
+
result = lookupCache(name)
|
473
|
+
end
|
474
|
+
if !$cache || result == nil
|
475
|
+
sourceWasWeb = true
|
476
|
+
result = lookupWeb(name)
|
477
|
+
end
|
478
|
+
if result != nil
|
479
|
+
if $cache && sourceWasWeb
|
480
|
+
writeToCache(name,result)
|
481
|
+
end
|
482
|
+
pager(result)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
opts = GetoptLong.new(
|
487
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
488
|
+
[ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
|
489
|
+
[ '--comments','-u', GetoptLong::NO_ARGUMENT ],
|
490
|
+
[ '--no-cache','--nocache','-n', GetoptLong::NO_ARGUMENT ],
|
491
|
+
[ '--debuginfo', GetoptLong::NO_ARGUMENT ],
|
492
|
+
[ '--version', GetoptLong::NO_ARGUMENT ],
|
493
|
+
[ '--mirror', '-m', GetoptLong::REQUIRED_ARGUMENT ],
|
494
|
+
[ '--man', GetoptLong::NO_ARGUMENT ]
|
495
|
+
)
|
496
|
+
|
497
|
+
# Handle command-line arguments
|
498
|
+
begin
|
499
|
+
opts.each do |opt, arg|
|
500
|
+
case opt
|
501
|
+
when '--help'
|
502
|
+
Help()
|
503
|
+
exit(0)
|
504
|
+
when '--verbose'
|
505
|
+
$verbose = true
|
506
|
+
when '--comments'
|
507
|
+
$includeUserNotes = true
|
508
|
+
when '--no-cache'
|
509
|
+
$cache = false
|
510
|
+
when '--debuginfo'
|
511
|
+
debugInfo()
|
512
|
+
when '--version'
|
513
|
+
puts('phpdocr version '+$version.to_s)
|
514
|
+
exit(0)
|
515
|
+
when '--mirror'
|
516
|
+
$mirror = arg
|
517
|
+
when '--man'
|
518
|
+
showManPage()
|
519
|
+
exit(0)
|
520
|
+
end
|
521
|
+
end
|
522
|
+
rescue
|
523
|
+
puts('See --help for more inforation')
|
524
|
+
exit(1)
|
525
|
+
end
|
526
|
+
|
527
|
+
if ARGV.length == 0 || ARGV.length > 1
|
528
|
+
Help()
|
529
|
+
exit(1)
|
530
|
+
end
|
531
|
+
|
532
|
+
begin
|
533
|
+
lookup(ARGV.shift)
|
534
|
+
rescue => ex
|
535
|
+
puts('---')
|
536
|
+
puts('Exception: '+ex.to_s)
|
537
|
+
puts('Backtrace: '+"\n"+ex.backtrace.join("\n"))
|
538
|
+
puts('---')
|
539
|
+
puts()
|
540
|
+
puts('An exception has occurred and phpdocr can not continue.')
|
541
|
+
puts('This almost certainly reflects a bug in phpdocr.')
|
542
|
+
puts('Please check that you have the latest version off phpdocr,')
|
543
|
+
puts('and if you do, report this issue along with the text between the "---" above');
|
544
|
+
puts('to http://random.zerodogg.org/phpdocr/bugs')
|
545
|
+
exit(1)
|
546
|
+
end
|