]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/Here.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / base / Here.cc
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "base/Here.h"
11
12 #include <iostream>
13
14 /* File name hashing helpers */
15
16 // Build prefix is the file system path leading to Squid src/ source directory.
17 // It is "." for in-tree builds but may be lengthy and sensitive otherwise.
18
19 /// \returns the build prefix length or, if estimation is not possible, zero
20 static size_t
21 BuildPrefixLength()
22 {
23 // The hard-coded tail must be kept in sync with this file actual name!
24 const char *tail = "src/base/Here.cc";
25 const char *full = __FILE__;
26
27 // Disable heuristic if it does not work.
28 if (strstr(full, tail) == 0)
29 return 0;
30
31 return strlen(full) - strlen(tail);
32 }
33
34 /// \returns filename portion without the build prefix
35 static const char *
36 SkipBuildPrefix(const char* path)
37 {
38 static const size_t ToSkip = BuildPrefixLength();
39 return path + ToSkip;
40 }
41
42 /// quickly computes a (weak) hash of a file name
43 static SourceLocationId
44 FileNameHash(const char *path)
45 {
46 // Keep in sync with FileNameHash() in scripts/calc-must-ids.pl!
47
48 const char *name = strrchr(path, '/');
49 if (name)
50 ++name; // skip '/'
51 else
52 name = path;
53
54 uint32_t hash = 0;
55 uint32_t iterations = 0;
56 while (*name) {
57 ++iterations;
58 hash ^= 271 * static_cast<uint32_t>(*name);
59 ++name;
60 }
61 return hash ^ (iterations * 271);
62 }
63
64 /* SourceLocation */
65
66 SourceLocationId
67 SourceLocation::id() const
68 {
69 const auto fnameHashFull = fileNameHashCacher(fileName, &FileNameHash);
70 // 32 bits = 18 bits for the filename hash + 14 bits for the line number.
71 // Keep in sync with ComputeMustIds() in scripts/calc-must-ids.pl.
72 const auto fnameHash = fnameHashFull % 0x3FFFF;
73 return (fnameHash << 14) | (lineNo & 0x3FFF);
74 }
75
76 std::ostream &
77 SourceLocation::print(std::ostream &os) const
78 {
79 if (fileName) {
80 os << SkipBuildPrefix(fileName);
81
82 // TODO: Use more common and search-friendlier fileName:lineNo: format.
83 if (lineNo > 0)
84 os << '(' << lineNo << ')';
85 }
86 if (context) {
87 if (fileName)
88 os << ' ';
89 os << context;
90 }
91 return os;
92 }
93