]>
Commit | Line | Data |
---|---|---|
9c82357b | 1 | /* |
5e0de328 | 2 | * Copyright (C) 2009-2012 the libgit2 contributors |
9c82357b | 3 | * |
bb742ede VM |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
9c82357b CMN |
6 | */ |
7 | ||
92cb6aa9 CMN |
8 | #include "git2/errors.h" |
9 | ||
9c82357b CMN |
10 | #include "common.h" |
11 | #include "refspec.h" | |
63f91e1c | 12 | #include "util.h" |
3fbcac89 | 13 | #include "posix.h" |
9c82357b CMN |
14 | |
15 | int git_refspec_parse(git_refspec *refspec, const char *str) | |
16 | { | |
17 | char *delim; | |
18 | ||
19 | memset(refspec, 0x0, sizeof(git_refspec)); | |
20 | ||
21 | if (*str == '+') { | |
22 | refspec->force = 1; | |
23 | str++; | |
24 | } | |
25 | ||
26 | delim = strchr(str, ':'); | |
0ca7ca3e CMN |
27 | if (delim == NULL) { |
28 | refspec->src = git__strdup(str); | |
3aa351ea CMN |
29 | GITERR_CHECK_ALLOC(refspec->src); |
30 | return 0; | |
0ca7ca3e | 31 | } |
9c82357b CMN |
32 | |
33 | refspec->src = git__strndup(str, delim - str); | |
3aa351ea | 34 | GITERR_CHECK_ALLOC(refspec->src); |
9c82357b CMN |
35 | |
36 | refspec->dst = git__strdup(delim + 1); | |
37 | if (refspec->dst == NULL) { | |
3286c408 | 38 | git__free(refspec->src); |
9c82357b | 39 | refspec->src = NULL; |
3aa351ea | 40 | return -1; |
9c82357b CMN |
41 | } |
42 | ||
3aa351ea | 43 | return 0; |
9c82357b CMN |
44 | } |
45 | ||
46 | const char *git_refspec_src(const git_refspec *refspec) | |
47 | { | |
4a3b18a6 | 48 | return refspec == NULL ? NULL : refspec->src; |
9c82357b CMN |
49 | } |
50 | ||
51 | const char *git_refspec_dst(const git_refspec *refspec) | |
52 | { | |
4a3b18a6 | 53 | return refspec == NULL ? NULL : refspec->dst; |
9c82357b | 54 | } |
63f91e1c | 55 | |
3fbcac89 | 56 | int git_refspec_src_matches(const git_refspec *refspec, const char *refname) |
63f91e1c | 57 | { |
3fbcac89 VM |
58 | if (refspec == NULL || refspec->src == NULL) |
59 | return false; | |
60 | ||
61 | return (p_fnmatch(refspec->src, refname, 0) == 0); | |
63f91e1c | 62 | } |
92cb6aa9 | 63 | |
87d9869f | 64 | int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name) |
92cb6aa9 CMN |
65 | { |
66 | size_t baselen, namelen; | |
67 | ||
68 | baselen = strlen(spec->dst); | |
3aa351ea CMN |
69 | if (outlen <= baselen) { |
70 | giterr_set(GITERR_INVALID, "Reference name too long"); | |
904b67e6 | 71 | return GIT_EBUFS; |
3aa351ea | 72 | } |
92cb6aa9 CMN |
73 | |
74 | /* | |
75 | * No '*' at the end means that it's mapped to one specific local | |
76 | * branch, so no actual transformation is needed. | |
77 | */ | |
78 | if (spec->dst[baselen - 1] != '*') { | |
79 | memcpy(out, spec->dst, baselen + 1); /* include '\0' */ | |
3aa351ea | 80 | return 0; |
92cb6aa9 CMN |
81 | } |
82 | ||
83 | /* There's a '*' at the end, so remove its length */ | |
84 | baselen--; | |
85 | ||
86 | /* skip the prefix, -1 is for the '*' */ | |
87 | name += strlen(spec->src) - 1; | |
88 | ||
89 | namelen = strlen(name); | |
90 | ||
3aa351ea CMN |
91 | if (outlen <= baselen + namelen) { |
92 | giterr_set(GITERR_INVALID, "Reference name too long"); | |
904b67e6 | 93 | return GIT_EBUFS; |
3aa351ea | 94 | } |
92cb6aa9 CMN |
95 | |
96 | memcpy(out, spec->dst, baselen); | |
97 | memcpy(out + baselen, name, namelen + 1); | |
98 | ||
3aa351ea | 99 | return 0; |
92cb6aa9 | 100 | } |
97769280 RB |
101 | |
102 | int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name) | |
103 | { | |
3aa351ea CMN |
104 | if (git_buf_sets(out, spec->dst) < 0) |
105 | return -1; | |
97769280 RB |
106 | |
107 | /* | |
108 | * No '*' at the end means that it's mapped to one specific local | |
109 | * branch, so no actual transformation is needed. | |
110 | */ | |
fa6420f7 | 111 | if (git_buf_len(out) > 0 && out->ptr[git_buf_len(out) - 1] != '*') |
3aa351ea | 112 | return 0; |
97769280 | 113 | |
fa6420f7 | 114 | git_buf_truncate(out, git_buf_len(out) - 1); /* remove trailing '*' */ |
279afd2a | 115 | git_buf_puts(out, name + strlen(spec->src) - 1); |
97769280 | 116 | |
cb8a7961 | 117 | if (git_buf_oom(out)) |
3aa351ea | 118 | return -1; |
cb8a7961 VM |
119 | |
120 | return 0; | |
97769280 | 121 | } |
cb8a7961 | 122 |