ACAV f0ba4b7c9529
Abstract Syntax Tree (AST) visualization tool for C, C++, and Objective-C
Loading...
Searching...
No Matches
FileManager.cpp
1/*$!{
2* Aurora Clang AST Viewer (ACAV)
3*
4* Copyright (c) 2026 Min Liu
5* Copyright (c) 2026 Michael David Adams
6*
7* SPDX-License-Identifier: GPL-2.0-or-later
8*
9* This program is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation; either version 2 of the License, or
12* (at your option) any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License along
20* with this program; if not, see <https://www.gnu.org/licenses/>.
21}$!*/
22
23#include "common/FileManager.h"
24#include <filesystem>
25#include <stdexcept>
26
27namespace acav {
28
29FileID FileManager::registerFile(std::string_view filePath) {
30 std::lock_guard<std::mutex> lock(mutex_);
31
32 // Normalize the path first
33 std::string normalizedPath = normalizePath(filePath);
34
35 // Check if already registered
36 auto it = pathToId_.find(normalizedPath);
37 if (it != pathToId_.end()) {
38 // File already registered, increment ref count and return existing ID
39 FileID id = it->second;
40 files_[id - 1].refCount++;
41 return id;
42 }
43
44 // New file - create record
45 FileRecord record;
46 record.path = std::move(normalizedPath);
47 record.refCount = 1;
48
49 // Assign FileID (starting from 1, since 0 is reserved for invalid)
50 FileID newId = files_.size() + 1;
51
52 // Store record and update mapping
53 files_.push_back(std::move(record));
54 pathToId_[files_.back().path] = newId;
55
56 return newId;
57}
58
59std::optional<FileID> FileManager::tryGetFileId(std::string_view filePath) const {
60 std::lock_guard<std::mutex> lock(mutex_);
61
62 // Normalize path for lookup
63 std::string normalizedPath = normalizePath(filePath);
64
65 auto it = pathToId_.find(normalizedPath);
66 if (it != pathToId_.end()) {
67 return it->second;
68 }
69
70 return std::nullopt;
71}
72
73std::string_view FileManager::getFilePath(FileID id) const {
74 std::lock_guard<std::mutex> lock(mutex_);
75
76 if (!isValidFileId(id)) {
77 static const std::string empty;
78 return empty;
79 }
80
81 return files_[id - 1].path;
82}
83
84std::size_t FileManager::getRefCount(FileID id) const {
85 std::lock_guard<std::mutex> lock(mutex_);
86
87 if (!isValidFileId(id)) {
88 return 0;
89 }
90
91 return files_[id - 1].refCount;
92}
93
95 std::lock_guard<std::mutex> lock(mutex_);
96 return files_.size();
97}
98
100 // Note: mutex should already be held by caller
101 return id != InvalidFileID && id <= files_.size();
102}
103
104std::string FileManager::normalizePath(std::string_view filePath) const {
105 try {
106 // Convert to filesystem path
107 std::filesystem::path fsPath(filePath);
108
109 // Get canonical path (resolves symlinks, relative paths, etc.)
110 // If file doesn't exist, use absolute path instead
111 std::filesystem::path canonicalPath;
112
113 if (std::filesystem::exists(fsPath)) {
114 canonicalPath = std::filesystem::canonical(fsPath);
115 } else {
116 // File doesn't exist yet, just make it absolute
117 canonicalPath = std::filesystem::absolute(fsPath);
118 // Normalize by removing . and .. components
119 canonicalPath = canonicalPath.lexically_normal();
120 }
121
122 return canonicalPath.string();
123 } catch (const std::filesystem::filesystem_error &e) {
124 // If filesystem operations fail, fall back to making the path absolute
125 try {
126 std::filesystem::path fsPath(filePath);
127 return std::filesystem::absolute(fsPath).lexically_normal().string();
128 } catch (...) {
129 // Last resort: return as-is
130 return std::string(filePath);
131 }
132 }
133}
134
135} // namespace acav
Centralized file registry with path-to-FileID mapping.
std::size_t FileID
Type-safe identifier for registered files. 0 is reserved for invalid.
Definition FileManager.h:38
static constexpr FileID InvalidFileID
Reserved invalid FileID.
Definition FileManager.h:47
FileID registerFile(std::string_view filePath)
Register a file and return its FileID.
std::size_t getRefCount(FileID id) const
Get reference count for a file.
std::string_view getFilePath(FileID id) const
Get the canonical path for a FileID.
std::size_t getRegisteredFileCount() const
Get total number of registered files.
bool isValidFileId(FileID id) const
Check if a FileID is valid.
std::optional< FileID > tryGetFileId(std::string_view filePath) const
Look up FileID for a path without registering.