]> git.sesse.net Git - plocate/blob - lib.cpp
Release plocate 1.1.7.
[plocate] / lib.cpp
1 /* Common functions.
2
3 Copyright (C) 2005, 2007 Red Hat, Inc. All rights reserved.
4 This copyrighted material is made available to anyone wishing to use, modify,
5 copy, or redistribute it subject to the terms and conditions of the GNU General
6 Public License v.2.
7
8 This program is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 PARTICULAR PURPOSE. See the GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License along with
13 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
14 Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
16 Author: Miloslav Trmac <mitr@redhat.com>
17
18 plocate modifications: Copyright (C) 2020 Steinar H. Gunderson.
19 plocate parts and modifications are licensed under the GPLv2 or, at your option,
20 any later version.
21 */
22
23 #include "lib.h"
24
25 #include "db.h"
26 #include "error.h"
27
28 #include <algorithm>
29 #include <arpa/inet.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 using namespace std;
41
42 /* Compare two path names using the database directory order. This is not
43    exactly strcmp () order: "a" < "a.b", so "a/z" < "a.b". */
44 int dir_path_cmp(const string &a, const string &b)
45 {
46         auto [ai, bi] = mismatch(a.begin(), a.end(), b.begin(), b.end());
47         if (ai == a.end() && bi == b.end()) {
48                 return 0;
49         }
50         if (ai == a.end()) {
51                 return -1;
52         }
53         if (bi == b.end()) {
54                 return 1;
55         }
56         if (*ai == *bi) {
57                 return 0;
58         }
59         if (*ai == '/') {
60                 return -1;
61         }
62         if (*bi == '/') {
63                 return 1;
64         }
65         return int((unsigned char)*ai) - int((unsigned char)*bi);
66 }
67
68 /* Sort LIST using dir_path_cmp () */
69 void string_list_dir_path_sort(vector<string> *list)
70 {
71         sort(list->begin(), list->end(), [](const string &a, const string &b) {
72                 return dir_path_cmp(a, b) < 0;
73         });
74 }
75
76 /* Is PATH included in LIST?  Update *IDX to move within LIST.
77
78    LIST is assumed to be sorted using dir_path_cmp (), successive calls to this
79    function are assumed to use PATH values increasing in dir_path_cmp (). */
80 bool string_list_contains_dir_path(const vector<string> *list, size_t *idx,
81                                    const string &path)
82 {
83         int cmp = 0;
84         while (*idx < list->size() && (cmp = dir_path_cmp((*list)[*idx], path)) < 0) {
85                 (*idx)++;
86         }
87         if (*idx < list->size() && cmp == 0) {
88                 (*idx)++;
89                 return true;
90         }
91         return false;
92 }