1#!/usr/local/bin/perl 2# 3# Copyright (c) 2001 Tama Communications Corporation 4# 5# This file is part of GNU GLOBAL. 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20# Main procedure. 21# 22$com = $0; 23$com =~ s/.*\///; 24while ($ARGV[0] =~ /^-/) { 25 $opt = shift; 26 if ($opt eq '--c') { 27 $c = 1; 28 } elsif ($opt eq '--perl') { 29 $perl = 1; 30 } elsif ($opt eq '--man') { 31 $man = 1; 32 } elsif ($opt eq '--info') { 33 $info = 1; 34 } elsif ($opt eq '--menu') { 35 $menu = 1; 36 } 37} 38if ($menu) { 39 &menu'gen(@ARGV); 40} else { 41 $infile = $ARGV[0]; 42 open(INFILE, $infile) || die("cannot open '$infile'\n"); 43 if ($c) { 44 &c'gen(); 45 } elsif ($perl) { 46 &perl'gen(); 47 } elsif ($man) { 48 &man'gen(); 49 } elsif ($info) { 50 &info'gen(); 51 } 52 close(INFILE); 53} 54exit 0; 55#------------------------------------------------------------------ 56# 57# Generate langmap statement. 58# 59#------------------------------------------------------------------ 60# 61# Get a value from configure.ac file by name. 62# 63sub getvalue { 64 my($name) = @_; 65 my $value; 66 # 67 # A value should be defined as: 68 # NAME='VALUE' 69 # 70 my $line=`grep "$name=" configure.ac`; 71 ($value) = $line =~ /^$name='(.*)'$/; 72 unless ($value) { 73 print STDERR "$name not found.\n"; 74 exit(1); 75 } 76 $value; 77} 78# 79# Generate statements about the langmap variable. 80# 81sub langmapstatement { 82 my($maps) = getvalue('DEFAULTLANGMAP'); 83 my(@statement); 84 my %name = ( 85 'c' => 'C', 86 'yacc' => 'Yacc', 87 'java' => 'Java', 88 'cpp' => 'C++', 89 'php' => 'PHP', 90 'asm' => 'assembly language', 91 ); 92 my $line = ''; 93 my @maps = split(/,/, $maps); 94 for ($i = 0; $i < @maps; $i++) { 95 $_ = $maps[$i]; 96 my($lang, $suffixes) = /([^:]+):(.*)/; 97 if ($i > 0) { 98 if ($i + 1 == @maps) { # last 99 $line .= ' and '; 100 } else { 101 $line .= ', '; 102 } 103 } 104 $line .= $name{$lang}; 105 } 106 $line .= " source files.\n"; 107 unshift(@statement, $line); 108 foreach (@maps) { 109 my($lang, $suffixes) = /([^:]+):(.*)/; 110 unless ($name{$lang}) { 111 print STDERR "ERROR: $lang not defined.\n"; 112 exit(1); 113 } 114 $suffixes =~ s/^\.//; 115 my(@suffixes) = split(/\./, $suffixes); 116 $line = 'Files whose names end in '; 117 for ($i = 0; $i < @suffixes; $i++) { 118 my $sx = $suffixes[$i]; 119 $line .= ', ' if ($i > 0); 120 $line .= "\@file{.$sx}"; 121 } 122 $line .= " are assumed to be $name{$lang} source files.\n"; 123 unshift(@statement, $line); 124 } 125 @statement; 126} 127#------------------------------------------------------------------ 128# 129# Read line. 130# 131#------------------------------------------------------------------ 132@lines = (); 133sub getline { 134 if (@lines > 0) { 135 $_ = pop(@lines); 136 } else { 137 while (<INFILE>) { 138 if (/\@LANGMAPSTATEMENT\@/) { 139 @lines = &'langmapstatement(); 140 $_ = pop(@lines); 141 } elsif (/\@DEFAULTLANGMAP\@/) { 142 my $value = &'getvalue('DEFAULTLANGMAP'); 143 s/\@DEFAULTLANGMAP\@/$value/; 144 } elsif (/\@DEFAULTINCLUDEFILESUFFIXES\@/) { 145 my $value = &'getvalue('DEFAULTINCLUDEFILESUFFIXES'); 146 s/\@DEFAULTINCLUDEFILESUFFIXES\@/$value/; 147 } 148 last unless (/^#/); 149 } 150 } 151 ($_) ? 1 : 0; 152} 153sub ungetline { 154 push(@lines, $_); 155} 156#------------------------------------------------------------------ 157# 158# C package. 159# 160#------------------------------------------------------------------ 161package c; 162sub convert { 163 local($arg) = '[^},]+'; 164 local($macros) = 'arg|code|var|file|name|option|val|samp|kbd'; 165 chop; 166 s/^\s+//; 167 while (s/\@($macros)\{($arg)\}/$2/) { 168 ; 169 } 170 while (s/\@xref\{($arg),($arg)\}/$1($2)/) { 171 ; 172 } 173 while (s/\@(begin|end)_verbatim//) { 174 ; 175 } 176} 177sub gen { 178 local($help_const) = 0; 179 print "/* This file is generated automatically by $'com from $'infile. */\n"; 180 while (&'getline()) { 181 if (/^\@NAME\s+(.*)\s+-/) { 182 print "const char *progname = \"$1\";\n"; 183 } elsif (/^\@SYNOPSIS$/) { 184 local($first) = 1; 185 print "const char *usage_const = \""; 186 while (&'getline()) { 187 if (/^\@/) { 188 &'ungetline(); 189 last; 190 } 191 convert(); 192 if ($first) { 193 $first = 0; 194 print "Usage: "; 195 } else { 196 print "\\n\\\n"; 197 print " "; 198 } 199 print $_; 200 } 201 print "\\n\";\n"; 202 } elsif (/^\@COMMANDS$/ || /^\@OPTIONS$/) { 203 if (!$help_const) { 204 $help_const = 1; 205 print "const char *help_const = \""; 206 } 207 if (/^\@COMMANDS$/) { 208 print "Commands:"; 209 } else { 210 print "Options:"; 211 } 212 print "\\n\\\n"; 213 local($itemize) = 0; 214 while (&'getline()) { 215 if (/^\@/) { 216 &'ungetline(); 217 last; 218 } 219 convert(); 220 if (/^\@begin_itemize$/) { 221 $itemize = 1; 222 } elsif (/^\@end_itemize$/) { 223 $itemize = 0; 224 } elsif ($itemize) { 225 if (/^\@item\{(.*)\}$/) { 226 print $1; 227 } else { 228 print " "; 229 print; 230 } 231 print "\\n\\\n"; 232 } 233 } 234 } 235 } 236 print "See also:\\n\\\n"; 237 print " GNU GLOBAL web site: http://www.gnu.org/software/global/\\n\\\n"; 238 print "\";\n"; 239} 240#------------------------------------------------------------------ 241# 242# Man package. 243# 244#------------------------------------------------------------------ 245package man; 246sub convert { 247 local($arg) = '[^},]+'; 248 s/^\s+//; 249 while (s/\@arg\{($arg)\}/\\fI$1\\fP/) { 250 ; 251 } 252 while (/\@code\{($arg)\}/) { 253 $val = $1; 254 $val =~ s/\./\\./g; 255 s/\@code\{$arg\}/$val/; 256 } 257 while (s/\@(val|samp|kbd)\{([^}]+)\}/\\'$2\\'/) { 258 ; 259 } 260 while (s/\@file\{($arg)\}/\\'$1\\'/) { 261 ; 262 } 263 while (s/\@(var|name|option)\{($arg)\}/\\fB$2\\fP/) { 264 ; 265 } 266 while (s/\@xref\{($arg),($arg)\}/\\fB$1\\fP($2)/) { 267 ; 268 } 269 s/\@\{/\{/g; 270 s/\@\}/\}/g; 271 s/\@br$/\n.br/; 272 s/\@\@/@/g; 273 s/^\./\\&./; 274} 275sub gen { 276 local($arg) = '[^,]+'; 277 print ".\\\" This file is generated automatically by $'com from $'infile.\n"; 278 while (&'getline()) { 279 if (/^\@HEADER\s+($arg),($arg),($arg),($arg)\n$/) { 280 print ".TH $1 $2 \"$3\" \"$4\"\n"; 281 } elsif (/^\@NAME\s+(.*)$/) { 282 local($name) = $1; 283 $name =~ s/-/\\-/; 284 print ".SH NAME\n$name\n"; 285 } elsif (/^\@(SYNOPSIS)$/) { 286 print ".SH $1\n"; 287 while (&'getline()) { 288 if (/^\@/) { 289 &'ungetline(); 290 last; 291 } elsif (/^$/) { 292 print ".PP\n"; 293 next; 294 } 295 convert(); 296 print; 297 print ".br\n"; 298 } 299 } elsif (/^\@(.*)$/) { 300 $type = $1; 301 if ($type =~ /\s+/) { 302 $type = "\"$type\""; 303 } 304 print ".SH $type\n"; 305 local($itemize) = 0; 306 local($verbatim) = 0; 307 while (&'getline()) { 308 if (/^\s*\@begin_verbatim\s*$/) { 309 $verbatim = 1; 310 print ".nf\n"; 311 next; 312 } elsif (/^\s*\@end_verbatim\s*$/) { 313 $verbatim = 0; 314 print ".fi\n"; 315 next; 316 } elsif (/^\@/) { 317 &'ungetline(); 318 last; 319 } elsif (/^$/) { 320 print ".PP\n"; 321 next; 322 } 323 convert(); 324 if (/^\@begin_itemize$/) { 325 $itemize = 1; 326 } elsif (/^\@end_itemize$/) { 327 $itemize = 0; 328 } elsif ($itemize && /^\@item\{(.*)\}$/) { 329 print ".TP\n$1\n"; 330 } else { 331 print; 332 } 333 } 334 } 335 } 336} 337#------------------------------------------------------------------ 338# 339# Info package. 340# 341#------------------------------------------------------------------ 342package info; 343sub convert { 344 local($arg) = '[^},]+'; 345 chop; 346 s/^\s+//; 347 while (s/\@xref\{($arg),($arg)\}/$1($2)/) { 348 ; 349 } 350 s/\@option\{/\@samp\{/g; 351 s/\@val\{/\@samp\{/g; 352 while (s/\@(arg|name)\{($arg)\}/$2/) { 353 ; 354 } 355 s/\@br$/\@\*/; 356} 357sub gen { 358 print "\@c This file is generated automatically by $'com from $'infile.\n"; 359 while (&'getline()) { 360 if (/^\@HEADER/) { 361 ; 362 } elsif (/^\@(NAME)\s+(.*)$/) { 363 local($name) = $2; 364 print "\@unnumberedsubsec $1\n"; 365 print "$name\n"; 366 } elsif (/^\@(SYNOPSIS)$/) { 367 print "\@unnumberedsubsec $1\n"; 368 print "\@quotation\n"; 369 while (&'getline()) { 370 if (/^\@/) { 371 &'ungetline(); 372 last; 373 } elsif (/^$/) { 374 print; 375 next; 376 } 377 convert(); 378 print; 379 print "\@*\n"; 380 } 381 print "\@end quotation\n"; 382 } elsif (/^\@(.*)$/) { 383 $type = $1; 384 print "\@unnumberedsubsec $type\n"; 385 local($itemize) = 0; 386 local($verbatim) = 0; 387 while (&'getline()) { 388 if (/^\s*\@begin_verbatim\s*$/) { 389 $verbatim = 1; 390 print "\@example\n"; 391 next; 392 } elsif (/^\s*\@end_verbatim\s*$/) { 393 $verbatim = 0; 394 print "\@end example\n"; 395 next; 396 } elsif ($verbatim) { 397 s/\{/@\{/g; 398 s/\}/@\}/g; 399 s/^\s+//; 400 print; 401 next; 402 } elsif (/^\@/) { 403 &'ungetline(); 404 last; 405 } elsif (/^$/) { 406 print; 407 next; 408 } 409 convert(); 410 if (/^\@begin_itemize$/) { 411 $itemize = 1; 412 print "\@table \@asis\n"; 413 } elsif (/^\@end_itemize$/) { 414 $itemize = 0; 415 print "\@end table\n"; 416 } elsif ($itemize && /^\@item\{(.*)\}$/) { 417 print "\@item $1\n"; 418 } else { 419 print "$_\n"; 420 } 421 } 422 } 423 } 424} 425#------------------------------------------------------------------ 426# 427# Menu package. 428# 429#------------------------------------------------------------------ 430package menu; 431sub gen { 432 local(@args) = @_; 433 local($line, $name); 434 foreach $dir (@args) { 435 $infile = "$dir/manual.in"; 436 open(INFILE, $infile) || die("cannot open '$infile'\n"); 437 while (<INFILE>) { 438 if (/^\@NAME\s+((\S+)\s+\-\s+.*)$/) { 439 $line = $1; 440 $name = $2; 441 last; 442 } 443 } 444 close(INFILE); 445 push(@name, $name); 446 push(@line, $line); 447 } 448 print "\@c This file is generated automatically by $'com from a set of manual.in.\n"; 449 print "\@menu\n"; 450 for ($i = 0; $i < @name; $i++) { 451 $name = $name[$i]; 452 $line = $line[$i]; 453 $name .= '::'; 454 printf "* %-16s %s\n", $name, $line; 455 } 456 print "\@end menu\n\n"; 457 for ($i = 0; $i < @name; $i++) { 458 $name = $name[$i]; 459 $line = $line[$i]; 460 printf "\@node %s\n", $name; 461 printf "\@section %s\n", $line; 462 printf "\@include $name.ref\n"; 463 } 464} 465