Yet Another eXchange Tool 0.11.1
Loading...
Searching...
No Matches
xt_idxmod.c
Go to the documentation of this file.
1
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
63 struct Xt_modifier *modifier,
64 int modifier_num, int *mstate) {
65 // ensure that yaxt is initialized
66 assert(xt_initialized());
67
68 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 if (modifier_num<1) return xt_idxlist_copy(patch_idxlist);
72
73 Xt_int *workpatch_idx = xmalloc((size_t)patch_size * sizeof(Xt_int));
74 Xt_int const* inter_idx;
75 int *workpatch_pos = xmalloc((size_t)patch_size * sizeof(int));
76 int *extract_pos = xmalloc((size_t)patch_size * sizeof(int));
77 Xt_int *subst_idx = xmalloc((size_t)patch_size * sizeof(Xt_int));
78
79 Xt_idxlist workpatch_idxlist = patch_idxlist;
80
81 xt_idxlist_get_indices(workpatch_idxlist, workpatch_idx);
82
83 for (int im = 0; im < modifier_num; im++) {
84 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 = xt_idxlist_get_intersection(m->extract,workpatch_idxlist);
91
92 // get intersection index array => inter_idx:
93 int intersection_size = xt_idxlist_get_num_indices(intersection_idxlist);
94 if (intersection_size > patch_size) die("xt_idxmod_new: internal error: (intersection_size > patch_size)");
95 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 int missing = xt_idxlist_get_positions_of_indices(m->extract, inter_idx,
101 intersection_size,
102 extract_pos, 0);
103 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 missing = xt_idxlist_get_positions_of_indices(workpatch_idxlist, inter_idx,
109 intersection_size,
110 workpatch_pos, 1);
111
112 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 int undef_num = xt_idxlist_get_indices_at_positions(m->subst, extract_pos,
117 intersection_size,
118 subst_idx, 0);
119 if (undef_num) die("xt_idxmod_new: internal error: failed access: m->subst is too small");
120
121 // delete workpatch_idxlist
122 if (im > 0) {
123 xt_idxlist_delete(workpatch_idxlist);
124 }
125
126 // substitude indices within workpatch_idx
127 int p;
128 int mask = m->mask;
129 if ( mstate != NULL && mask != 0) {
130 // we also update the modification state
131 for (int i=0; i<intersection_size; i++) {
132 p = workpatch_pos[i];
133 workpatch_idx[p] = subst_idx[i];
134 mstate[p] |= mask;
135 }
136 } else {
137 for (int i=0; i<intersection_size; i++) {
138 p = workpatch_pos[i];
139 workpatch_idx[p] = subst_idx[i];
140 }
141 }
142 workpatch_idxlist = xt_idxvec_new(workpatch_idx, patch_size);
143
144 xt_idxlist_delete(intersection_idxlist);
145 }
146
147 free(subst_idx);
148 free(extract_pos);
149 free(workpatch_pos);
150 free(workpatch_idx);
151
152 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 */
#define die(msg)
Definition core.h:131
add versions of standard API functions not returning on error
#define xmalloc(size)
Definition ppm_xfuncs.h:70
Xt_idxlist extract
idx values
Definition xt_idxmod.h:69
Xt_idxlist subst
Definition xt_idxmod.h:70
base definitions header file
int xt_initialized(void)
XT_INT Xt_int
Definition xt_core.h:72
index list declaration
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int single_match_only)
Definition xt_idxlist.c:221
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
Definition xt_idxlist.c:119
void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Definition xt_idxlist.c:113
int xt_idxlist_get_indices_at_positions(Xt_idxlist idxlist, const int *positions, int num_pos, Xt_int *indices, Xt_int undef_idx)
Definition xt_idxlist.c:183
Xt_idxlist xt_idxlist_get_intersection(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
Xt_idxlist xt_idxlist_copy(Xt_idxlist idxlist)
Definition xt_idxlist.c:94
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition xt_idxlist.c:75
Provide non-public declarations common to all index lists.
#define xt_idxlist_get_num_indices(idxlist)
Xt_idxlist xt_idxmod_new(Xt_idxlist patch_idxlist, struct Xt_modifier *modifier, int modifier_num, int *mstate)
generates a new index list based on an index list and a sequence of modifiers
Definition xt_idxmod.c:62
Xt_idxlist xt_idxvec_new(const Xt_int *idxlist, int num_indices)
Definition xt_idxvec.c:212