]> Sergey Matveev's repositories - dotfiles.git/blob - bin/bin/docstringer.pl
Download magnet
[dotfiles.git] / bin / bin / docstringer.pl
1 #!/usr/bin/env perl
2 # Simple script for substitute placeholders in Texinfo files with
3 # docstring values found in source code.
4 # Copyright (C) 2020-2023 Sergey Matveev (stargrave@stargrave.org)
5 #
6 # If you C source code contains:
7 #
8 #     // TEXINFO: SomeKey
9 #     // ...
10 #     // last line of docstring
11 #     some C code
12 #
13 # Then under "SomeKey" you will have the whole docstring (starting from
14 # the line after "TEXINFO", till "last line"). You can include its
15 # contents (excluding comment characters) in your .texi files placing
16 #
17 #     @DOCSTRING SomeKey@
18
19 use strict;
20 use warnings;
21
22 my $verbose = 0;
23 if ($ARGV[0] eq "-v") {
24     $verbose = 1;
25     shift @ARGV;
26 }
27 my $outDir = $ARGV[0];
28 my @srcDirs = split /:/, $ARGV[1];
29 my @docDirs = split /:/, $ARGV[2];
30 my @exts = split / /, (defined $ENV{EXTS}) ? $ENV{EXTS} : "c h h.in";
31
32 my %docstrings;
33
34 foreach my $srcDir (@srcDirs) {
35     print "src: $srcDir\n" if $verbose;
36     opendir(my $dir, $srcDir) or die "can not open $srcDir";
37     foreach my $fn (readdir $dir) {
38         next unless grep { $fn =~ /\.$_$/ } @exts;
39         open(my $src, "<:encoding(UTF-8)", "$srcDir/$fn") or
40             die "can not open $srcDir/$fn";
41         my $curEntry;
42         while (<$src>) {
43             chomp;
44             if (not /^\/\//) {
45                 if (defined $curEntry) {
46                     undef $curEntry;
47                 }
48                 next;
49             }
50             s/^\/\/ ?//;
51             if (/^TEXINFO: (.*)$/) {
52                 $curEntry = $1;
53                 $docstrings{$curEntry} = "";
54                 print "\t$fn: $curEntry\n" if $verbose;
55                 next;
56             }
57             ($docstrings{$curEntry} .= "$_\n") if defined $curEntry;
58         }
59         close $src;
60     }
61     closedir $dir;
62 }
63
64 foreach my $docDir (@docDirs) {
65     print "doc: $docDir\n" if $verbose;
66     opendir(my $dir, $docDir) or die "can not open $docDir";
67     ($docDir .= "/") unless $docDir =~ /\/$/;
68     ($docDir = "") if $docDir eq "./";
69     foreach my $fn (readdir $dir) {
70         next unless $fn =~ /\.texi$/;
71         $fn = $docDir . $fn;
72         open(my $src, "<:encoding(UTF-8)", $fn) or die "can not open $fn";
73         mkdir "$outDir/$docDir";
74         open(my $dst, ">:encoding(UTF-8)", "$outDir/$fn") or
75             die "can not open $outDir/$fn";
76         while (<$src>) {
77             (print($dst $_) and next) unless /^\s*\@DOCSTRING (.*)\@$/;
78             print "\t$fn: $1\n" if $verbose;
79             die "unable to find docstring: $1" unless defined $docstrings{$1};
80             print $dst $docstrings{$1};
81         }
82         close $src;
83         close $dst;
84     }
85     closedir $dir;
86 }