--- /dev/null
+#!/usr/bin/env perl
+# Simple script for substitute placeholders in Texinfo files with
+# docstring values found in source code.
+# Copyright (C) 2020 Sergey Matveev (stargrave@stargrave.org)
+#
+# If you C source code contains:
+#
+# // TEXINFO: SomeKey
+# // ...
+# // last line of docstring
+# some C code
+#
+# Then under "SomeKey" you will have the whole docstring (starting from
+# the line after "TEXINFO", till "last line"). You can include its
+# contents (excluding comment characters) in your .texi files placing
+#
+# @DOCSTRING SomeKey@
+
+use strict;
+use warnings;
+
+my $verbose = 0;
+if ($ARGV[0] eq "-v") {
+ $verbose = 1;
+ shift @ARGV;
+};
+my @srcDirs = split / /, $ARGV[0];
+my $docDir = $ARGV[1];
+my $docBuildDir = $ARGV[2];
+
+my %docstrings;
+
+foreach my $srcDir (@srcDirs) {
+ print "src: $srcDir\n" if $verbose;
+ opendir(my $dir, $srcDir) or die "can not open $srcDir";
+ foreach my $fn (readdir $dir) {
+ next unless $fn =~ /\.[ch]$/;
+ open(my $src, "<:encoding(UTF-8)", "$srcDir/$fn") or
+ die "can not open $srcDir/$fn";
+ my $curEntry;
+ while(<$src>) {
+ chomp;
+ if (not /^\/\//) {
+ if (defined $curEntry) {
+ undef $curEntry;
+ };
+ next;
+ };
+ s/^\/\/ ?//;
+ if (/^TEXINFO: (.*)$/) {
+ $curEntry = $1;
+ $docstrings{$curEntry} = "";
+ print "\t$fn: $curEntry\n" if $verbose;
+ next;
+ };
+ ( $docstrings{$curEntry} .= "$_\n" ) if defined $curEntry;
+ };
+ close $src;
+ };
+ closedir $dir;
+};
+
+print "doc: $docDir\n" if $verbose;
+opendir(my $dir, $docDir) or die "can not open $docDir";
+foreach my $fn (readdir $dir) {
+ next unless $fn =~ /\.texi$/;
+ open(my $src, "<:encoding(UTF-8)", "$docDir/$fn") or
+ die "can not open $docDir/$fn";
+ open(my $dst, ">:encoding(UTF-8)", "$docBuildDir/$fn") or
+ die "can not open $docBuildDir/$fn";
+ while(<$src>) {
+ ( print($dst $_) and next ) unless /^\@DOCSTRING (.*)\@$/;
+ print "\t$fn: $1\n" if $verbose;
+ die "unable to find docstring: $1" unless defined $docstrings{$1};
+ print $dst $docstrings{$1};
+ };
+ close $src;
+ close $dst;
+};
+closedir $dir;