FieldsCore.pm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. # Copyright © 2007-2009 Raphaël Hertzog <hertzog@debian.org>
  2. #
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. package Dpkg::Control::FieldsCore;
  16. use strict;
  17. use warnings;
  18. our $VERSION = '1.00';
  19. our @EXPORT = qw(
  20. field_capitalize
  21. field_is_official
  22. field_is_allowed_in
  23. field_transfer_single
  24. field_transfer_all
  25. field_list_src_dep
  26. field_list_pkg_dep
  27. field_get_dep_type
  28. field_get_sep_type
  29. field_ordered_list
  30. field_register
  31. field_insert_after
  32. field_insert_before
  33. FIELD_SEP_UNKNOWN
  34. FIELD_SEP_SPACE
  35. FIELD_SEP_COMMA
  36. FIELD_SEP_LINE
  37. );
  38. use Exporter qw(import);
  39. use Dpkg::Gettext;
  40. use Dpkg::ErrorHandling;
  41. use Dpkg::Control::Types;
  42. use Dpkg::Checksums;
  43. use constant {
  44. ALL_PKG => CTRL_INFO_PKG | CTRL_INDEX_PKG | CTRL_PKG_DEB | CTRL_FILE_STATUS,
  45. ALL_SRC => CTRL_INFO_SRC | CTRL_INDEX_SRC | CTRL_PKG_SRC,
  46. ALL_CHANGES => CTRL_FILE_CHANGES | CTRL_CHANGELOG,
  47. };
  48. use constant {
  49. FIELD_SEP_UNKNOWN => 0,
  50. FIELD_SEP_SPACE => 1,
  51. FIELD_SEP_COMMA => 2,
  52. FIELD_SEP_LINE => 4,
  53. };
  54. # The canonical list of fields
  55. # Note that fields used only in dpkg's available file are not listed
  56. # Deprecated fields of dpkg's status file are also not listed
  57. our %FIELDS = (
  58. 'Architecture' => {
  59. allowed => (ALL_PKG | ALL_SRC | CTRL_FILE_CHANGES) & (~CTRL_INFO_SRC),
  60. separator => FIELD_SEP_SPACE,
  61. },
  62. 'Binary' => {
  63. allowed => CTRL_PKG_SRC | CTRL_FILE_CHANGES,
  64. # XXX: This field values are separated either by space or comma
  65. # depending on the context.
  66. separator => FIELD_SEP_SPACE | FIELD_SEP_COMMA,
  67. },
  68. 'Binary-Only' => {
  69. allowed => ALL_CHANGES,
  70. },
  71. 'Breaks' => {
  72. allowed => ALL_PKG,
  73. separator => FIELD_SEP_COMMA,
  74. dependency => 'union',
  75. dep_order => 7,
  76. },
  77. 'Bugs' => {
  78. allowed => (ALL_PKG | CTRL_INFO_SRC | CTRL_FILE_VENDOR) & (~CTRL_INFO_PKG),
  79. },
  80. 'Build-Conflicts' => {
  81. allowed => ALL_SRC,
  82. separator => FIELD_SEP_COMMA,
  83. dependency => 'union',
  84. dep_order => 4,
  85. },
  86. 'Build-Conflicts-Arch' => {
  87. allowed => ALL_SRC,
  88. separator => FIELD_SEP_COMMA,
  89. dependency => 'union',
  90. dep_order => 5,
  91. },
  92. 'Build-Conflicts-Indep' => {
  93. allowed => ALL_SRC,
  94. separator => FIELD_SEP_COMMA,
  95. dependency => 'union',
  96. dep_order => 6,
  97. },
  98. 'Build-Depends' => {
  99. allowed => ALL_SRC,
  100. separator => FIELD_SEP_COMMA,
  101. dependency => 'normal',
  102. dep_order => 1,
  103. },
  104. 'Build-Depends-Arch' => {
  105. allowed => ALL_SRC,
  106. separator => FIELD_SEP_COMMA,
  107. dependency => 'normal',
  108. dep_order => 2,
  109. },
  110. 'Build-Depends-Indep' => {
  111. allowed => ALL_SRC,
  112. separator => FIELD_SEP_COMMA,
  113. dependency => 'normal',
  114. dep_order => 3,
  115. },
  116. 'Build-Essential' => {
  117. allowed => ALL_PKG,
  118. },
  119. 'Build-Profiles' => {
  120. allowed => CTRL_INFO_PKG,
  121. separator => FIELD_SEP_SPACE,
  122. },
  123. 'Built-For-Profiles' => {
  124. allowed => ALL_PKG | CTRL_FILE_CHANGES,
  125. separator => FIELD_SEP_SPACE,
  126. },
  127. 'Built-Using' => {
  128. allowed => ALL_PKG,
  129. separator => FIELD_SEP_COMMA,
  130. dependency => 'union',
  131. dep_order => 10,
  132. },
  133. 'Changed-By' => {
  134. allowed => CTRL_FILE_CHANGES,
  135. },
  136. 'Changes' => {
  137. allowed => ALL_CHANGES,
  138. },
  139. 'Closes' => {
  140. allowed => ALL_CHANGES,
  141. separator => FIELD_SEP_SPACE,
  142. },
  143. 'Conffiles' => {
  144. allowed => CTRL_FILE_STATUS,
  145. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
  146. },
  147. 'Config-Version' => {
  148. allowed => CTRL_FILE_STATUS,
  149. },
  150. 'Conflicts' => {
  151. allowed => ALL_PKG,
  152. separator => FIELD_SEP_COMMA,
  153. dependency => 'union',
  154. dep_order => 6,
  155. },
  156. 'Date' => {
  157. allowed => ALL_CHANGES,
  158. },
  159. 'Depends' => {
  160. allowed => ALL_PKG,
  161. separator => FIELD_SEP_COMMA,
  162. dependency => 'normal',
  163. dep_order => 2,
  164. },
  165. 'Description' => {
  166. allowed => ALL_PKG | CTRL_FILE_CHANGES,
  167. },
  168. 'Directory' => {
  169. allowed => CTRL_INDEX_SRC,
  170. },
  171. 'Distribution' => {
  172. allowed => ALL_CHANGES,
  173. },
  174. 'Enhances' => {
  175. allowed => ALL_PKG,
  176. separator => FIELD_SEP_COMMA,
  177. dependency => 'union',
  178. dep_order => 5,
  179. },
  180. 'Essential' => {
  181. allowed => ALL_PKG,
  182. },
  183. 'Filename' => {
  184. allowed => CTRL_INDEX_PKG,
  185. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
  186. },
  187. 'Files' => {
  188. allowed => CTRL_PKG_SRC | CTRL_FILE_CHANGES,
  189. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
  190. },
  191. 'Format' => {
  192. allowed => CTRL_PKG_SRC | CTRL_FILE_CHANGES,
  193. },
  194. 'Homepage' => {
  195. allowed => ALL_SRC | ALL_PKG,
  196. },
  197. 'Installed-Size' => {
  198. allowed => ALL_PKG & ~CTRL_INFO_PKG,
  199. },
  200. 'Installer-Menu-Item' => {
  201. allowed => ALL_PKG,
  202. },
  203. 'Kernel-Version' => {
  204. allowed => ALL_PKG,
  205. },
  206. 'Origin' => {
  207. allowed => (ALL_PKG | ALL_SRC) & (~CTRL_INFO_PKG),
  208. },
  209. 'Maintainer' => {
  210. allowed => CTRL_PKG_DEB| CTRL_FILE_STATUS | ALL_SRC | ALL_CHANGES,
  211. },
  212. 'Multi-Arch' => {
  213. allowed => ALL_PKG,
  214. },
  215. 'Package' => {
  216. allowed => ALL_PKG,
  217. },
  218. 'Package-List' => {
  219. allowed => ALL_SRC & ~CTRL_INFO_SRC,
  220. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
  221. },
  222. 'Package-Type' => {
  223. allowed => ALL_PKG,
  224. },
  225. 'Parent' => {
  226. allowed => CTRL_FILE_VENDOR,
  227. },
  228. 'Pre-Depends' => {
  229. allowed => ALL_PKG,
  230. separator => FIELD_SEP_COMMA,
  231. dependency => 'normal',
  232. dep_order => 1,
  233. },
  234. 'Priority' => {
  235. allowed => CTRL_INFO_SRC | CTRL_INDEX_SRC | ALL_PKG,
  236. },
  237. 'Provides' => {
  238. allowed => ALL_PKG,
  239. separator => FIELD_SEP_COMMA,
  240. dependency => 'union',
  241. dep_order => 9,
  242. },
  243. 'Recommends' => {
  244. allowed => ALL_PKG,
  245. separator => FIELD_SEP_COMMA,
  246. dependency => 'normal',
  247. dep_order => 3,
  248. },
  249. 'Replaces' => {
  250. allowed => ALL_PKG,
  251. separator => FIELD_SEP_COMMA,
  252. dependency => 'union',
  253. dep_order => 8,
  254. },
  255. 'Section' => {
  256. allowed => CTRL_INFO_SRC | CTRL_INDEX_SRC | ALL_PKG,
  257. },
  258. 'Size' => {
  259. allowed => CTRL_INDEX_PKG,
  260. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
  261. },
  262. 'Source' => {
  263. allowed => (ALL_PKG | ALL_SRC | ALL_CHANGES) &
  264. (~(CTRL_INDEX_SRC | CTRL_INFO_PKG)),
  265. },
  266. 'Standards-Version' => {
  267. allowed => ALL_SRC,
  268. },
  269. 'Status' => {
  270. allowed => CTRL_FILE_STATUS,
  271. separator => FIELD_SEP_SPACE,
  272. },
  273. 'Subarchitecture' => {
  274. allowed => ALL_PKG,
  275. },
  276. 'Suggests' => {
  277. allowed => ALL_PKG,
  278. separator => FIELD_SEP_COMMA,
  279. dependency => 'normal',
  280. dep_order => 4,
  281. },
  282. 'Tag' => {
  283. allowed => ALL_PKG,
  284. separator => FIELD_SEP_COMMA,
  285. },
  286. 'Task' => {
  287. allowed => ALL_PKG,
  288. },
  289. 'Testsuite' => {
  290. allowed => ALL_SRC,
  291. separator => FIELD_SEP_COMMA,
  292. },
  293. 'Triggers-Awaited' => {
  294. allowed => CTRL_FILE_STATUS,
  295. separator => FIELD_SEP_SPACE,
  296. },
  297. 'Triggers-Pending' => {
  298. allowed => CTRL_FILE_STATUS,
  299. separator => FIELD_SEP_SPACE,
  300. },
  301. 'Uploaders' => {
  302. allowed => ALL_SRC,
  303. separator => FIELD_SEP_COMMA,
  304. },
  305. 'Urgency' => {
  306. allowed => ALL_CHANGES,
  307. },
  308. 'Vcs-Browser' => {
  309. allowed => ALL_SRC,
  310. },
  311. 'Vcs-Arch' => {
  312. allowed => ALL_SRC,
  313. },
  314. 'Vcs-Bzr' => {
  315. allowed => ALL_SRC,
  316. },
  317. 'Vcs-Cvs' => {
  318. allowed => ALL_SRC,
  319. },
  320. 'Vcs-Darcs' => {
  321. allowed => ALL_SRC,
  322. },
  323. 'Vcs-Git' => {
  324. allowed => ALL_SRC,
  325. },
  326. 'Vcs-Hg' => {
  327. allowed => ALL_SRC,
  328. },
  329. 'Vcs-Mtn' => {
  330. allowed => ALL_SRC,
  331. },
  332. 'Vcs-Svn' => {
  333. allowed => ALL_SRC,
  334. },
  335. 'Vendor' => {
  336. allowed => CTRL_FILE_VENDOR,
  337. },
  338. 'Vendor-Url' => {
  339. allowed => CTRL_FILE_VENDOR,
  340. },
  341. 'Version' => {
  342. allowed => (ALL_PKG | ALL_SRC | ALL_CHANGES) &
  343. (~(CTRL_INFO_SRC | CTRL_INFO_PKG)),
  344. },
  345. );
  346. my @checksum_fields = map { &field_capitalize("Checksums-$_") } checksums_get_list();
  347. my @sum_fields = map { $_ eq 'md5' ? 'MD5sum' : &field_capitalize($_) }
  348. checksums_get_list();
  349. &field_register($_, CTRL_PKG_SRC | CTRL_FILE_CHANGES) foreach @checksum_fields;
  350. &field_register($_, CTRL_INDEX_PKG,
  351. separator => FIELD_SEP_LINE | FIELD_SEP_SPACE) foreach @sum_fields;
  352. our %FIELD_ORDER = (
  353. CTRL_PKG_DEB() => [
  354. qw(Package Package-Type Source Version Built-Using Kernel-Version
  355. Built-For-Profiles Architecture Subarchitecture
  356. Installer-Menu-Item Essential Origin Bugs
  357. Maintainer Installed-Size), &field_list_pkg_dep(),
  358. qw(Section Priority Multi-Arch Homepage Description Tag Task)
  359. ],
  360. CTRL_PKG_SRC() => [
  361. qw(Format Source Binary Architecture Version Origin Maintainer
  362. Uploaders Homepage Standards-Version Vcs-Browser
  363. Vcs-Arch Vcs-Bzr Vcs-Cvs Vcs-Darcs Vcs-Git Vcs-Hg Vcs-Mtn
  364. Vcs-Svn Testsuite), &field_list_src_dep(), qw(Package-List),
  365. @checksum_fields, qw(Files)
  366. ],
  367. CTRL_FILE_CHANGES() => [
  368. qw(Format Date Source Binary Binary-Only Built-For-Profiles Architecture
  369. Version Distribution Urgency Maintainer Changed-By Description
  370. Closes Changes),
  371. @checksum_fields, qw(Files)
  372. ],
  373. CTRL_CHANGELOG() => [
  374. qw(Source Binary-Only Version Distribution Urgency Maintainer
  375. Date Closes Changes)
  376. ],
  377. CTRL_FILE_STATUS() => [ # Same as fieldinfos in lib/dpkg/parse.c
  378. qw(Package Essential Status Priority Section Installed-Size Origin
  379. Maintainer Bugs Architecture Multi-Arch Source Version Config-Version
  380. Replaces Provides Depends Pre-Depends Recommends Suggests Breaks
  381. Conflicts Enhances Conffiles Description Triggers-Pending
  382. Triggers-Awaited)
  383. ],
  384. );
  385. # Order for CTRL_INDEX_PKG is derived from CTRL_PKG_DEB
  386. $FIELD_ORDER{CTRL_INDEX_PKG()} = [ @{$FIELD_ORDER{CTRL_PKG_DEB()}} ];
  387. &field_insert_before(CTRL_INDEX_PKG, 'Section', 'Filename', 'Size', @sum_fields);
  388. # Order for CTRL_INDEX_SRC is derived from CTRL_PKG_SRC
  389. $FIELD_ORDER{CTRL_INDEX_SRC()} = [ @{$FIELD_ORDER{CTRL_PKG_SRC()}} ];
  390. @{$FIELD_ORDER{CTRL_INDEX_SRC()}} = map { $_ eq 'Source' ? 'Package' : $_ }
  391. @{$FIELD_ORDER{CTRL_PKG_SRC()}};
  392. &field_insert_after(CTRL_INDEX_SRC, 'Version', 'Priority', 'Section');
  393. &field_insert_before(CTRL_INDEX_SRC, 'Checksums-Md5', 'Directory');
  394. =encoding utf8
  395. =head1 NAME
  396. Dpkg::Control::FieldsCore - manage (list of official) control fields
  397. =head1 DESCRIPTION
  398. The modules contains a list of fieldnames with associated meta-data explaining
  399. in which type of control information they are allowed. The types are the
  400. CTRL_* constants exported by Dpkg::Control.
  401. =head1 FUNCTIONS
  402. =over 4
  403. =item $f = field_capitalize($field_name)
  404. Returns the field name properly capitalized. All characters are lowercase,
  405. except the first of each word (words are separated by a hyphen in field names).
  406. =cut
  407. sub field_capitalize($) {
  408. my $field = lc(shift);
  409. # Some special cases due to history
  410. return 'MD5sum' if $field eq 'md5sum';
  411. return uc($field) if checksums_is_supported($field);
  412. # Generic case
  413. return join '-', map { ucfirst } split /-/, $field;
  414. }
  415. =item field_is_official($fname)
  416. Returns true if the field is official and known.
  417. =cut
  418. sub field_is_official($) {
  419. my $field = field_capitalize(shift);
  420. return exists $FIELDS{$field};
  421. }
  422. =item field_is_allowed_in($fname, @types)
  423. Returns true (1) if the field $fname is allowed in all the types listed in
  424. the list. Note that you can use type sets instead of individual types (ex:
  425. CTRL_FILE_CHANGES | CTRL_CHANGELOG).
  426. field_allowed_in(A|B, C) returns true only if the field is allowed in C
  427. and either A or B.
  428. Undef is returned for non-official fields.
  429. =cut
  430. sub field_is_allowed_in($@) {
  431. my ($field, @types) = @_;
  432. $field = field_capitalize($field);
  433. return unless field_is_official($field);
  434. return 0 if not scalar(@types);
  435. foreach my $type (@types) {
  436. next if $type == CTRL_UNKNOWN; # Always allowed
  437. return 0 unless $FIELDS{$field}{allowed} & $type;
  438. }
  439. return 1;
  440. }
  441. =item field_transfer_single($from, $to, $field)
  442. If appropriate, copy the value of the field named $field taken from the
  443. $from Dpkg::Control object to the $to Dpkg::Control object.
  444. Official fields are copied only if the field is allowed in both types of
  445. objects. Custom fields are treated in a specific manner. When the target
  446. is not among CTRL_PKG_SRC, CTRL_PKG_DEB or CTRL_FILE_CHANGES, then they
  447. are alway copied as is (the X- prefix is kept). Otherwise they are not
  448. copied except if the target object matches the target destination encoded
  449. in the field name. The initial X denoting custom fields can be followed by
  450. one or more letters among "S" (Source: corresponds to CTRL_PKG_SRC), "B"
  451. (Binary: corresponds to CTRL_PKG_DEB) or "C" (Changes: corresponds to
  452. CTRL_FILE_CHANGES).
  453. Returns undef if nothing has been copied or the name of the new field
  454. added to $to otherwise.
  455. =cut
  456. sub field_transfer_single($$;$) {
  457. my ($from, $to, $field) = @_;
  458. $field //= $_;
  459. my ($from_type, $to_type) = ($from->get_type(), $to->get_type());
  460. $field = field_capitalize($field);
  461. if (field_is_allowed_in($field, $from_type, $to_type)) {
  462. $to->{$field} = $from->{$field};
  463. return $field;
  464. } elsif ($field =~ /^X([SBC]*)-/i) {
  465. my $dest = $1;
  466. if (($dest =~ /B/i and $to_type == CTRL_PKG_DEB) or
  467. ($dest =~ /S/i and $to_type == CTRL_PKG_SRC) or
  468. ($dest =~ /C/i and $to_type == CTRL_FILE_CHANGES))
  469. {
  470. my $new = $field;
  471. $new =~ s/^X([SBC]*)-//i;
  472. $to->{$new} = $from->{$field};
  473. return $new;
  474. } elsif ($to_type != CTRL_PKG_DEB and
  475. $to_type != CTRL_PKG_SRC and
  476. $to_type != CTRL_FILE_CHANGES)
  477. {
  478. $to->{$field} = $from->{$field};
  479. return $field;
  480. }
  481. } elsif (not field_is_allowed_in($field, $from_type)) {
  482. warning(g_("unknown information field '%s' in input data in %s"),
  483. $field, $from->get_option('name') || g_('control information'));
  484. }
  485. return;
  486. }
  487. =item field_transfer_all($from, $to)
  488. Transfer all appropriate fields from $from to $to. Calls
  489. field_transfer_single() on all fields available in $from.
  490. Returns the list of fields that have been added to $to.
  491. =cut
  492. sub field_transfer_all($$) {
  493. my ($from, $to) = @_;
  494. my (@res, $res);
  495. foreach my $k (keys %$from) {
  496. $res = field_transfer_single($from, $to, $k);
  497. push @res, $res if $res and defined wantarray;
  498. }
  499. return @res;
  500. }
  501. =item field_ordered_list($type)
  502. Returns an ordered list of fields for a given type of control information.
  503. This list can be used to output the fields in a predictable order.
  504. The list might be empty for types where the order does not matter much.
  505. =cut
  506. sub field_ordered_list($) {
  507. my $type = shift;
  508. return @{$FIELD_ORDER{$type}} if exists $FIELD_ORDER{$type};
  509. return ();
  510. }
  511. =item field_list_src_dep()
  512. List of fields that contains dependencies-like information in a source
  513. Debian package.
  514. =cut
  515. sub field_list_src_dep() {
  516. my @list = sort {
  517. $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
  518. } grep {
  519. field_is_allowed_in($_, CTRL_PKG_SRC) and
  520. exists $FIELDS{$_}{dependency}
  521. } keys %FIELDS;
  522. return @list;
  523. }
  524. =item field_list_pkg_dep()
  525. List of fields that contains dependencies-like information in a binary
  526. Debian package. The fields that express real dependencies are sorted from
  527. the stronger to the weaker.
  528. =cut
  529. sub field_list_pkg_dep() {
  530. my @keys = keys %FIELDS;
  531. my @list = sort {
  532. $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
  533. } grep {
  534. field_is_allowed_in($_, CTRL_PKG_DEB) and
  535. exists $FIELDS{$_}{dependency}
  536. } @keys;
  537. return @list;
  538. }
  539. =item field_get_dep_type($field)
  540. Return the type of the dependency expressed by the given field. Can
  541. either be "normal" for a real dependency field (Pre-Depends, Depends, ...)
  542. or "union" for other relation fields sharing the same syntax (Conflicts,
  543. Breaks, ...). Returns undef for fields which are not dependencies.
  544. =cut
  545. sub field_get_dep_type($) {
  546. my $field = field_capitalize(shift);
  547. return unless field_is_official($field);
  548. return $FIELDS{$field}{dependency} if exists $FIELDS{$field}{dependency};
  549. return;
  550. }
  551. =item field_get_sep_type($field)
  552. Return the type of the field value separator. Can be one of FIELD_SEP_UNKNOWN,
  553. FIELD_SEP_SPACE, FIELD_SEP_COMMA or FIELD_SEP_LINE.
  554. =cut
  555. sub field_get_sep_type($) {
  556. my $field = field_capitalize(shift);
  557. return $FIELDS{$field}{separator} if exists $FIELDS{$field}{separator};
  558. return FIELD_SEP_UNKNOWN;
  559. }
  560. =item field_register($field, $allowed_types, %opts)
  561. Register a new field as being allowed in control information of specified
  562. types. %opts is optional
  563. =cut
  564. sub field_register($$;@) {
  565. my ($field, $types, %opts) = @_;
  566. $field = field_capitalize($field);
  567. $FIELDS{$field} = {
  568. allowed => $types,
  569. %opts
  570. };
  571. }
  572. =item field_insert_after($type, $ref, @fields)
  573. Place field after another one ($ref) in output of control information of
  574. type $type.
  575. =cut
  576. sub field_insert_after($$@) {
  577. my ($type, $field, @fields) = @_;
  578. return 0 if not exists $FIELD_ORDER{$type};
  579. ($field, @fields) = map { field_capitalize($_) } ($field, @fields);
  580. @{$FIELD_ORDER{$type}} = map {
  581. ($_ eq $field) ? ($_, @fields) : $_
  582. } @{$FIELD_ORDER{$type}};
  583. return 1;
  584. }
  585. =item field_insert_before($type, $ref, @fields)
  586. Place field before another one ($ref) in output of control information of
  587. type $type.
  588. =cut
  589. sub field_insert_before($$@) {
  590. my ($type, $field, @fields) = @_;
  591. return 0 if not exists $FIELD_ORDER{$type};
  592. ($field, @fields) = map { field_capitalize($_) } ($field, @fields);
  593. @{$FIELD_ORDER{$type}} = map {
  594. ($_ eq $field) ? (@fields, $_) : $_
  595. } @{$FIELD_ORDER{$type}};
  596. return 1;
  597. }
  598. =back
  599. =head1 CHANGES
  600. =head2 Version 1.00 (dpkg 1.17.0)
  601. Mark the module as public.
  602. =head1 AUTHOR
  603. Raphaël Hertzog <hertzog@debian.org>.
  604. =cut
  605. 1;