File Coverage

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

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

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

=head1 DESCRIPTION

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

=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
1044
1045sub field_capitalize($) {
1046
6018
1
3775
    my $field = lc(shift);
1047
1048    # Use known fields first.
1049
6018
7392
    return $FIELDS{$field}{name} if exists $FIELDS{$field};
1050
1051    # Generic case
1052
64
136
68
173
    return join '-', map { ucfirst } split /-/, $field;
1053}
1054
1055 - 1059
=item $bool = field_is_official($fname)

Returns true if the field is official and known.

=cut
1060
1061sub field_is_official($) {
1062
352
1
297
    my $field = lc shift;
1063
1064
352
500
    return exists $FIELDS{$field};
1065}
1066
1067 - 1078
=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
1079
1080sub field_is_allowed_in($@) {
1081
2466
1
1883
    my ($field, @types) = @_;
1082
2466
1642
    $field = lc $field;
1083
1084
2466
2181
    return unless exists $FIELDS{$field};
1085
1086
2444
1800
    return 0 if not scalar(@types);
1087
2444
1435
    foreach my $type (@types) {
1088
2782
2148
        next if $type == CTRL_UNKNOWN; # Always allowed
1089
2782
3739
        return 0 unless $FIELDS{$field}{allowed} & $type;
1090    }
1091
737
802
    return 1;
1092}
1093
1094 - 1112
=item $new_field = field_transfer_single($from, $to, $field)

If appropriate, copy the value of the field named $field taken from the
$from Dpkg::Control object to the $to 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_PKG_SRC, CTRL_PKG_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_PKG_SRC), "B"
(Binary: corresponds to CTRL_PKG_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
1113
1114sub field_transfer_single($$;$) {
1115
360
1
286
    my ($from, $to, $field) = @_;
1116
360
714
    $field //= $_;
1117
360
326
    my ($from_type, $to_type) = ($from->get_type(), $to->get_type());
1118
360
302
    $field = field_capitalize($field);
1119
1120
360
274
    if (field_is_allowed_in($field, $from_type, $to_type)) {
1121
338
249
        $to->{$field} = $from->{$field};
1122
338
456
        return $field;
1123    } elsif ($field =~ /^X([SBC]*)-/i) {
1124
22
22
        my $dest = $1;
1125
22
136
        if (($dest =~ /B/i and $to_type == CTRL_PKG_DEB) or
1126            ($dest =~ /S/i and $to_type == CTRL_PKG_SRC) or
1127            ($dest =~ /C/i and $to_type == CTRL_FILE_CHANGES))
1128        {
1129
0
0
            my $new = $field;
1130
0
0
            $new =~ s/^X([SBC]*)-//i;
1131
0
0
            $to->{$new} = $from->{$field};
1132
0
0
            return $new;
1133        } elsif ($to_type != CTRL_PKG_DEB and
1134                 $to_type != CTRL_PKG_SRC and
1135                 $to_type != CTRL_FILE_CHANGES)
1136        {
1137
22
18
            $to->{$field} = $from->{$field};
1138
22
37
            return $field;
1139        }
1140    } elsif (not field_is_allowed_in($field, $from_type)) {
1141
0
0
        warning(g_("unknown information field '%s' in input data in %s"),
1142                $field, $from->get_option('name') || g_('control information'));
1143    }
1144
0
0
    return;
1145}
1146
1147 - 1154
=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
1155
1156sub field_transfer_all($$) {
1157
0
1
0
    my ($from, $to) = @_;
1158
0
0
    my (@res, $res);
1159
0
0
    foreach my $k (keys %$from) {
1160
0
0
        $res = field_transfer_single($from, $to, $k);
1161
0
0
        push @res, $res if $res and defined wantarray;
1162    }
1163
0
0
    return @res;
1164}
1165
1166 - 1172
=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
1173
1174sub field_ordered_list($) {
1175
864
1
500
    my $type = shift;
1176
1177
864
717
    if (exists $FIELD_ORDER{$type}) {
1178
864
9534
864
456
7121
742
        return map { $FIELDS{$_}{name} } @{$FIELD_ORDER{$type}};
1179    }
1180
0
0
    return ();
1181}
1182
1183 - 1195
=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
1196
1197sub field_parse_binary_source($) {
1198
3
1
2
    my $ctrl = shift;
1199
3
3
    my $ctrl_type = $ctrl->get_type();
1200
1201
3
14
    if ($ctrl_type != CTRL_INDEX_PKG and
1202        $ctrl_type != CTRL_PKG_DEB and
1203        $ctrl_type != CTRL_FILE_CHANGES and
1204        $ctrl_type != CTRL_FILE_BUILDINFO and
1205        $ctrl_type != CTRL_FILE_STATUS) {
1206
0
0
        return;
1207    }
1208
1209
3
1
    my ($source, $version);
1210
1211    # For .changes and .buildinfo the Source field always exists,
1212    # and there is no Package field.
1213
3
3
    if (exists $ctrl->{'Source'}) {
1214
2
2
        $source = $ctrl->{'Source'};
1215
2
7
        if ($source =~ m/^([^ ]+) +\(([^)]*)\)$/) {
1216
1
1
            $source = $1;
1217
1
1
            $version = $2;
1218        } else {
1219
1
1
            $version = $ctrl->{'Version'};
1220        }
1221    } else {
1222
1
1
        $source = $ctrl->{'Package'};
1223
1
1
        $version = $ctrl->{'Version'};
1224    }
1225
1226
3
5
    return ($source, $version);
1227}
1228
1229 - 1234
=item @field_list = field_list_src_dep()

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

=cut
1235
1236sub field_list_src_dep() {
1237    my @list = map {
1238        $FIELDS{$_}{name}
1239
6
5
    } sort {
1240        $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
1241
11
9
    } grep {
1242
1
1
10
        field_is_allowed_in($_, CTRL_PKG_SRC) and
1243        exists $FIELDS{$_}{dependency}
1244
117
70
    } keys %FIELDS;
1245
1
6
    return @list;
1246}
1247
1248 - 1254
=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
1255
1256sub field_list_pkg_dep() {
1257    my @list = map {
1258        $FIELDS{$_}{name}
1259
11
10
    } sort {
1260        $FIELDS{$a}{dep_order} <=> $FIELDS{$b}{dep_order}
1261
29
20
    } grep {
1262
1
1
7
        field_is_allowed_in($_, CTRL_PKG_DEB) and
1263        exists $FIELDS{$_}{dependency}
1264
117
92
    } keys %FIELDS;
1265
1
7
    return @list;
1266}
1267
1268 - 1275
=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
1276
1277sub field_get_dep_type($) {
1278
0
1
0
    my $field = lc shift;
1279
1280
0
0
    return unless exists $FIELDS{$field};
1281
0
0
    return $FIELDS{$field}{dependency} if exists $FIELDS{$field}{dependency};
1282
0
0
    return;
1283}
1284
1285 - 1290
=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
1291
1292sub field_get_sep_type($) {
1293
0
1
0
    my $field = lc shift;
1294
1295
0
0
    return $FIELDS{$field}{separator} if exists $FIELDS{$field}{separator};
1296
0
0
    return FIELD_SEP_UNKNOWN;
1297}
1298
1299 - 1304
=item field_register($field, $allowed_types, %opts)

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

=cut
1305
1306sub field_register($$;@) {
1307
1
1
1
    my ($field, $types, %opts) = @_;
1308
1309
1
1
    $field = lc $field;
1310
1
1
    $FIELDS{$field} = {
1311        name => field_capitalize($field),
1312        allowed => $types,
1313        %opts
1314    };
1315
1316
1
1
    return;
1317}
1318
1319 - 1326
=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
1327
1328sub field_insert_after($$@) {
1329
2
1
8
    my ($type, $field, @fields) = @_;
1330
1331
2
2
    return 0 if not exists $FIELD_ORDER{$type};
1332
1333
2
4
1
4
    ($field, @fields) = map { lc } ($field, @fields);
1334
2
1
    @{$FIELD_ORDER{$type}} = map {
1335
29
20
        ($_ eq $field) ? ($_, @fields) : $_
1336
2
2
0
2
    } @{$FIELD_ORDER{$type}};
1337
1338
2
3
    return 1;
1339}
1340
1341 - 1348
=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
1349
1350sub field_insert_before($$@) {
1351
0
1
    my ($type, $field, @fields) = @_;
1352
1353
0
    return 0 if not exists $FIELD_ORDER{$type};
1354
1355
0
0
    ($field, @fields) = map { lc } ($field, @fields);
1356
0
    @{$FIELD_ORDER{$type}} = map {
1357
0
        ($_ eq $field) ? (@fields, $_) : $_
1358
0
0
    } @{$FIELD_ORDER{$type}};
1359
1360
0
    return 1;
1361}
1362
1363=back
1364
1365 - 1375
=head1 CHANGES

=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
1376
13771;