KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kigit_driver_registry.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
26
27#include <git2.h>
28#include <git2/sys/merge.h>
29
30#include <trace_helpers.h>
31
32#include <wx/log.h>
33
34#include <cstdint>
35#include <map>
36#include <memory>
37#include <mutex>
38#include <string>
39
40
41namespace KIGIT
42{
43
44namespace
45{
46
47struct KICAD_DRIVER
48{
49 git_merge_driver base;
50 std::string name; // owns the c-string libgit2 borrows
51 MERGE_APPLY_FN apply;
52};
53
54
55std::mutex g_registryMutex;
56std::map<std::string, MERGE_APPLY_FN> g_appliers;
57std::map<std::string, std::unique_ptr<KICAD_DRIVER>> g_drivers;
58
59int trampolineApply( git_merge_driver* aSelf, const char** aPathOut, uint32_t* aModeOut,
60 git_buf* aMergedOut, const char* /*aFilterName*/,
61 const git_merge_driver_source* aSrc )
62{
63 KICAD_DRIVER* driver = reinterpret_cast<KICAD_DRIVER*>( aSelf );
64
65 if( !driver || !driver->apply )
66 return -1;
67
68 unsigned int mode = 0;
69 int rc = driver->apply( aSrc, aPathOut, &mode, aMergedOut );
70
71 if( aModeOut )
72 *aModeOut = mode;
73
74 return rc;
75}
76
77} // namespace
78
79
80bool RegisterMergeDriver( const char* aName, MERGE_APPLY_FN aApply )
81{
82 if( !aName || !aApply )
83 return false;
84
85 std::lock_guard<std::mutex> lock( g_registryMutex );
86
87 std::string name( aName );
88
89 if( g_appliers.count( name ) )
90 return true; // already registered — idempotent
91
92 auto driver = std::make_unique<KICAD_DRIVER>();
93 driver->base.version = GIT_MERGE_DRIVER_VERSION;
94 driver->base.initialize = nullptr;
95 driver->base.shutdown = nullptr;
96 driver->base.apply = trampolineApply;
97 driver->name = name;
98 driver->apply = aApply;
99
100 int rc = git_merge_driver_register( driver->name.c_str(),
101 reinterpret_cast<git_merge_driver*>( driver.get() ) );
102
103 if( rc != 0 )
104 {
105 wxLogTrace( traceGit, "git_merge_driver_register('%s') failed: %s",
107 return false;
108 }
109
110 g_appliers[name] = aApply;
111 g_drivers[name] = std::move( driver ); // owns the full KICAD_DRIVER
112
113 return true;
114}
115
116} // namespace KIGIT
const char * name
static wxString GetLastGitError()
const wxChar *const traceGit
Flag to enable Git debugging output.
int(*)(const git_merge_driver_source *src, const char ** path_out, unsigned int * mode_out, git_buf * merged_out) MERGE_APPLY_FN
Signature for a KiCad merge-driver apply function.
bool RegisterMergeDriver(const char *aName, MERGE_APPLY_FN aApply)
Register a KiCad merge driver with libgit2.
wxLogTrace helper definitions.