Home | History | Annotate | Download | only in examples
      1 # Extract all examples from the manual source.            -*- AWK -*-
      2 
      3 # This file is part of GNU Bison
      4 
      5 # Copyright (C) 1992, 2000-2001, 2005-2006, 2009-2012 Free Software
      6 # Foundation, Inc.
      7 #
      8 # This program is free software: you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation, either version 3 of the License, or
     11 # (at your option) any later version.
     12 #
     13 # This program is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 #
     18 # You should have received a copy of the GNU General Public License
     19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20 
     21 # This script is for use with any Awk that conforms to POSIX.
     22 # It was derived from a similar script tests/generate.awk in GNU m4.
     23 #
     24 # Usage: extexi input-file.texi ... -- [FILES to extract]
     25 BEGIN {
     26   if (!output_dir)
     27     output_dir = ".";
     28   for (argc = 1; argc < ARGC; ++argc)
     29     if (ARGV[argc] == "--")
     30       break;
     31   for (i = argc + 1; i < ARGC; ++i)
     32     file_wanted[ARGV[i]] = 1;
     33   ARGC = argc;
     34 }
     35 
     36 /^@node / {
     37   if (seq > 0)
     38     print "AT_CLEANUP";
     39 
     40   split ($0, tmp, ",");
     41   node = substr(tmp[1], 7);
     42   seq = 0;
     43 }
     44 
     45 /^@comment file: / {
     46   if (!file_wanted[$3])
     47     message("ignoring " $3);
     48   else
     49     {
     50       message("extracting " $3);
     51       file = $3;
     52     }
     53 }
     54 
     55 /^@example$/, /^@end example$/ {
     56   if (!file)
     57     next;
     58 
     59   if ($0 ~ /^@example$/)
     60     {
     61       input = files_output[file] ? "\n" : "";
     62 
     63       # FNR is starting at 0 instead of 1, and
     64       # #line report the line number of the *next* line.
     65       # => + 2.
     66       # Note that recent Bison support it, but not Flex.
     67       if (file ~ /\.[chy]*$/)
     68 	input = "#line " (FNR + 1) " \"" FILENAME "\"\n";
     69       next;
     70     }
     71 
     72   if ($0 ~ /^@end example$/)
     73     {
     74       if (input == "")
     75 	fatal("no contents: " file);
     76 
     77       input = normalize(input);
     78       # No spurious end of line: use printf.
     79       if (files_output[file])
     80 	# The parens around the output file seem to be required
     81         # by awk on Mac OS X Tiger (darwin 8.4.6).
     82         printf ("%s", input) >> (output_dir "/" file);
     83       else
     84 	printf ("%s", input) > (output_dir "/" file);
     85       close (output_dir "/" file);
     86       files_output[file] = 1;
     87 
     88       file = input = "";
     89       next;
     90     }
     91 
     92   input = input $0 "\n";
     93 }
     94 
     95 
     96 # We have to handle CONTENTS line per line, since anchors in AWK are
     97 # referring to the whole string, not the lines.
     98 function normalize(contents,    i, lines, n, line, res) {
     99   # Remove the Texinfo tags.
    100   n = split (contents, lines, "\n");
    101   # We don't want the last field which empty: it's behind the last \n.
    102   for (i = 1; i < n; ++i)
    103     {
    104       line = lines[i];
    105 
    106       # Whole line commands.
    107       if (line ~ /^@(c |comment|dots|end (ignore|group)|ignore|group)/)
    108 	# Gperf accepts empty lines as valid input!!!
    109 	if (file ~ /\.gperf$/)
    110 	  continue;
    111 	else
    112 	  line = "";
    113 
    114       gsub (/"@value\{VERSION\}"/, "\"" VERSION "\"", line)
    115       gsub (/^@result\{\}/, "", line);
    116       gsub (/^@error\{\}/,  "", line);
    117       gsub ("@[{]", "{", line);
    118       gsub ("@}", "}", line);
    119       gsub ("@@", "@", line);
    120       gsub ("@comment.*", "", line);
    121 
    122       res = res line "\n";
    123     }
    124   return res;
    125 }
    126 
    127 
    128 function message(msg) {
    129   if (! message_printed[msg])
    130     {
    131       print "extexi: " msg > "/dev/stderr";
    132       message_printed[msg] = 1;
    133     }
    134 }
    135 
    136 function fatal(msg) {
    137   message(msg);
    138   exit 1
    139 }
    140