File Coverage

File:Dpkg/Control/FieldsCore.pm
Coverage:64.8%

linestmtbrancondsubpodtimecode
1# Copyright © 2007-2009 Raphaël Hertzog <hertzog@debian.org>
2# Copyright © 2012-2024 Guillem Jover <guillem@debian.org>
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17=encoding utf8
18
19 - 29
=head1 NAME

Dpkg::Control::FieldsCore - manage (list of official) control fields

=head1 DESCRIPTION

The modules contains a list of field names with associated meta-data explaining
in which type of control information they are allowed. The types are the
CTRL_* constants exported by L<Dpkg::Control>.

=cut
30
31package Dpkg::Control::FieldsCore 1.02;
32
33
138
138
138
353
109
1998
use strict;
34
138
138
138
191
138
6016
use warnings;
35
36our @EXPORT = qw(
37    field_capitalize
38    field_is_official
39    field_is_allowed_in
40    field_transfer_single
41    field_transfer_all
42    field_parse_binary_source
43    field_list_src_dep
44    field_list_pkg_dep
45    field_get_dep_type
46    field_get_sep_type
47    field_ordered_list
48    field_register
49    field_insert_after
50    field_insert_before
51    FIELD_SEP_UNKNOWN
52    FIELD_SEP_SPACE
53    FIELD_SEP_COMMA
54    FIELD_SEP_LINE
55);
56
57
138
138
138
261
145
2254
use Exporter qw(import);
58
59
138
138
138
626
136
4078
use Dpkg::Gettext;
60
138
138
138
750
108
4398
use Dpkg::ErrorHandling;
61
138
138
138
17141
145
9124
use Dpkg::Control::Types;
62
63use constant {
64
138
5315
    ALL_PKG => CTRL_TMPL_PKG | CTRL_REPO_PKG | CTRL_DEB | CTRL_FILE_STATUS,
65    ALL_SRC => CTRL_TMPL_SRC | CTRL_REPO_SRC | CTRL_DSC,
66    ALL_FILE_MANIFEST => CTRL_FILE_BUILDINFO | CTRL_FILE_CHANGES,
67    ALL_CHANGES => CTRL_FILE_CHANGES | CTRL_CHANGELOG,
68    ALL_COPYRIGHT => CTRL_COPYRIGHT_HEADER | CTRL_COPYRIGHT_FILES | CTRL_COPYRIGHT_LICENSE,
69
138
138
302
106
};
70
71use constant {
72
138
230952
    FIELD_SEP_UNKNOWN => 0,
73    FIELD_SEP_SPACE => 1,
74    FIELD_SEP_COMMA => 2,
75    FIELD_SEP_LINE => 4,
76
138
138
274
104
};
77
78# The canonical list of fields.
79
80# Note that fields used only in dpkg's available file are not listed.
81# Deprecated fields of dpkg's status file are also not listed.
82our %FIELDS = (
83    'acquire-by-hash' => {
84        name => 'Acquire-By-Hash',
85        allowed => CTRL_REPO_RELEASE,
86    },
87    'architecture' => {
88        name => 'Architecture',
89        allowed => (ALL_PKG | ALL_SRC | ALL_FILE_MANIFEST | CTRL_TESTS) & (~CTRL_TMPL_SRC),
90        separator => FIELD_SEP_SPACE,
91    },
92    'architectures' => {
93        name => 'Architectures',
94        allowed => CTRL_REPO_RELEASE,
95        separator => FIELD_SEP_SPACE,
96    },
97    'auto-built-package' => {
98        name => 'Auto-Built-Package',
99        allowed => ALL_PKG & ~CTRL_TMPL_PKG,
100        separator => FIELD_SEP_SPACE,
101    },
102    'binary' => {
103        name => 'Binary',
104        allowed => CTRL_DSC | CTRL_REPO_SRC | ALL_FILE_MANIFEST,
105        # XXX: This field values are separated either by space or comma
106        # depending on the context.
107        separator => FIELD_SEP_SPACE | FIELD_SEP_COMMA,
108    },
109    'binary-only' => {
110        name => 'Binary-Only',
111        allowed => ALL_CHANGES,
112    },
113    'binary-only-changes' => {
114        name => 'Binary-Only-Changes',
115        allowed => CTRL_FILE_BUILDINFO,
116    },
117    'breaks' => {
118        name => 'Breaks',
119        allowed => ALL_PKG,
120        separator => FIELD_SEP_COMMA,
121        dependency => 'union',
122        dep_order => 7,
123    },
124    'bugs' => {
125        name => 'Bugs',
126        allowed => (ALL_PKG | CTRL_TMPL_SRC | CTRL_FILE_VENDOR) & (~CTRL_TMPL_PKG),
127    },
128    'build-architecture' => {
129        name => 'Build-Architecture',
130        allowed => CTRL_FILE_BUILDINFO,
131    },
132    'build-conflicts' => {
133        name => 'Build-Conflicts',
134        allowed => ALL_SRC,
135        separator => FIELD_SEP_COMMA,
136        dependency => 'union',
137        dep_order => 4,
138    },
139    'build-conflicts-arch' => {
140        name => 'Build-Conflicts-Arch',
141        allowed => ALL_SRC,
142        separator => FIELD_SEP_COMMA,
143        dependency => 'union',
144        dep_order => 5,
145    },
146    'build-conflicts-indep' => {
147        name => 'Build-Conflicts-Indep',
148        allowed => ALL_SRC,
149        separator => FIELD_SEP_COMMA,
150        dependency => 'union',
151        dep_order => 6,
152    },
153    'build-date' => {
154        name => 'Build-Date',
155        allowed => CTRL_FILE_BUILDINFO,
156    },
157    'build-depends' => {
158        name => 'Build-Depends',
159        allowed => ALL_SRC,
160        separator => FIELD_SEP_COMMA,
161        dependency => 'normal',
162        dep_order => 1,
163    },
164    'build-depends-arch' => {
165        name => 'Build-Depends-Arch',
166        allowed => ALL_SRC,
167        separator => FIELD_SEP_COMMA,
168        dependency => 'normal',
169        dep_order => 2,
170    },
171    'build-depends-indep' => {
172        name => 'Build-Depends-Indep',
173        allowed => ALL_SRC,
174        separator => FIELD_SEP_COMMA,
175        dependency => 'normal',
176        dep_order => 3,
177    },
178    'build-driver' => {
179        name => 'Build-Driver',
180        allowed => CTRL_TMPL_SRC,
181    },
182    'build-essential' => {
183        name => 'Build-Essential',
184        allowed => ALL_PKG,
185    },
186    'build-kernel-version' => {
187        name => 'Build-Kernel-Version',
188        allowed => CTRL_FILE_BUILDINFO,
189    },
190    'build-origin' => {
191        name => 'Build-Origin',
192        allowed => CTRL_FILE_BUILDINFO,
193    },
194    'build-path' => {
195        name => 'Build-Path',
196        allowed => CTRL_FILE_BUILDINFO,
197    },
198    'build-profiles' => {
199        name => 'Build-Profiles',
200        allowed => CTRL_TMPL_PKG,
201        separator => FIELD_SEP_SPACE,
202    },
203    'build-tainted-by' => {
204        name => 'Build-Tainted-By',
205        allowed => CTRL_FILE_BUILDINFO,
206        separator => FIELD_SEP_SPACE,
207    },
208    'built-for-profiles' => {
209        name => 'Built-For-Profiles',
210        allowed => ALL_PKG | CTRL_FILE_CHANGES,
211        separator => FIELD_SEP_SPACE,
212    },
213    'built-using' => {
214        name => 'Built-Using',
215        allowed => ALL_PKG,
216        separator => FIELD_SEP_COMMA,
217        dependency => 'union',
218        dep_order => 10,
219    },
220    'butautomaticupgrades' => {
221        name => 'ButAutomaticUpgrades',
222        allowed => CTRL_REPO_RELEASE,
223    },
224    'changed-by' => {
225        name => 'Changed-By',
226        allowed => CTRL_FILE_CHANGES,
227    },
228    'changelogs' => {
229        name => 'Changelogs',
230        allowed => CTRL_REPO_RELEASE,
231    },
232    'changes' => {
233        name => 'Changes',
234        allowed => ALL_CHANGES,
235    },
236    'checksums-md5' => {
237        name => 'Checksums-Md5',
238        allowed => CTRL_DSC | CTRL_REPO_SRC | ALL_FILE_MANIFEST,
239    },
240    'checksums-sha1' => {
241        name => 'Checksums-Sha1',
242        allowed => CTRL_DSC | CTRL_REPO_SRC | ALL_FILE_MANIFEST,
243    },
244    'checksums-sha256' => {
245        name => 'Checksums-Sha256',
246        allowed => CTRL_DSC | CTRL_REPO_SRC | ALL_FILE_MANIFEST,
247    },
248    'classes' => {
249        name => 'Classes',
250        allowed => CTRL_TESTS,
251        separator => FIELD_SEP_COMMA,
252    },
253    'closes' => {
254        name => 'Closes',
255        allowed => ALL_CHANGES,
256        separator => FIELD_SEP_SPACE,
257    },
258    'codename' => {
259        name => 'Codename',
260        allowed => CTRL_REPO_RELEASE,
261    },
262    'comment' => {
263        name => 'Comment',
264        allowed => ALL_COPYRIGHT,
265    },
266    'components' => {
267        name => 'Components',
268        allowed => CTRL_REPO_RELEASE,
269        separator => FIELD_SEP_SPACE,
270    },
271    'conffiles' => {
272        name => 'Conffiles',
273        allowed => CTRL_FILE_STATUS,
274        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
275    },
276    'config-version' => {
277        name => 'Config-Version',
278        allowed => CTRL_FILE_STATUS,
279    },
280    'conflicts' => {
281        name => 'Conflicts',
282        allowed => ALL_PKG,
283        separator => FIELD_SEP_COMMA,
284        dependency => 'union',
285        dep_order => 6,
286    },
287    'copyright' => {
288        name => 'Copyright',
289        allowed => CTRL_COPYRIGHT_HEADER | CTRL_COPYRIGHT_FILES,
290    },
291    'date' => {
292        name => 'Date',
293        allowed => ALL_CHANGES | CTRL_REPO_RELEASE,
294    },
295    'depends' => {
296        name => 'Depends',
297        allowed => ALL_PKG | CTRL_TESTS,
298        separator => FIELD_SEP_COMMA,
299        dependency => 'normal',
300        dep_order => 2,
301    },
302    'description' => {
303        name => 'Description',
304        allowed => ALL_SRC | ALL_PKG | CTRL_FILE_CHANGES | CTRL_REPO_RELEASE,
305    },
306    'disclaimer' => {
307        name => 'Disclaimer',
308        allowed => CTRL_COPYRIGHT_HEADER,
309    },
310    'directory' => {
311        name => 'Directory',
312        allowed => CTRL_REPO_SRC,
313    },
314    'distribution' => {
315        name => 'Distribution',
316        allowed => ALL_CHANGES,
317    },
318    'enhances' => {
319        name => 'Enhances',
320        allowed => ALL_PKG,
321        separator => FIELD_SEP_COMMA,
322        dependency => 'union',
323        dep_order => 5,
324    },
325    'environment' => {
326        name => 'Environment',
327        allowed => CTRL_FILE_BUILDINFO,
328        separator => FIELD_SEP_LINE,
329    },
330    'essential' => {
331        name => 'Essential',
332        allowed => ALL_PKG,
333    },
334    'features' => {
335        name => 'Features',
336        allowed => CTRL_TESTS,
337        separator => FIELD_SEP_SPACE,
338    },
339    'filename' => {
340        name => 'Filename',
341        allowed => CTRL_REPO_PKG,
342        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
343    },
344    'files' => {
345        name => 'Files',
346        allowed => CTRL_DSC | CTRL_REPO_SRC | CTRL_FILE_CHANGES | CTRL_COPYRIGHT_FILES,
347        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
348    },
349    'format' => {
350        name => 'Format',
351        allowed => CTRL_DSC | CTRL_REPO_SRC | ALL_FILE_MANIFEST | CTRL_COPYRIGHT_HEADER,
352    },
353    'homepage' => {
354        name => 'Homepage',
355        allowed => ALL_SRC | ALL_PKG,
356    },
357    'installed-build-depends' => {
358        name => 'Installed-Build-Depends',
359        allowed => CTRL_FILE_BUILDINFO,
360        separator => FIELD_SEP_COMMA,
361        dependency => 'union',
362        dep_order => 12,
363    },
364    'installed-size' => {
365        name => 'Installed-Size',
366        allowed => ALL_PKG & ~CTRL_TMPL_PKG,
367    },
368    'installer-menu-item' => {
369        name => 'Installer-Menu-Item',
370        allowed => ALL_PKG,
371    },
372    'kernel-version' => {
373        name => 'Kernel-Version',
374        allowed => ALL_PKG,
375    },
376    'label' => {
377        name => 'Label',
378        allowed => CTRL_REPO_RELEASE,
379    },
380    'license' => {
381        name => 'License',
382        allowed => ALL_COPYRIGHT,
383    },
384    'origin' => {
385        name => 'Origin',
386        allowed => (ALL_PKG | ALL_SRC | CTRL_REPO_RELEASE) & (~CTRL_TMPL_PKG),
387    },
388    'maintainer' => {
389        name => 'Maintainer',
390        allowed => CTRL_DEB | CTRL_REPO_PKG | CTRL_FILE_STATUS | ALL_SRC  | ALL_CHANGES,
391    },
392    'md5sum' => {
393        # XXX: Wrong capitalization due to historical reasons.
394        name => 'MD5sum',
395        allowed => CTRL_REPO_PKG | CTRL_REPO_RELEASE,
396        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
397    },
398    'multi-arch' => {
399        name => 'Multi-Arch',
400        allowed => ALL_PKG,
401    },
402    'no-support-for-architecture-all' => {
403        name => 'No-Support-for-Architecture-all',
404        allowed => CTRL_REPO_RELEASE,
405    },
406    'notautomatic' => {
407        name => 'NotAutomatic',
408        allowed => CTRL_REPO_RELEASE,
409    },
410    'package' => {
411        name => 'Package',
412        allowed => ALL_PKG | CTRL_REPO_SRC,
413    },
414    'package-list' => {
415        name => 'Package-List',
416        allowed => ALL_SRC & ~CTRL_TMPL_SRC,
417        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
418    },
419    'package-type' => {
420        name => 'Package-Type',
421        allowed => ALL_PKG,
422    },
423    'parent' => {
424        name => 'Parent',
425        allowed => CTRL_FILE_VENDOR,
426    },
427    'pre-depends' => {
428        name => 'Pre-Depends',
429        allowed => ALL_PKG,
430        separator => FIELD_SEP_COMMA,
431        dependency => 'normal',
432        dep_order => 1,
433    },
434    'priority' => {
435        name => 'Priority',
436        allowed => CTRL_TMPL_SRC | CTRL_REPO_SRC | ALL_PKG,
437    },
438    'protected' => {
439        name => 'Protected',
440        allowed => ALL_PKG,
441    },
442    'provides' => {
443        name => 'Provides',
444        allowed => ALL_PKG,
445        separator => FIELD_SEP_COMMA,
446        dependency => 'union',
447        dep_order => 9,
448    },
449    'recommends' => {
450        name => 'Recommends',
451        allowed => ALL_PKG,
452        separator => FIELD_SEP_COMMA,
453        dependency => 'normal',
454        dep_order => 3,
455    },
456    'replaces' => {
457        name => 'Replaces',
458        allowed => ALL_PKG,
459        separator => FIELD_SEP_COMMA,
460        dependency => 'union',
461        dep_order => 8,
462    },
463    'restrictions' => {
464        name => 'Restrictions',
465        allowed => CTRL_TESTS,
466        separator => FIELD_SEP_SPACE,
467    },
468    'rules-requires-root' => {
469        name => 'Rules-Requires-Root',
470        allowed => CTRL_TMPL_SRC,
471        separator => FIELD_SEP_SPACE,
472    },
473    'section' => {
474        name => 'Section',
475        allowed => CTRL_TMPL_SRC | CTRL_REPO_SRC | ALL_PKG,
476    },
477    'sha1' => {
478        # XXX: Wrong capitalization due to historical reasons.
479        name => 'SHA1',
480        allowed => CTRL_REPO_PKG | CTRL_REPO_RELEASE,
481        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
482    },
483    'sha256' => {
484        # XXX: Wrong capitalization due to historical reasons.
485        name => 'SHA256',
486        allowed => CTRL_REPO_PKG | CTRL_REPO_RELEASE,
487        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
488    },
489    'size' => {
490        name => 'Size',
491        allowed => CTRL_REPO_PKG,
492        separator => FIELD_SEP_LINE | FIELD_SEP_SPACE,
493    },
494    'source' => {
495        name => 'Source',
496        allowed => (ALL_PKG | ALL_SRC | ALL_CHANGES | CTRL_COPYRIGHT_HEADER | CTRL_FILE_BUILDINFO) &
497                   (~(CTRL_REPO_SRC | CTRL_TMPL_PKG)),
498    },
499    'standards-version' => {
500        name => 'Standards-Version',
501        allowed => ALL_SRC,
502    },
503    'static-built-using' => {
504        name => 'Static-Built-Using',
505        allowed => ALL_PKG,
506        separator => FIELD_SEP_COMMA,
507        dependency => 'union',
508        dep_order => 11,
509    },
510    'status' => {
511        name => 'Status',
512        allowed => CTRL_FILE_STATUS,
513        separator => FIELD_SEP_SPACE,
514    },
515    'subarchitecture' => {
516        name => 'Subarchitecture',
517        allowed => ALL_PKG,
518    },
519    'suite' => {
520        name => 'Suite',
521        allowed => CTRL_REPO_RELEASE,
522    },
523    'suggests' => {
524        name => 'Suggests',
525        allowed => ALL_PKG,
526        separator => FIELD_SEP_COMMA,
527        dependency => 'normal',
528        dep_order => 4,
529    },
530    'tag' => {
531        name => 'Tag',
532        allowed => ALL_PKG,
533        separator => FIELD_SEP_COMMA,
534    },
535    'task' => {
536        name => 'Task',
537        allowed => ALL_PKG,
538    },
539    'test-command' => {
540        name => 'Test-Command',
541        allowed => CTRL_TESTS,
542    },
543    'tests' => {
544        name => 'Tests',
545        allowed => CTRL_TESTS,
546        separator => FIELD_SEP_SPACE,
547    },
548    'tests-directory' => {
549        name => 'Tests-Directory',
550        allowed => CTRL_TESTS,
551    },
552    'testsuite' => {
553        name => 'Testsuite',
554        allowed => ALL_SRC,
555        separator => FIELD_SEP_COMMA,
556    },
557    'testsuite-triggers' => {
558        name => 'Testsuite-Triggers',
559        allowed => ALL_SRC,
560        separator => FIELD_SEP_COMMA,
561    },
562    'timestamp' => {
563        name => 'Timestamp',
564        allowed => CTRL_CHANGELOG,
565    },
566    'triggers-awaited' => {
567        name => 'Triggers-Awaited',
568        allowed => CTRL_FILE_STATUS,
569        separator => FIELD_SEP_SPACE,
570    },
571    'triggers-pending' => {
572        name => 'Triggers-Pending',
573        allowed => CTRL_FILE_STATUS,
574        separator => FIELD_SEP_SPACE,
575    },
576    'uploaders' => {
577        name => 'Uploaders',
578        allowed => ALL_SRC,
579        separator => FIELD_SEP_COMMA,
580    },
581    'upstream-name' => {
582        name => 'Upstream-Name',
583        allowed => CTRL_COPYRIGHT_HEADER,
584    },
585    'upstream-contact' => {
586        name => 'Upstream-Contact',
587        allowed => CTRL_COPYRIGHT_HEADER,
588    },
589    'urgency' => {
590        name => 'Urgency',
591        allowed => ALL_CHANGES,
592    },
593    'valid-until' => {
594        name => 'Valid-Until',
595        allowed => CTRL_REPO_RELEASE,
596    },
597    'vcs-browser' => {
598        name => 'Vcs-Browser',
599        allowed => ALL_SRC,
600    },
601    'vcs-arch' => {
602        name => 'Vcs-Arch',
603        allowed => ALL_SRC,
604    },
605    'vcs-bzr' => {
606        name => 'Vcs-Bzr',
607        allowed => ALL_SRC,
608    },
609    'vcs-cvs' => {
610        name => 'Vcs-Cvs',
611        allowed => ALL_SRC,
612    },
613    'vcs-darcs' => {
614        name => 'Vcs-Darcs',
615        allowed => ALL_SRC,
616    },
617    'vcs-git' => {
618        name => 'Vcs-Git',
619        allowed => ALL_SRC,
620    },
621    'vcs-hg' => {
622        name => 'Vcs-Hg',
623        allowed => ALL_SRC,
624    },
625    'vcs-mtn' => {
626        name => 'Vcs-Mtn',
627        allowed => ALL_SRC,
628    },
629    'vcs-svn' => {
630        name => 'Vcs-Svn',
631        allowed => ALL_SRC,
632    },
633    'vendor' => {
634        name => 'Vendor',
635        allowed => CTRL_FILE_VENDOR,
636    },
637    'vendor-url' => {
638        name => 'Vendor-Url',
639        allowed => CTRL_FILE_VENDOR,
640    },
641    'version' => {
642        name => 'Version',
643        allowed => (ALL_PKG | ALL_SRC | CTRL_FILE_BUILDINFO | ALL_CHANGES | CTRL_REPO_RELEASE) &
644                    (~(CTRL_TMPL_SRC | CTRL_TMPL_PKG)),
645    },
646);
647
648my @src_vcs_fields = qw(
649    vcs-browser
650    vcs-arch
651    vcs-bzr
652    vcs-cvs
653    vcs-darcs
654    vcs-git
655    vcs-hg
656    vcs-mtn
657    vcs-svn
658);
659
660my @src_dep_fields = qw(
661    build-depends
662    build-depends-arch
663    build-depends-indep
664    build-conflicts
665    build-conflicts-arch
666    build-conflicts-indep
667);
668my @bin_dep_fields = qw(
669    pre-depends
670    depends
671    recommends
672    suggests
673    enhances
674    conflicts
675    breaks
676    replaces
677    provides
678    built-using
679    static-built-using
680);
681
682my @src_test_fields = qw(
683    testsuite
684    testsuite-triggers
685);
686
687my @src_checksums_fields = qw(
688    checksums-md5
689    checksums-sha1
690    checksums-sha256
691);
692my @bin_checksums_fields = qw(
693    md5sum
694    sha1
695    sha256
696);
697
698our %FIELD_ORDER = (
699    CTRL_TMPL_SRC() => [
700        qw(
701            source
702            section
703            priority
704            maintainer
705            uploaders
706            origin
707            bugs
708        ),
709        @src_vcs_fields,
710        qw(
711            homepage
712            standards-version
713            rules-requires-root
714        ),
715        @src_dep_fields,
716        @src_test_fields,
717        qw(
718            description
719        ),
720    ],
721    CTRL_TMPL_PKG() => [
722        qw(
723            package
724            package-type
725            section
726            priority
727            architecture
728            subarchitecture
729            multi-arch
730            essential
731            protected
732            build-essential
733            build-profiles
734            built-for-profiles
735            kernel-version
736        ),
737        @bin_dep_fields,
738        qw(
739            homepage
740            installer-menu-item
741            task
742            tag
743            description
744        ),
745    ],
746    CTRL_DSC() => [
747        qw(
748            format
749            source
750            binary
751            architecture
752            version
753            origin
754            maintainer
755            uploaders
756            homepage
757            description
758            standards-version
759        ),
760        @src_vcs_fields,
761        @src_test_fields,
762        @src_dep_fields,
763        qw(
764            package-list
765        ),
766        @src_checksums_fields,
767        qw(
768            files
769        ),
770    ],
771    CTRL_DEB() => [
772        qw(
773            package
774            package-type
775            source
776            version
777            kernel-version
778            built-for-profiles
779            auto-built-package
780            architecture
781            subarchitecture
782            installer-menu-item
783            build-essential
784            essential
785            protected
786            origin
787            bugs
788            maintainer
789            installed-size
790        ),
791        @bin_dep_fields,
792        qw(
793            section
794            priority
795            multi-arch
796            homepage
797            description
798            tag
799            task
800        ),
801    ],
802    CTRL_REPO_SRC() => [
803        qw(
804            format
805            package
806            binary
807            architecture
808            version
809            priority
810            section
811            origin
812            maintainer
813            uploaders
814            homepage
815            description
816            standards-version
817        ),
818        @src_vcs_fields,
819        @src_test_fields,
820        @src_dep_fields,
821        qw(
822            package-list
823            directory
824        ),
825        @src_checksums_fields,
826        qw(
827            files
828        ),
829    ],
830    CTRL_REPO_PKG() => [
831        qw(
832            package
833            package-type
834            source
835            version
836            kernel-version
837            built-for-profiles
838            auto-built-package
839            architecture
840            subarchitecture
841            installer-menu-item
842            build-essential
843            essential
844            protected
845            origin
846            bugs
847            maintainer
848            installed-size
849        ),
850        @bin_dep_fields,
851        qw(
852            filename
853            size
854        ),
855        @bin_checksums_fields,
856        qw(
857            section
858            priority
859            multi-arch
860            homepage
861            description
862            tag
863            task
864        ),
865    ],
866    CTRL_REPO_RELEASE() => [
867        qw(
868            origin
869            label
870            suite
871            version
872            codename
873            changelogs
874            date
875            valid-until
876            notautomatic
877            butautomaticupgrades
878            acquire-by-hash
879            no-support-for-architecture-all
880            architectures
881            components
882            description
883        ),
884        @bin_checksums_fields
885    ],
886    CTRL_CHANGELOG() => [
887        qw(
888            source
889            binary-only
890            version
891            distribution
892            urgency
893            maintainer
894            timestamp
895            date
896            closes
897            changes
898        ),
899    ],
900    CTRL_COPYRIGHT_HEADER() => [
901        qw(
902            format
903            upstream-name
904            upstream-contact
905            source
906            disclaimer
907            comment
908            license
909            copyright
910        ),
911    ],
912    CTRL_COPYRIGHT_FILES() => [
913        qw(
914            files
915            copyright
916            license
917            comment
918        ),
919    ],
920    CTRL_COPYRIGHT_LICENSE() => [
921        qw(
922            license
923            comment
924        ),
925    ],
926    CTRL_FILE_BUILDINFO() => [
927        qw(
928            format
929            source
930            binary
931            architecture
932            version
933            binary-only-changes
934        ),
935        @src_checksums_fields,
936        qw(
937            build-origin
938            build-architecture
939            build-kernel-version
940            build-date
941            build-path
942            build-tainted-by
943            installed-build-depends
944            environment
945        ),
946    ],
947    CTRL_FILE_CHANGES() => [
948        qw(
949            format
950            date
951            source
952            binary
953            binary-only
954            built-for-profiles
955            architecture
956            version
957            distribution
958            urgency
959            maintainer
960            changed-by
961            description
962            closes
963            changes
964        ),
965        @src_checksums_fields,
966        qw(
967            files
968        ),
969    ],
970    CTRL_FILE_VENDOR() => [
971        qw(
972            vendor
973            vendor-url
974            bugs
975            parent
976        ),
977    ],
978    CTRL_FILE_STATUS() => [
979        # Same as fieldinfos in lib/dpkg/parse.c
980        qw(
981            package
982            essential
983            protected
984            status
985            priority
986            section
987            installed-size
988            origin
989            maintainer
990            bugs
991            architecture
992            multi-arch
993            source
994            version
995            config-version
996            replaces
997            provides
998            depends
999            pre-depends
1000            recommends
1001            suggests
1002            breaks
1003            conflicts
1004            enhances
1005            conffiles
1006            description
1007            triggers-pending
1008            triggers-awaited
1009        ),
1010        # These are allowed here, but not tracked by lib/dpkg/parse.c.
1011        qw(
1012            auto-built-package
1013            build-essential
1014            built-for-profiles
1015            built-using
1016            static-built-using
1017            homepage
1018            installer-menu-item
1019            kernel-version
1020            package-type
1021            subarchitecture
1022            tag
1023            task
1024        ),
1025    ],
1026    CTRL_TESTS() => [
1027        qw(
1028            test-command
1029            tests
1030            tests-directory
1031            architecture
1032            restrictions
1033            features
1034            classes
1035            depends
1036        ),
1037    ],
1038);
1039
1040 - 1049
=head1 FUNCTIONS

=over 4

=item $f = field_capitalize($field_name)

Returns the field name properly capitalized. All characters are lowercase,
except the first of each word (words are separated by a hyphen in field names).

=cut
1050
1051sub field_capitalize($) {
1052
18150
1
13615
    my $field = lc(shift);
1053
1054    # Use known fields first.
1055
18150
30762
    return $FIELDS{$field}{name} if exists $FIELDS{$field};
1056
1057    # Generic case
1058
192
408
308
743
    return join '-', map { ucfirst } split /-/, $field;
1059}
1060
1061 - 1065
=item $bool = field_is_official($fname)

Returns true if the field is official and known.

=cut
1066
1067sub field_is_official($) {
1068
1056
1
1215
    my $field = lc shift;
1069
1070
1056
2384
    return exists $FIELDS{$field};
1071}
1072
1073 - 1084
=item $bool = field_is_allowed_in($fname, @types)

Returns true (1) if the field $fname is allowed in all the types listed in
the list. Note that you can use type sets instead of individual types (ex:
CTRL_FILE_CHANGES | CTRL_CHANGELOG).

field_allowed_in(A|B, C) returns true only if the field is allowed in C
and either A or B.

Undef is returned for non-official fields.

=cut
1085
1086sub field_is_allowed_in($@) {
1087
7404
1
8030
    my ($field, @types) = @_;
1088
7404
6545
    $field = lc $field;
1089
1090
7404
9471
    return unless exists $FIELDS{$field};
1091
1092
7338
6878
    return 0 if not scalar(@types);
1093
7338
6099
    foreach my $type (@types) {
1094
8352
8773
        next if $type == CTRL_UNKNOWN; # Always allowed
1095
8352
16223
        return 0 unless $FIELDS{$field}{allowed} & $type;
1096    }
1097
2211
3525
    return 1;
1098}
1099
1100 - 1118
=item $new_field = field_transfer_single($from, $to, $field)

If appropriate, copy the value of the field named $field taken from the
$from L<Dpkg::Control> object to the $to L<Dpkg::Control> object.

Official fields are copied only if the field is allowed in both types of
objects. Custom fields are treated in a specific manner. When the target
is not among CTRL_DSC, CTRL_DEB or CTRL_FILE_CHANGES, then they
are always copied as is (the X- prefix is kept). Otherwise they are not
copied except if the target object matches the target destination encoded
in the field name. The initial X denoting custom fields can be followed by
one or more letters among "S" (Source: corresponds to CTRL_DSC), "B"
(Binary: corresponds to CTRL_DEB) or "C" (Changes: corresponds to
CTRL_FILE_CHANGES).

Returns undef if nothing has been copied or the name of the new field
added to $to otherwise.

=cut
1119
1120sub field_transfer_single($$;$) {
1121
1080
1
1163
    my ($from, $to, $field) = @_;
1122
1080
1433
    if (not defined $field) {
1123
0
0
        warnings::warnif('deprecated',
1124            'using Dpkg::Control::Fields::field_transfer_single() with an ' .
1125            'an implicit field argument is deprecated');
1126
0
0
        $field = $_;
1127    }
1128
1080
1724
    my ($from_type, $to_type) = ($from->get_type(), $to->get_type());
1129
1080
1327
    $field = field_capitalize($field);
1130
1131
1080
1310
    if (field_is_allowed_in($field, $from_type, $to_type)) {
1132
1014
1093
        $to->{$field} = $from->{$field};
1133
1014
1871
        return $field;
1134    } elsif ($field =~ /^X([SBC]*)-/i) {
1135
66
105
        my $dest = $1;
1136
66
774
        if (($dest =~ /B/i and $to_type == CTRL_DEB) or
1137            ($dest =~ /S/i and $to_type == CTRL_DSC) or
1138            ($dest =~ /C/i and $to_type == CTRL_FILE_CHANGES))
1139        {
1140
0
0
            my $new = $field;
1141
0
0
            $new =~ s/^X([SBC]*)-//i;
1142
0
0
            $to->{$new} = $from->{$field};
1143
0
0
            return $new;
1144        } elsif ($to_type != CTRL_DEB and
1145                 $to_type != CTRL_DSC and
1146                 $to_type != CTRL_FILE_CHANGES)
1147        {
1148
66
93
            $to->{$field} = $from->{$field};
1149
66
183
            return $field;
1150        }
1151    } elsif (not field_is_allowed_in($field, $from_type)) {
1152
0
0
        warning(g_("unknown information field '%s' in input data in %s"),
1153                $field, $from->get_option('name') || g_('control information'));
1154    }
1155
0
0
    return;
1156}
1157
1158 - 1165
=item @field_list = field_transfer_all($from, $to)

Transfer all appropriate fields from $from to $to. Calls
field_transfer_single() on all fields available in $from.

Returns the list of fields that have been added to $to.

=cut
1166
1167sub field_transfer_all($$) {
1168
0
1
0
    my ($from, $to) = @_;
1169
0
0
    my (@res, $res);
1170
0
0
    foreach my $k (keys %$from) {
1171
0
0
        $res = field_transfer_single($from, $to, $k);
1172
0
0
        push @res, $res if $res and defined wantarray;
1173    }
1174
0
0
    return @res;
1175}
1176
1177 - 1183
=item @field_list = field_ordered_list($type)

Returns an ordered list of fields for a given type of control information.
This list can be used to output the fields in a predictable order.
The list might be empty for types where the order does not matter much.

=cut
1184
1185sub field_ordered_list($) {
1186
2655
1
2031
    my $type = shift;
1187
1188
2655
3240
    if (exists $FIELD_ORDER{$type}) {
1189
2655
30408
2655
1986
31980
3400
        return map { $FIELDS{$_}{name} } @{$FIELD_ORDER{$type}};
1190    }
1191
0
0
    return ();
1192}
1193
1194 - 1206
=item ($source, $version) = field_parse_binary_source($ctrl)

Parse the B<Source> field in a binary package control stanza. The field
contains the source package name where it was built from, and optionally
a space and the source version enclosed in parenthesis if it is different
from the binary version.

Returns a list with the $source name, and the source $version, or undef
or an empty list when $ctrl does not contain a binary package control stanza.
Neither $source nor $version are validated, but that can be done with
Dpkg::Package::pkg_name_is_illegal() and Dpkg::Version::version_check().

=cut
1207
1208sub field_parse_binary_source($) {
1209
9
1
10
    my $ctrl = shift;
1210
9
13
    my $ctrl_type = $ctrl->get_type();
1211
1212
9
33
    if ($ctrl_type != CTRL_REPO_PKG and
1213        $ctrl_type != CTRL_DEB and
1214        $ctrl_type != CTRL_FILE_CHANGES and
1215        $ctrl_type != CTRL_FILE_BUILDINFO and
1216        $ctrl_type != CTRL_FILE_STATUS) {
1217
0
0
        return;
1218    }
1219
1220
9
8
    my ($source, $version);
1221
1222    # For .changes and .buildinfo the Source field always exists,
1223    # and there is no Package field.
1224
9
9
    if (exists $ctrl->{'Source'}) {
1225
6
6
        $source = $ctrl->{'Source'};
1226
6
23
        if ($source =~ m/^([^ ]+) +\(([^)]*)\)$/) {
1227
3
8
            $source = $1;
1228
3
4
            $version = $2;
1229        } else {
1230
3
6
            $version = $ctrl->{'Version'};
1231        }
1232    } else {
1233
3
3
        $source = $ctrl->{'Package'};
1234
3
3
        $version = $ctrl->{'Version'};
1235    }
1236
1237
9
18
    return ($source, $version);
1238}
1239
1240 - 1245
=item @field_list = field_list_src_dep()

List of fields that contains dependencies-like information in a source
Debian package.

=cut
1246
1247sub field_list_src_dep() {
1248    my @list = map {
1249        $FIELDS{$_}{name}
1250
18
18
    } sort {
1251        $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
1252
30
25
    } grep {
1253
3
1
26
        field_is_allowed_in($_, CTRL_DSC) and
1254        exists $FIELDS{$_}{dependency}
1255
354
216
    } keys %FIELDS;
1256
3
20
    return @list;
1257}
1258
1259 - 1265
=item @field_list = field_list_pkg_dep()

List of fields that contains dependencies-like information in a binary
Debian package. The fields that express real dependencies are sorted from
the stronger to the weaker.

=cut
1266
1267sub field_list_pkg_dep() {
1268    my @list = map {
1269        $FIELDS{$_}{name}
1270
33
27
    } sort {
1271        $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
1272
80
56
    } grep {
1273
3
1
17
        field_is_allowed_in($_, CTRL_DEB) and
1274        exists $FIELDS{$_}{dependency}
1275
354
224
    } keys %FIELDS;
1276
3
21
    return @list;
1277}
1278
1279 - 1286
=item $dep_type = field_get_dep_type($field)

Return the type of the dependency expressed by the given field. Can
either be "normal" for a real dependency field (Pre-Depends, Depends, ...)
or "union" for other relation fields sharing the same syntax (Conflicts,
Breaks, ...). Returns undef for fields which are not dependencies.

=cut
1287
1288sub field_get_dep_type($) {
1289
0
1
0
    my $field = lc shift;
1290
1291
0
0
    return unless exists $FIELDS{$field};
1292
0
0
    return $FIELDS{$field}{dependency} if exists $FIELDS{$field}{dependency};
1293
0
0
    return;
1294}
1295
1296 - 1301
=item $sep_type = field_get_sep_type($field)

Return the type of the field value separator. Can be one of FIELD_SEP_UNKNOWN,
FIELD_SEP_SPACE, FIELD_SEP_COMMA or FIELD_SEP_LINE.

=cut
1302
1303sub field_get_sep_type($) {
1304
0
1
0
    my $field = lc shift;
1305
1306
0
0
    return $FIELDS{$field}{separator} if exists $FIELDS{$field}{separator};
1307
0
0
    return FIELD_SEP_UNKNOWN;
1308}
1309
1310 - 1315
=item field_register($field, $allowed_types, %opts)

Register a new field as being allowed in control information of specified
types. %opts is optional.

=cut
1316
1317sub field_register($$;@) {
1318
3
1
3
    my ($field, $types, %opts) = @_;
1319
1320
3
4
    $field = lc $field;
1321
3
4
    $FIELDS{$field} = {
1322        name => field_capitalize($field),
1323        allowed => $types,
1324        %opts
1325    };
1326
1327
3
7
    return;
1328}
1329
1330 - 1337
=item $bool = field_insert_after($type, $ref, @fields)

Place field after another one ($ref) in output of control information of
type $type.

Return true if the field was inserted, otherwise false.

=cut
1338
1339sub field_insert_after($$@) {
1340
6
1
7
    my ($type, $field, @fields) = @_;
1341
1342
6
6
    return 0 if not exists $FIELD_ORDER{$type};
1343
1344
6
12
6
11
    ($field, @fields) = map { lc } ($field, @fields);
1345
6
8
    @{$FIELD_ORDER{$type}} = map {
1346
87
63
        ($_ eq $field) ? ($_, @fields) : $_
1347
6
6
3
5
    } @{$FIELD_ORDER{$type}};
1348
1349
6
8
    return 1;
1350}
1351
1352 - 1359
=item $bool = field_insert_before($type, $ref, @fields)

Place field before another one ($ref) in output of control information of
type $type.

Return true if the field was inserted, otherwise false.

=cut
1360
1361sub field_insert_before($$@) {
1362
0
1
    my ($type, $field, @fields) = @_;
1363
1364
0
    return 0 if not exists $FIELD_ORDER{$type};
1365
1366
0
0
    ($field, @fields) = map { lc } ($field, @fields);
1367
0
    @{$FIELD_ORDER{$type}} = map {
1368
0
        ($_ eq $field) ? (@fields, $_) : $_
1369
0
0
    } @{$FIELD_ORDER{$type}};
1370
1371
0
    return 1;
1372}
1373
1374=back
1375
1376 - 1390
=head1 CHANGES

=head2 Version 1.02 (dpkg 1.22.0)

Deprecate argument: field_transfer_single() implicit argument usage.

=head2 Version 1.01 (dpkg 1.21.0)

New function: field_parse_binary_source().

=head2 Version 1.00 (dpkg 1.17.0)

Mark the module as public.

=cut
1391
13921;