dpkg-parsechangelog.pl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use English;
  5. use POSIX;
  6. use POSIX qw(:errno_h);
  7. use Dpkg;
  8. use Dpkg::Gettext;
  9. use Dpkg::ErrorHandling qw(warning error syserr subprocerr usageerr);
  10. textdomain("dpkg-dev");
  11. my $format ='debian';
  12. my $changelogfile = 'debian/changelog';
  13. my @parserpath = ("/usr/local/lib/dpkg/parsechangelog",
  14. "$dpkglibdir/parsechangelog");
  15. my $libdir;
  16. my $force;
  17. sub version {
  18. printf _g("Debian %s version %s.\n"), $progname, $version;
  19. printf _g("
  20. Copyright (C) 1996 Ian Jackson.
  21. Copyright (C) 2001 Wichert Akkerman");
  22. printf _g("
  23. This is free software; see the GNU General Public Licence version 2 or
  24. later for copying conditions. There is NO warranty.
  25. ");
  26. }
  27. sub usage {
  28. printf _g(
  29. "Usage: %s [<option> ...]
  30. Options:
  31. -l<changelogfile> get per-version info from this file.
  32. -F<changelogformat> force change log format.
  33. -L<libdir> look for change log parsers in <libdir>.
  34. -h, --help show this help message.
  35. --version show the version.
  36. parser options:
  37. --format <outputformat> see man page for list of available
  38. output formats, defaults to 'dpkg'
  39. for compatibility with dpkg-dev
  40. --since, -s, -v <version> include all changes later than version
  41. --until, -u <version> include all changes earlier than version
  42. --from, -f <version> include all changes equal or later
  43. than version
  44. --to, -t <version> include all changes up to or equal
  45. than version
  46. --count, -c, -n <number> include <number> entries from the top
  47. (or the tail if <number> is lower than 0)
  48. --offset, -o <number> change the starting point for --count,
  49. counted from the top (or the tail if
  50. <number> is lower than 0)
  51. --all include all changes
  52. "), $progname;
  53. }
  54. my @ap = ();
  55. while (@ARGV) {
  56. last unless $ARGV[0] =~ m/^-/;
  57. $_= shift(@ARGV);
  58. if (m/^-L/ && length($_)>2) { $libdir=$POSTMATCH; next; }
  59. if (m/^-F([0-9a-z]+)$/) { $force=1; $format=$1; next; }
  60. push(@ap,$_);
  61. if (m/^-l/ && length($_)>2) { $changelogfile=$POSTMATCH; next; }
  62. m/^--$/ && last;
  63. m/^-[cfnostuv]/ && next;
  64. m/^--all$/ && next;
  65. m/^--(count|file|format|from|offset|since|to|until)(.*)$/ && do {
  66. push(@ap, shift(@ARGV)) unless $2;
  67. next;
  68. };
  69. if (m/^-(h|-help)$/) { &usage; exit(0); }
  70. if (m/^--version$/) { &version; exit(0); }
  71. &usageerr(_g("unknown option \`%s'"), $_);
  72. }
  73. @ARGV && usageerr(_g("%s takes no non-option arguments"), $progname);
  74. if (not $force and $changelogfile ne "-") {
  75. open(STDIN,"<", $changelogfile) ||
  76. syserr(_g("cannot open %s to find format"), $changelogfile);
  77. open(P,"-|","tail","-n",40) || syserr(_g("cannot fork"));
  78. while(<P>) {
  79. next unless m/\schangelog-format:\s+([0-9a-z]+)\W/;
  80. $format=$1;
  81. }
  82. close(P);
  83. $? && subprocerr(_g("tail of %s"), $changelogfile);
  84. }
  85. my ($pa, $pf);
  86. unshift(@parserpath, $libdir) if $libdir;
  87. for my $pd (@parserpath) {
  88. $pa= "$pd/$format";
  89. if (!stat("$pa")) {
  90. $! == ENOENT || syserr(_g("failed to check for format parser %s"), $pa);
  91. } elsif (!-x _) {
  92. warning(_g("format parser %s not executable"), $pa);
  93. } else {
  94. $pf= $pa;
  95. last;
  96. }
  97. }
  98. defined($pf) || error(_g("format %s unknown"), $pa);
  99. if ($changelogfile ne "-") {
  100. open(STDIN,"<", $changelogfile)
  101. || syserr(_g("cannot open %s: %s"), $changelogfile);
  102. }
  103. exec($pf,@ap) || syserr(_g("cannot exec format parser: %s"));