Blame tools/generate-docs-nm-property-infos.pl

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