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