]> git.saurik.com Git - apt.git/blame - cmdline/apt-sortpkgs.cc
The entire concept of PendingError() is flawed :/.
[apt.git] / cmdline / apt-sortpkgs.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
8f312f45 3// $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
b2e465d6
AL
4/* ######################################################################
5
6 APT Sort Packages - Program to sort Package and Source files
7
8 This program is quite simple, it just sorts the package files by
9 package and sorts the fields inside by the internal APT sort order.
10 Input is taken from a named file and sent to stdout.
11
12 ##################################################################### */
13 /*}}}*/
14// Include Files /*{{{*/
ea542140
DK
15#include <config.h>
16
b2e465d6
AL
17#include <apt-pkg/tagfile.h>
18#include <apt-pkg/error.h>
19#include <apt-pkg/configuration.h>
20#include <apt-pkg/cmndline.h>
21#include <apt-pkg/init.h>
22#include <apt-pkg/strutl.h>
472ff00e
DK
23#include <apt-pkg/fileutl.h>
24#include <apt-pkg/pkgsystem.h>
b2e465d6 25
ad7e0941 26#include <apt-private/private-cmndline.h>
e7e10e47 27#include <apt-private/private-main.h>
ad7e0941 28
b2e465d6
AL
29#include <vector>
30#include <algorithm>
453b82a3 31#include <stdio.h>
24a59c62 32#include <unistd.h>
453b82a3
DK
33#include <iostream>
34#include <string>
7414af7f 35#include <memory>
ea542140
DK
36
37#include <apti18n.h>
b2e465d6
AL
38 /*}}}*/
39
8f312f45
AL
40using namespace std;
41
92fcbfc1 42struct PkgName /*{{{*/
b2e465d6
AL
43{
44 string Name;
45 string Ver;
46 string Arch;
47 unsigned long Offset;
48 unsigned long Length;
49
50 inline int Compare3(const PkgName &x) const
51 {
52 int A = stringcasecmp(Name,x.Name);
53 if (A == 0)
54 {
55 A = stringcasecmp(Ver,x.Ver);
56 if (A == 0)
57 A = stringcasecmp(Arch,x.Arch);
58 }
59 return A;
60 }
61
62 bool operator <(const PkgName &x) const {return Compare3(x) < 0;};
63 bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
64 bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
65};
92fcbfc1 66 /*}}}*/
b2e465d6
AL
67// DoIt - Sort a single file /*{{{*/
68// ---------------------------------------------------------------------
69/* */
c3ccac92 70static bool DoIt(string InFile)
b2e465d6
AL
71{
72 FileFd Fd(InFile,FileFd::ReadOnly);
73 pkgTagFile Tags(&Fd);
74 if (_error->PendingError() == true)
75 return false;
76
77 // Parse.
78 vector<PkgName> List;
79 pkgTagSection Section;
80 unsigned long Largest = 0;
81 unsigned long Offset = Tags.Offset();
82 bool Source = _config->FindB("APT::SortPkgs::Source",false);
83 while (Tags.Step(Section) == true)
84 {
85 PkgName Tmp;
86
87 /* Fetch the name, auto-detecting if this is a source file or a
88 package file */
89 Tmp.Name = Section.FindS("Package");
90 Tmp.Ver = Section.FindS("Version");
91 Tmp.Arch = Section.FindS("Architecture");
92
93 if (Tmp.Name.empty() == true)
94 return _error->Error(_("Unknown package record!"));
95
96 Tmp.Offset = Offset;
97 Tmp.Length = Section.size();
98 if (Largest < Tmp.Length)
99 Largest = Tmp.Length;
100
101 List.push_back(Tmp);
102
103 Offset = Tags.Offset();
104 }
105 if (_error->PendingError() == true)
106 return false;
107
108 // Sort it
109 sort(List.begin(),List.end());
110
111 const char **Order = TFRewritePackageOrder;
112 if (Source == true)
113 Order = TFRewriteSourceOrder;
88593886 114
b2e465d6 115 // Emit
88593886
DK
116 FileFd stdoutfd;
117 stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
7414af7f 118 auto const Buffer = std::unique_ptr<unsigned char[]>(new unsigned char[Largest+1]);
91c03d37 119 for (vector<PkgName>::iterator I = List.begin(); I != List.end(); ++I)
b2e465d6
AL
120 {
121 // Read in the Record.
7414af7f 122 if (Fd.Seek(I->Offset) == false || Fd.Read(Buffer.get(),I->Length) == false)
b2e465d6 123 return false;
88593886
DK
124
125 Buffer[I->Length] = '\n';
7414af7f 126 if (Section.Scan((char *)Buffer.get(),I->Length+1) == false)
b2e465d6 127 return _error->Error("Internal error, failed to scan buffer");
b2e465d6
AL
128
129 // Sort the section
88593886 130 if (Section.Write(stdoutfd, Order) == false || stdoutfd.Write("\n", 1) == false)
b2e465d6 131 return _error->Error("Internal error, failed to sort fields");
b2e465d6 132 }
b2e465d6
AL
133 return true;
134}
135 /*}}}*/
f6777222 136static bool ShowHelp(CommandLine &) /*{{{*/
b2e465d6 137{
41d39345 138 std::cout <<
b2e465d6
AL
139 _("Usage: apt-sortpkgs [options] file1 [file2 ...]\n"
140 "\n"
8561c2fe 141 "apt-sortpkgs is a simple tool to sort package information files.\n"
d04e44ac 142 "By default it sorts by binary package information, but the -s option\n"
8561c2fe 143 "can be used to switch to source package ordering instead.\n");
ad7e0941 144 return true;
b2e465d6
AL
145}
146 /*}}}*/
f6777222 147static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
011188e3
DK
148{
149 return {
150 {nullptr, nullptr, nullptr}
151 };
152}
153 /*}}}*/
92fcbfc1 154int main(int argc,const char *argv[]) /*{{{*/
b2e465d6 155{
ad7e0941 156 CommandLine CmdL;
90986d4d 157 ParseCommandLine(CmdL, APT_CMD::APT_SORTPKG, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
b2e465d6
AL
158
159 // Match the operation
160 for (unsigned int I = 0; I != CmdL.FileSize(); I++)
161 if (DoIt(CmdL.FileList[I]) == false)
162 break;
e7e10e47 163
011188e3 164 return DispatchCommandLine(CmdL, {});
b2e465d6 165}
92fcbfc1 166 /*}}}*/