]>
git.ipfire.org Git - thirdparty/squid.git/blob - scripts/www/build-cfg-help.pl
3 # * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
5 # * Squid software is distributed under GPLv2+ license and includes
6 # * contributions from numerous individuals and organizations.
7 # * Please see the COPYING and CONTRIBUTORS files for details.
15 # This mess is designed to parse the squid config template file
16 # cf.data.pre and generate a set of HTML pages to use as documentation.
18 # Adrian Chadd <adrian@squid-cache.org>
21 # The template file is reasonably simple to parse. There's a number of
22 # directives which delineate sections but there's no section delineation.
23 # A section will "look" somewhat like this, most of the time:
25 # IFDEF: <the ifdef bit>
26 # TYPE: <the config type>
27 # LOC: <location in the Config struct>
28 # DEFAULT: <the default value(s) - may be multiple lines>
29 # DEFAULT_IF_NONE: <alternative default value>
30 # DEFAULT_DOC: <the text to display instead of default value(s)>
32 # documentation goes here
34 # stuff which goes verbatim into the config file goes here
38 # Now, we can't assume its going to be nicely nested, so I'll say that
39 # sections are delineated by NAME: lines, and then stuff is marked up
42 # Then we have to fake paragraph markups as well for the documentation.
43 # We can at least use <PRE> type markups for the NOCOMMENT_START/_END stuff.
46 # Configuration sections are actually broken up by COMMENT_START/COMMENT_END
47 # bits, which we can use in the top-level index page. Nifty!
50 # XXX NAME: can actually have multiple entries on it; we should generate
51 # XXX a configuration index entry for each, linking back to the one entry.
52 # XXX I'll probably just choose the first entry in the list.
55 # This code is ugly, but meh. We'll keep reading, line by line, and appending
56 # lines into 'state' variables until the next NAME comes up. We'll then
57 # shuffle everything off to a function to generate the page.
66 my $version = "3.1.0";
69 my $format = "splithtml";
72 my ($index) = new IO
::File
;
74 my $top = dirname
($0);
77 'verbose' => \
$verbose, 'v' => \
$verbose,
79 'version=s' => \
$version,
80 'format=s' => \
$format
83 if ($format eq "splithtml") {
84 $pagetemplate = "template.html";
85 } elsif ($format eq "singlehtml") {
86 $pagetemplate = "template_single.html";
90 my ($df) = new IO
::File
;
92 $df->open("$top/../../src/cf_gen_defines", "r") || die;
94 $defines{$1} = $2 if /define\["([^"]*)"\]="([^"]*)"/;
99 # XXX should implement this!
109 return $path . "/" . $name . ".html";
115 return "" if !defined $line;
116 $line =~ s/&/\&/g;
117 $line =~ s/</\</g;
118 $line =~ s/>/\>/g;
119 $line =~ s/[^\x{20}-\x{7e}\s]/sprintf ("&#%d;", ord ($1))/ge;
125 return uriescape
($_[0]).".html" if $format eq "splithtml";
126 return "#".$_[0] if $format eq "singlehtml";
131 return "index.html#toc_".uriescape
($_[0]) if $format eq "splithtml";
132 return "#toc_".uriescape
($_[0]) if $format eq "singlehtml";
137 return "index_all.html#toc_".uriescape
($_[0]);
141 # Yes, we could just read the template file in once..!
143 sub generate_page
($$)
145 my ($template, $data) = @_;
148 # XXX should make sure the config option is a valid unix filename!
149 if ($format eq "splithtml") {
150 my ($fn) = filename
($data->{'name'});
152 $fh->open($fn, "w") || die "Couldn't open $fn: $!\n";
158 $data->{"ifdef"} = $defines{$data->{"ifdef"}} if (exists $data->{"ifdef"} && exists $defines{$data->{"ifdef"}});
160 my ($th) = new IO
::File
;
161 $th->open($template, "r") || die "Couldn't open $template: $!\n";
163 # add in the local variables
164 $data->{"title"} = $data->{"name"};
165 $data->{"ldoc"} = $data->{"doc"};
166 $data->{"toc_link"} = toc_link
($data->{"name"});
167 $data->{"alpha_link"} = alpha_link
($data->{"name"});
168 if (exists $data->{"aliases"}) {
169 $data->{"aliaslist"} = join(", ", @
{$data->{"aliases"}});
171 # XXX can't do this and then HTML escape..
172 # $data->{"ldoc"} =~ s/\n\n/<\/p>\n<p>\n/;
173 # XXX and the end-of-line formatting to turn single \n's into <BR>\n's.
176 # Do variable substitution
177 s/%(.*?)%/htmlescape($data->{$1})/ge;
189 $index->open(filename
("index"), "w") || die "Couldn't open ".filename
("index").": $!\n" if ($format eq "splithtml");
190 $index->open($path, "w") || die "Couldn't open ".filename
("index").": $!\n" if ($format eq "singlehtml");
192 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
193 <html xmlns="http://www.w3.org/1999/xhtml">
195 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
196 <title>Squid $version configuration file</title>
197 <meta name="keywords" content="squid squid.conf config configure" />
198 <meta name="description" content="Squid $version" />
199 <link rel="stylesheet" type="text/css" href="http://www.squid-cache.org/default.css" />
200 <link rel="stylesheet" type="text/css" href="http://www.squid-cache.org/cfgman.css" />
213 my ($name, $type) = @_;
215 print $index "<ul>\n";
218 return if $type eq "obsolete";
219 print $index ' <li><a href="' . htmlescape
(section_link
($name)) . '" name="toc_' . htmlescape
($name) . '">' . htmlescape
($name) . "</a></li>\n";
223 return if !$in_options;
224 print $index "</ul>\n";
227 sub section_heading
($)
230 print $index "<pre>\n";
231 print $index $comment;
232 print $index "</pre>\n";
234 sub update_defaults
()
236 if (defined($data->{"default_doc"})) {
237 # default text description masks out the default value display
238 if($data->{"default_doc"} ne "") {
239 print "REPLACE: default '". $data->{"default"} ."' with '" . $data->{"default_doc"} . "'\n" if $verbose;
240 $data->{"default"} = $data->{"default_doc"};
243 # when we have no predefined default use the DEFAULT_IF_NONE
244 if (defined($data->{"default_if_none"})) {
245 print "REPLACE: default '". $data->{"default"} ."' with '" . $data->{"default_if_none"} . "'\n" if $verbose && $data->{"default"} eq "";
246 $data->{"default"} = $data->{"default_if_none"} if $data->{"default"} eq "";
253 if ($_ =~ /^NAME: (.*)$/) {
254 my (@aliases) = split(/ /, $1);
256 $data->{'version'} = $version;
258 $all_names{$_} = $data;
261 $name = shift @aliases;
263 $option{$name} = $data;
264 $data->{'name'} = $name;
265 $data->{'aliases'} = \
@aliases;
266 $data->{'default'} = "";
267 $data->{'default_doc'} = "";
268 $data->{'default_if_none'} = "";
270 print "DEBUG: new option: $name\n" if $verbose;
272 } elsif ($_ =~ /^COMMENT: (.*)$/) {
273 $data->{"comment"} = $1;
274 } elsif ($_ =~ /^TYPE: (.*)$/) {
275 $data->{"type"} = $1;
276 start_option
($data->{"name"}, $data->{"type"});
277 } elsif ($_ =~ /^DEFAULT: (.*)$/) {
279 $data->{"default"} = "$1\n";
281 $data->{"default"} .= "$name $1\n";
283 } elsif ($_ =~ /^DEFAULT_DOC: (.*)$/) {
284 $data->{"default_doc"} .= "$1\n";
285 } elsif ($_ =~ /^DEFAULT_IF_NONE: (.*)$/) {
286 $data->{"default_if_none"} .= "$1\n";
287 } elsif ($_ =~ /^LOC:(.*)$/) {
289 $data->{"loc"} =~ s/^[\s\t]*//;
290 } elsif ($_ =~ /^DOC_START$/) {
293 } elsif ($_ =~ /^DOC_END$/) {
296 foreach $othername (@chained) {
297 $option{$othername}{'doc'} = $data->{'doc'};
300 } elsif ($_ =~ /^DOC_NONE$/) {
302 push(@chained, $name);
303 } elsif ($_ =~ /^NOCOMMENT_START$/) {
304 $state = "nocomment";
305 } elsif ($_ =~ /^NOCOMMENT_END$/) {
307 } elsif ($_ =~ /^IFDEF: (.*)$/) {
308 $data->{"ifdef"} = $1;
309 } elsif ($_ =~ /^#/ && $state eq "doc") {
310 $data->{"config"} .= $_ . "\n";
311 } elsif ($state eq "nocomment") {
312 $data->{"config"} .= $_ . "\n";
313 } elsif ($state eq "doc") {
314 $data->{"doc"} .= $_ . "\n";
315 } elsif ($_ =~ /^COMMENT_START$/) {
319 } elsif ($_ =~ /^COMMENT_END$/) {
320 section_heading
($comment);
321 } elsif ($state eq "comment") {
322 $comment .= $_ . "\n";
326 print "NOTICE: unknown line '$_'\n";
330 print $index "<p><a href=\"index_all.html\">Alphabetic index</a></p>\n" if $format eq "splithtml";
331 print $index "<p><a href=\"#index\">Alphabetic index</a></p>\n" if $format eq "singlehtml";
332 print $index "<hr />\n" if $format eq "singlehtml";
334 # and now, build the option pages
335 my (@names) = keys %option;
336 foreach $name (@names) {
337 next if $option{$name}->{'type'} eq "obsolete";
338 generate_page
("${top}/${pagetemplate}", $option{$name});
341 # and now, the alpabetic index file!
345 if ($format eq "splithtml") {
347 my ($indexname) = filename
("index_all");
348 $fh->open($indexname, "w") || die "Couldn't open $indexname for writing: $!\n";
351 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
352 <html xmlns="http://www.w3.org/1999/xhtml">
354 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
355 <title>Squid $version configuration file</title>
356 <meta name="keywords" content="squid squid.conf config configure" />
357 <meta name="description" content="Squid $version" />
358 <link rel="stylesheet" type="text/css" href="http://www.squid-cache.org/default.css" />
359 <link rel="stylesheet" type="text/css" href="http://www.squid-cache.org/cfgman.css" />
364 <h1><a href="http://www.squid-cache.org/"><span>Squid-</span>Cache.org</a></h1>
365 <h2>Optimising Web Delivery</h2>
369 <p>| <a href="index.html">Table of contents</a> |</p>
371 <h1>Alphabetic index of all options</h1>
374 } elsif ($format eq "singlehtml") {
376 print $fh "<h2><a name=\"index\">Alphabetic index of all options</a></h2>\n";
381 foreach $name (sort keys %all_names) {
382 my ($data) = $all_names{$name};
383 next if $data->{'type'} eq "obsolete";
384 print $fh ' <li><a href="' . uriescape
($data->{'name'}) . '.html" name="toc_' . htmlescape
($name) . '">' . htmlescape
($name) . "</a></li>\n";
390 <p>| <a href="index.html">Table of contents</a> |</p>