Directory: | src/ |
---|---|
File: | src/xt_idxmod.c |
Date: | 2024-11-08 09:02:52 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 40 | 40 | 100.0% |
Branches: | 17 | 24 | 70.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file xt_idxmod.c | ||
3 | * | ||
4 | * @copyright Copyright (C) 2016 Jörg Behrens <behrens@dkrz.de> | ||
5 | * Moritz Hanke <hanke@dkrz.de> | ||
6 | * Thomas Jahns <jahns@dkrz.de> | ||
7 | * | ||
8 | * @author Jörg Behrens <behrens@dkrz.de> | ||
9 | * Moritz Hanke <hanke@dkrz.de> | ||
10 | * Thomas Jahns <jahns@dkrz.de> | ||
11 | */ | ||
12 | /* | ||
13 | * Keywords: | ||
14 | * Maintainer: Jörg Behrens <behrens@dkrz.de> | ||
15 | * Moritz Hanke <hanke@dkrz.de> | ||
16 | * Thomas Jahns <jahns@dkrz.de> | ||
17 | * URL: https://dkrz-sw.gitlab-pages.dkrz.de/yaxt/ | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions are | ||
21 | * met: | ||
22 | * | ||
23 | * Redistributions of source code must retain the above copyright notice, | ||
24 | * this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in the | ||
28 | * documentation and/or other materials provided with the distribution. | ||
29 | * | ||
30 | * Neither the name of the DKRZ GmbH nor the names of its contributors | ||
31 | * may be used to endorse or promote products derived from this software | ||
32 | * without specific prior written permission. | ||
33 | * | ||
34 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
35 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
36 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
37 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
38 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
39 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
40 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
41 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
42 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
43 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
44 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
45 | */ | ||
46 | #ifdef HAVE_CONFIG_H | ||
47 | #include <config.h> | ||
48 | #endif | ||
49 | |||
50 | #include <assert.h> | ||
51 | |||
52 | #include "xt/xt_core.h" | ||
53 | #include "core/core.h" | ||
54 | #include "core/ppm_xfuncs.h" | ||
55 | #include "xt/xt_idxlist.h" | ||
56 | #include "xt_idxlist_internal.h" | ||
57 | #include "xt/xt_idxvec.h" | ||
58 | |||
59 | #include "xt/xt_idxmod.h" | ||
60 | |||
61 | |||
62 | 9 | Xt_idxlist xt_idxmod_new(Xt_idxlist patch_idxlist, | |
63 | struct Xt_modifier *modifier, | ||
64 | int modifier_num, int *mstate) { | ||
65 | // ensure that yaxt is initialized | ||
66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | assert(xt_initialized()); |
67 | |||
68 | 9 | int patch_size = xt_idxlist_get_num_indices(patch_idxlist); | |
69 | |||
70 | // if there is no modifier then we just give back a copy of the original: | ||
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (modifier_num<1) return xt_idxlist_copy(patch_idxlist); |
72 | |||
73 | 9 | Xt_int *workpatch_idx = xmalloc((size_t)patch_size * sizeof(Xt_int)); | |
74 | Xt_int const* inter_idx; | ||
75 | 9 | int *workpatch_pos = xmalloc((size_t)patch_size * sizeof(int)); | |
76 | 9 | int *extract_pos = xmalloc((size_t)patch_size * sizeof(int)); | |
77 | 9 | Xt_int *subst_idx = xmalloc((size_t)patch_size * sizeof(Xt_int)); | |
78 | |||
79 | 9 | Xt_idxlist workpatch_idxlist = patch_idxlist; | |
80 | |||
81 | 9 | xt_idxlist_get_indices(workpatch_idxlist, workpatch_idx); | |
82 | |||
83 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 9 times.
|
24 | for (int im = 0; im < modifier_num; im++) { |
84 | 15 | struct Xt_modifier *m = &modifier[im]; | |
85 | |||
86 | // intersection between extract values and workpatch: | ||
87 | // any multiplicity of workpatch must be repeated in the intersection therefore | ||
88 | // workpatch must have the target role | ||
89 | Xt_idxlist intersection_idxlist | ||
90 | 15 | = xt_idxlist_get_intersection(m->extract,workpatch_idxlist); | |
91 | |||
92 | // get intersection index array => inter_idx: | ||
93 | 15 | int intersection_size = xt_idxlist_get_num_indices(intersection_idxlist); | |
94 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (intersection_size > patch_size) die("xt_idxmod_new: internal error: (intersection_size > patch_size)"); |
95 | 15 | inter_idx = xt_idxlist_get_indices_const(intersection_idxlist); | |
96 | |||
97 | // get the intersection positions within the extract list | ||
98 | // m->extract has source role, therefore single_match_only = 0 | ||
99 | // => extract_pos | ||
100 | 15 | int missing = xt_idxlist_get_positions_of_indices(m->extract, inter_idx, | |
101 | intersection_size, | ||
102 | extract_pos, 0); | ||
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (missing) die("xt_idxmod_new: internal error: cannot locate all intersection positions (1)"); |
104 | |||
105 | // get the intersection positions within workpatch | ||
106 | // we must find each fitting index, so single_match_only = 1 | ||
107 | // => workpatch_pos | ||
108 | 15 | missing = xt_idxlist_get_positions_of_indices(workpatch_idxlist, inter_idx, | |
109 | intersection_size, | ||
110 | workpatch_pos, 1); | ||
111 | |||
112 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (missing) die("xt_idxmod_new: internal error: cannot locate all intersection positions (2)"); |
113 | |||
114 | // using the positions above, select indices within m->subst: | ||
115 | // it is an error if we cannot access all positions, so the value of undef_idx does not matter (set to 0) | ||
116 | 15 | int undef_num = xt_idxlist_get_indices_at_positions(m->subst, extract_pos, | |
117 | intersection_size, | ||
118 | subst_idx, 0); | ||
119 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (undef_num) die("xt_idxmod_new: internal error: failed access: m->subst is too small"); |
120 | |||
121 | // delete workpatch_idxlist | ||
122 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
|
15 | if (im > 0) { |
123 | 6 | xt_idxlist_delete(workpatch_idxlist); | |
124 | } | ||
125 | |||
126 | // substitude indices within workpatch_idx | ||
127 | int p; | ||
128 | 15 | int mask = m->mask; | |
129 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
15 | if ( mstate != NULL && mask != 0) { |
130 | // we also update the modification state | ||
131 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 12 times.
|
80 | for (int i=0; i<intersection_size; i++) { |
132 | 68 | p = workpatch_pos[i]; | |
133 | 68 | workpatch_idx[p] = subst_idx[i]; | |
134 | 68 | mstate[p] |= mask; | |
135 | } | ||
136 | } else { | ||
137 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 3 times.
|
49 | for (int i=0; i<intersection_size; i++) { |
138 | 46 | p = workpatch_pos[i]; | |
139 | 46 | workpatch_idx[p] = subst_idx[i]; | |
140 | } | ||
141 | } | ||
142 | 15 | workpatch_idxlist = xt_idxvec_new(workpatch_idx, patch_size); | |
143 | |||
144 | 15 | xt_idxlist_delete(intersection_idxlist); | |
145 | } | ||
146 | |||
147 | 9 | free(subst_idx); | |
148 | 9 | free(extract_pos); | |
149 | 9 | free(workpatch_pos); | |
150 | 9 | free(workpatch_idx); | |
151 | |||
152 | 9 | return workpatch_idxlist; | |
153 | } | ||
154 | |||
155 | /* | ||
156 | * Local Variables: | ||
157 | * c-basic-offset: 2 | ||
158 | * coding: utf-8 | ||
159 | * indent-tabs-mode: nil | ||
160 | * show-trailing-whitespace: t | ||
161 | * require-trailing-newline: t | ||
162 | * End: | ||
163 | */ | ||
164 |