GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/publish/command.cc
Date: 2026-09-27 02:40:09
Exec Total Coverage
Lines: 0 72 0.0%
Branches: 0 132 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5
6 #include "publish/command.h"
7
8 #include <getopt.h>
9
10 #include <cassert>
11 #include <cstdlib>
12 #include <cstring>
13
14 #include "publish/except.h"
15 #include "util/logging.h"
16 #include "util/smalloc.h"
17 #include "util/string.h"
18
19 using namespace std; // NOLINT
20
21 namespace publish {
22
23 ✗ std::string Command::GetExamples() const {
24 ✗ std::vector<std::string> examples = DoGetExamples();
25 ✗ std::string result;
26 ✗ for (unsigned i = 0; i < examples.size(); ++i) {
27 ✗ result += progname() + " " + GetName() + " " + examples[i] + "\n";
28 }
29 ✗ return result;
30 }
31
32
33 ✗ Command::Options Command::ParseOptions(int argc, char **argv) {
34 ✗ Options result;
35 ✗ progname_ = argv[0];
36 ✗ ParameterList params = GetParams();
37
38 ✗ string shortopts;
39 struct option *longopts = reinterpret_cast<option *>(
40 ✗ smalloc((params.size() + 1) * sizeof(struct option)));
41 struct option lastopt;
42 ✗ memset(&lastopt, 0, sizeof(lastopt));
43 ✗ longopts[params.size()] = lastopt;
44
45 ✗ for (unsigned i = 0; i < params.size(); ++i) {
46 ✗ shortopts.push_back(params[i].short_key);
47 ✗ if (!params[i].is_switch)
48 ✗ shortopts.push_back(':');
49
50 ✗ longopts[i].name = strdup(params[i].key.c_str());
51 ✗ longopts[i].has_arg = params[i].is_switch ? no_argument : required_argument;
52 ✗ longopts[i].flag = NULL;
53 ✗ longopts[i].val = params[i].short_key;
54 }
55
56 int idx;
57 int c;
58 ✗ opterr = 0; // Don't print error messages in getopt
59 ✗ optind = 2; // Skip the command itself
60 ✗ while ((c = getopt_long(argc, argv, shortopts.c_str(), longopts, &idx))
61 ✗ != -1) {
62 ✗ bool found = false;
63 ✗ for (unsigned i = 0; i < params.size(); ++i) {
64 ✗ if (c == params[i].short_key) {
65 ✗ Argument argument;
66 ✗ if (!params[i].is_switch) {
67 ✗ argument.value_str = optarg;
68 ✗ argument.value_int = String2Int64(argument.value_str);
69 }
70 ✗ result.Set(params[i], argument);
71 ✗ found = true;
72 ✗ break;
73 }
74 }
75
76 ✗ if (!found) {
77 ✗ assert(c == '?');
78 // Easier to duplicate the next few lines than to add an RAII wrapper
79 ✗ for (unsigned i = 0; i < params.size(); ++i) {
80 ✗ free(const_cast<char *>(longopts[i].name));
81 }
82 ✗ free(longopts);
83
84 ✗ throw EPublish(
85 ✗ GetName() + ": unrecognized parameter '" + argv[optind - 1] + "'",
86 ✗ EPublish::kFailInvocation);
87 }
88 }
89
90 ✗ for (unsigned i = 0; i < params.size(); ++i) {
91 ✗ free(const_cast<char *>(longopts[i].name));
92 }
93 ✗ free(longopts);
94
95 ✗ for (unsigned i = 0; i < params.size(); ++i) {
96 ✗ if (!params[i].is_optional && !result.Has(params[i].key)) {
97 ✗ throw EPublish(
98 ✗ GetName() + ": missing mandatory parameter '" + params[i].key + "'",
99 ✗ EPublish::kFailInvocation);
100 }
101 }
102
103 ✗ for (int i = optind; i < argc; ++i) {
104 ✗ result.AppendPlain(Argument(argv[i]));
105 }
106
107 ✗ if (result.plain_args().size() < GetMinPlainArgs()) {
108 ✗ LogCvmfs(kLogCvmfs, kLogStderr, "Usage: %s %s %s", progname().c_str(),
109 ✗ GetName().c_str(), GetUsage().c_str());
110 ✗ throw EPublish(GetName() + ": missing argument", EPublish::kFailInvocation);
111 }
112
113 ✗ return result;
114 }
115
116
117 //------------------------------------------------------------------------------
118
119
120 ✗ CommandList::~CommandList() {
121 ✗ for (unsigned i = 0; i < commands_.size(); ++i)
122 ✗ delete commands_[i];
123 }
124
125 ✗ Command *CommandList::Find(const std::string &name) {
126 ✗ Command *result = NULL;
127 ✗ for (unsigned i = 0; i < commands_.size(); ++i) {
128 ✗ if (commands_[i]->GetName() == name) {
129 ✗ result = commands_[i];
130 ✗ break;
131 }
132 }
133 ✗ return result;
134 }
135
136 ✗ void CommandList::TakeCommand(Command *command) {
137 ✗ assert(Find(command->GetName()) == NULL);
138 ✗ commands_.push_back(command);
139 }
140
141 } // namespace publish
142