Yet Another eXchange Tool  0.9.0
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://doc.redmine.dkrz.de/yaxt/html/
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/xt_idxvec.h"
57 
58 #include "xt/xt_idxmod.h"
59 
60 
62  struct Xt_modifier *modifier,
63  int modifier_num, int *mstate) {
64  // ensure that yaxt is initialized
65  assert(xt_initialized());
66 
67  int patch_size = xt_idxlist_get_num_indices(patch_idxlist);
68 
69  // if there is no modifier then we just give back a copy of the original:
70  if (modifier_num<1) return xt_idxlist_copy(patch_idxlist);
71 
72  Xt_int *workpatch_idx = xmalloc((size_t)patch_size * sizeof(Xt_int));
73  Xt_int const* inter_idx;
74  int *workpatch_pos = xmalloc((size_t)patch_size * sizeof(int));
75  int *extract_pos = xmalloc((size_t)patch_size * sizeof(int));
76  Xt_int *subst_idx = xmalloc((size_t)patch_size * sizeof(Xt_int));
77 
78  Xt_idxlist workpatch_idxlist = patch_idxlist;
79 
80  xt_idxlist_get_indices(workpatch_idxlist, workpatch_idx);
81 
82  for (int im = 0; im < modifier_num; im++) {
83  struct Xt_modifier *m = &modifier[im];
84 
85  // intersection between extract values and workpatch:
86  // any multiplicity of workpatch must be repeated in the intersection therefore
87  // workpatch must have the target role
88  Xt_idxlist intersection_idxlist
89  = xt_idxlist_get_intersection(m->extract,workpatch_idxlist);
90 
91  // get intersection index array => inter_idx:
92  int intersection_size = xt_idxlist_get_num_indices(intersection_idxlist);
93  if (intersection_size > patch_size) die("xt_idxmod_new: internal error: (intersection_size > patch_size)");
94  inter_idx = xt_idxlist_get_indices_const(intersection_idxlist);
95 
96  // get the intersection positions within the extract list
97  // m->extract has source role, therefore single_match_only = 0
98  // => extract_pos
99  int missing = xt_idxlist_get_positions_of_indices(m->extract, inter_idx,
100  intersection_size,
101  extract_pos, 0);
102  if (missing) die("xt_idxmod_new: internal error: cannot locate all intersection positions (1)");
103 
104  // get the intersection positions within workpatch
105  // we must find each fitting index, so single_match_only = 1
106  // => workpatch_pos
107  missing = xt_idxlist_get_positions_of_indices(workpatch_idxlist, inter_idx,
108  intersection_size,
109  workpatch_pos, 1);
110 
111  if (missing) die("xt_idxmod_new: internal error: cannot locate all intersection positions (2)");
112 
113  // using the positions above, select indices within m->subst:
114  // it is an error if we cannot access all positions, so the value of undef_idx does not matter (set to 0)
115  int undef_num = xt_idxlist_get_indices_at_positions(m->subst, extract_pos,
116  intersection_size,
117  subst_idx, 0);
118  if (undef_num) die("xt_idxmod_new: internal error: failed access: m->subst is too small");
119 
120  // delete workpatch_idxlist
121  if (im > 0) {
122  xt_idxlist_delete(workpatch_idxlist);
123  }
124 
125  // substitude indices within workpatch_idx
126  int p;
127  int mask = m->mask;
128  if ( mstate != NULL && mask != 0) {
129  // we also update the modification state
130  for (int i=0; i<intersection_size; i++) {
131  p = workpatch_pos[i];
132  workpatch_idx[p] = subst_idx[i];
133  mstate[p] |= mask;
134  }
135  } else {
136  for (int i=0; i<intersection_size; i++) {
137  p = workpatch_pos[i];
138  workpatch_idx[p] = subst_idx[i];
139  }
140  }
141  workpatch_idxlist = xt_idxvec_new(workpatch_idx, patch_size);
142 
143  xt_idxlist_delete(intersection_idxlist);
144  }
145 
146  free(subst_idx);
147  free(extract_pos);
148  free(workpatch_pos);
149  free(workpatch_idx);
150 
151  return workpatch_idxlist;
152 }
153 
154 /*
155  * Local Variables:
156  * c-basic-offset: 2
157  * coding: utf-8
158  * indent-tabs-mode: nil
159  * show-trailing-whitespace: t
160  * require-trailing-newline: t
161  * End:
162  */
#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)
Definition: xt_init.c:107
XT_INT Xt_int
Definition: xt_core.h:68
index list declaration
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
Definition: xt_idxlist.c:98
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:203
void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Definition: xt_idxlist.c:102
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:165
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:93
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
Definition: xt_idxlist.c:108
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition: xt_idxlist.c:74
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:61
Xt_idxlist xt_idxvec_new(const Xt_int *idxlist, int num_indices)
Definition: xt_idxvec.c:163