|
Packit |
5756e2 |
#!/usr/bin/env perl
|
|
Packit Service |
87a54e |
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
Packit |
5756e2 |
#
|
|
Packit |
5756e2 |
# Copyright (C) 2014 Red Hat, Inc.
|
|
Packit |
5756e2 |
#
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#
|
|
Packit |
5756e2 |
# The script parses nm-setting-*.c files and extracts documentation related
|
|
Packit |
5756e2 |
# to setting plugins. The documentation is in a simple format of lines
|
|
Packit |
5756e2 |
# "keyword: value". The documentation is enclosed between tags
|
|
Packit |
5756e2 |
# ---<plugin-name>--- and ---end---
|
|
Packit |
5756e2 |
# Recognized keywords are:
|
|
Packit |
5756e2 |
# "property: " - property name
|
|
Packit |
5756e2 |
# "variable: " - name of the variable used by the plugin
|
|
Packit |
5756e2 |
# "format: " - format of the value in 'keyfile' plugin
|
|
Packit |
5756e2 |
# "default: " - default value when variable is not used
|
|
Packit |
5756e2 |
# "values: " - allowed values (e.g. for enumerations)
|
|
Packit |
5756e2 |
# "example: " - example(s)
|
|
Packit |
5756e2 |
# "description: " - description text
|
|
Packit |
5756e2 |
# Value is an arbitrary string that can span over multiple lines.
|
|
Packit |
5756e2 |
#
|
|
Packit |
5756e2 |
# ifcfg-rh specifics:
|
|
Packit |
5756e2 |
# - mark NM extension variables with (+), e.g. variable: UUID(+)
|
|
Packit |
5756e2 |
#
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
use strict;
|
|
Packit |
5756e2 |
use warnings;
|
|
Packit |
5756e2 |
use v5.10;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# global variables
|
|
Packit |
5756e2 |
my @keywords = ("property", "variable", "format", "values", "default", "example", "description");
|
|
Packit |
5756e2 |
my @data;
|
|
Packit |
5756e2 |
my $fo;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
(scalar @ARGV >= 3) or die "Usage: $0 <plugin> <output-xml-file> <srcfiles>\n";
|
|
Packit |
5756e2 |
my ($plugin, $output, (@source_files)) = @ARGV;
|
|
Packit |
5756e2 |
my $start_tag = "---$plugin---\\s*\$";
|
|
Packit |
5756e2 |
my $end_tag = '---end---';
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# open output file
|
|
Packit |
5756e2 |
open $fo, '>', $output or die "Can't open $output: $!";
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# write XML header
|
|
Packit |
5756e2 |
write_header();
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# write generated documentation for each setting
|
|
Packit |
5756e2 |
foreach my $c_file (@source_files) {
|
|
Packit |
5756e2 |
my $setting_name = get_setting_name($c_file);
|
|
Packit |
5756e2 |
if ($setting_name) {
|
|
Packit |
5756e2 |
write_item("<setting name=\"$setting_name\">");
|
|
Packit |
5756e2 |
scan_doc_comments($c_file, $start_tag, $end_tag);
|
|
Packit |
5756e2 |
write_item("</setting>");
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# write XML footer
|
|
Packit |
5756e2 |
write_footer();
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# close output file
|
|
Packit |
5756e2 |
close $fo;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
### --- subroutines --- ###
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# get setting name from NM_SETTING_*_SETTING_NAME constant in C header file
|
|
Packit |
5756e2 |
sub get_setting_name {
|
|
Packit |
5756e2 |
my $path = $_[0];
|
|
Packit Service |
dff8e4 |
$path =~ s/\/libnm-core-impl\/nm-setting-(.*)\.c$/\/libnm-core-public\/nm-setting-$1.h/; # use header file to find out setting name
|
|
Packit Service |
dff8e4 |
$path =~ s/\.c$/.h/; # use header file to find out setting name
|
|
Packit |
5756e2 |
open my $fh, '<', $path or die "Can't open $path: $!";
|
|
Packit |
5756e2 |
while (my $line = <$fh>) {
|
|
Packit |
5756e2 |
if ($line =~ /NM_SETTING_.+SETTING_NAME\s+\"(\S+)\"/) {
|
|
Packit |
5756e2 |
return $1;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# scan source setting file for documentation tags and write them to XML
|
|
Packit |
5756e2 |
sub scan_doc_comments {
|
|
Packit |
5756e2 |
my($setting_file, $start, $end) = @_;
|
|
Packit |
5756e2 |
open my $fi, '<', $setting_file or die "Can't open $setting_file: $!";
|
|
Packit |
5756e2 |
while (<$fi>) {
|
|
Packit |
5756e2 |
if (/$start/ .. /$end/) {
|
|
Packit |
5756e2 |
next if /$start/;
|
|
Packit |
5756e2 |
if (/$end/) {
|
|
Packit |
5756e2 |
process_data();
|
|
Packit |
5756e2 |
} else {
|
|
Packit |
5756e2 |
push @data, $_;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
next;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
# ignore text not inside marks
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
close $fi;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# process plugin property documentation comments
|
|
Packit |
5756e2 |
sub process_data {
|
|
Packit |
5756e2 |
return if not @data;
|
|
Packit |
5756e2 |
my $kwd_pat = join("|", @keywords);
|
|
Packit |
5756e2 |
my %parsed_data;
|
|
Packit |
5756e2 |
my $this_key;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
foreach (@data) {
|
|
Packit |
5756e2 |
if (/^\s*\**\s+($kwd_pat):\s+(.*?)\s*$/) {
|
|
Packit |
5756e2 |
$this_key = $1;
|
|
Packit |
5756e2 |
$parsed_data{$this_key} = "$2\n";
|
|
Packit |
5756e2 |
} elsif (/^\s*\**\s+(.*?)\s*$/) {
|
|
Packit |
5756e2 |
die "Extra mess in a comment: $_" unless $this_key;
|
|
Packit |
5756e2 |
$parsed_data{$this_key} .= "$1\n";
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# now write a line into the XML
|
|
Packit |
5756e2 |
my $name = $parsed_data{property} // "";
|
|
Packit |
5756e2 |
my $var = $parsed_data{variable} // $name; # fallback to "property: "
|
|
Packit |
5756e2 |
my $format = $parsed_data{format} // "";
|
|
Packit |
5756e2 |
my $values = $parsed_data{values} // "";
|
|
Packit |
5756e2 |
my $def = $parsed_data{default} // "";
|
|
Packit |
5756e2 |
my $exam = $parsed_data{example} // "";
|
|
Packit |
5756e2 |
my $desc = $parsed_data{description} // "";
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
chomp($name, $var, $format, $values, $def, $exam, $desc);
|
|
Packit |
5756e2 |
escape_xml_chars($name, $var, $format, $values, $def, $exam, $desc);
|
|
Packit |
5756e2 |
my $foo = sprintf("
|
|
Packit |
5756e2 |
"default=\"%s\" example=\"%s\" description=\"%s\"/>",
|
|
Packit |
5756e2 |
$name, $var, $format, $values, $def, $exam, $desc);
|
|
Packit |
5756e2 |
write_item($foo);
|
|
Packit |
5756e2 |
@data = ();
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
# - XML handling -
|
|
Packit |
5756e2 |
sub write_header {
|
|
Packit |
5756e2 |
(my $header =
|
|
Packit |
5756e2 |
qq{<nm-setting-docs>
|
|
Packit |
5756e2 |
}) =~ s/^ {7}//mg;
|
|
Packit |
5756e2 |
print {$fo} $header;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
sub write_footer {
|
|
Packit |
5756e2 |
my $footer = "</nm-setting-docs>";
|
|
Packit |
5756e2 |
print {$fo} $footer;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
sub write_item {
|
|
Packit |
5756e2 |
my $str = join("", @_);
|
|
Packit |
5756e2 |
print {$fo} $str, "\n";
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
sub escape_xml_chars {
|
|
Packit |
5756e2 |
# http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined%5Fentities%5Fin%5FXML
|
|
Packit |
5756e2 |
foreach my $val (@_) {
|
|
Packit |
5756e2 |
$val =~ s/&/&/sg;
|
|
Packit |
5756e2 |
$val =~ s/</</sg;
|
|
Packit |
5756e2 |
$val =~ s/>/>/sg;
|
|
Packit |
5756e2 |
$val =~ s/"/"/sg;
|
|
Packit |
5756e2 |
$val =~ s/'/'/sg;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|