My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
check_zvr.cpp
Go to the documentation of this file.
1 /*
2  * check_zvr.cpp - iterate a zvr file
3  *
4  * Copyright (C) 2006, 2007 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id: check_zvr.cpp 1825 2011-03-11 20:42:14Z ela $
22  *
23  */
24 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <assert.h>
34 #include <float.h>
35 #include <ctype.h>
36 
37 #include "strlist.h"
38 #include "object.h"
39 #include "complex.h"
40 #include "vector.h"
41 #include "dataset.h"
42 #include "constants.h"
43 #include "check_zvr.h"
44 
45 // Global variables.
47 struct zvr_data_t * zvr_root = NULL;
48 
49 // Creates a valid data vector description.
50 static char * zvr_vector_txt (struct zvr_vector_t * vec) {
51  int i, i1 = -1, i2 = -1, off = 0, len = strlen (vec->n1);
52  static char txt[64];
53  // strip off leading 're' or 'im'
54  if (strstr (vec->n1, "re") == vec->n1 ||
55  strstr (vec->n1, "im") == vec->n1 ||
56  strstr (vec->n1, "db") == vec->n1) {
57  off = 2;
58  }
59  // strip off leading 'mag' or 'ang'
60  else if (strstr (vec->n1, "mag") == vec->n1 ||
61  strstr (vec->n1, "ang") == vec->n1) {
62  off = 3;
63  }
64  for (i = off; i < len; i++) if (!isalpha (vec->n1[i])) break;
65  // get index 1
66  if (i < len) {
67  if (isdigit (vec->n1[i])) { i1 = vec->n1[i] - '0'; vec->n1[i] = '\0'; }
68  }
69  // get index 2
70  if (++i < len) {
71  if (isdigit (vec->n1[i])) { i2 = vec->n1[i] - '0'; vec->n1[i] = '\0'; }
72  }
73  // create vector description
74  if (i1 >= 0 && i2 >= 0) {
75  sprintf (txt, "%s[%d,%d]", &vec->n1[off], i1, i2);
76  }
77  else if (i1 >= 0) {
78  sprintf (txt, "%s[%d]", &vec->n1[off], i1);
79  }
80  else {
81  sprintf (txt, "%s", &vec->n1[off]);
82  }
83  return txt;
84 }
85 
86 // The function free's the memory used by the ZVR checker.
87 static void zvr_finalize (void) {
88  struct zvr_data_t * root, * next;
89  // go through each dataset
90  for (root = zvr_root; root; root = next) {
91  struct zvr_vector_t * vec = root->v;
92  struct zvr_header_t * hdr = root->h;
93  next = root->next;
94  // free each data line
95  if (root->d) {
96  struct zvr_line_t * rl, * nl;
97  for (rl = root->d; rl; rl = nl) {
98  nl = rl->next;
99  free (rl);
100  }
101  }
102  // free header
103  if (hdr) {
104  if (hdr->funit) free (hdr->funit);
105  if (hdr->d_UNT) free (hdr->d_UNT);
106  if (hdr->d_FMT) free (hdr->d_FMT);
107  if (hdr->d_TYP) free (hdr->d_TYP);
108  free (hdr);
109  }
110  // free data vector
111  if (vec) {
112  if (vec->nf) free (vec->nf);
113  if (vec->n1) free (vec->n1);
114  if (vec->n2) free (vec->n2);
115  free (vec);
116  }
117  }
118  zvr_root = NULL;
119 }
120 
121 // Create a dependency string list.
122 static strlist * zvr_create_dep (char * n) {
123  strlist * dep = new strlist ();
124  dep->add (n);
125  return dep;
126 }
127 
128 // Handles the dependency vectors.
129 static void zvr_check_dependencies (void) {
130  vector * dep1 = zvr_result->getDependencies ();
131  vector * depn = (vector *) dep1->getNext ();
132  bool equal;
133 
134  // check for differing dependency vectors
135  for (equal = true; depn != NULL; depn = (vector *) depn->getNext ()) {
136  if (depn->getSize () != dep1->getSize ()) {
137  equal = false; // differs in size
138  break;
139  } else {
140  for (int i = 0; i < depn->getSize (); i++) {
141  if (depn->get (i) != dep1->get (i)) {
142  equal = false; // differs in content
143  break;
144  }
145  }
146  }
147  }
148 
149  // all dependency vectors equal
150  if (equal) {
151  vector * ndep;
152  // delete unnecessary vectors
153  for (depn = (vector *) dep1->getNext (); depn != NULL; depn = ndep) {
154  ndep = (vector *) depn->getNext ();
155  zvr_result->delDependency (depn);
156  }
157  }
158  // at least one dependency vectors not equal
159  else {
160  vector * depn = zvr_result->getDependencies ();
161  vector * varn = zvr_result->getVariables ();
162  char txt[64]; int i = 1;
163  // change name of dependency vectors as well as the dependency
164  // reference in the appropriate variable vectors
165  while (depn != NULL && varn != NULL) {
166  sprintf (txt, "%s.%d", depn->getName (), i);
167  depn->setName (txt);
168  varn->setDependencies (zvr_create_dep (txt));
169  depn = (vector *) depn->getNext ();
170  varn = (vector *) varn->getNext ();
171  i++;
172  }
173  }
174 }
175 
176 // The function performs the data conversion if necessary.
177 static void zvr_conversion (struct zvr_data_t * root) {
178  for (; root != NULL; root = root->next) {
179  struct zvr_vector_t * vec = root->v;
180  struct zvr_header_t * hdr = root->h;
181  vector * var = vec->vd; int n;
182  // magnitude in [dB] and angle in [degree]
183  if (!strcmp (hdr->d_FMT, "COMPLEX") && !strcmp (hdr->d_UNT, "dB")) {
184  for (n = 0; n < var->getSize (); n++) {
185  nr_double_t r = real (var->get (n));
186  nr_double_t i = imag (var->get (n));
187  var->set (polar (pow (10.0, r / 20.0), rad (i)), n);
188  }
189  }
190  // magnitude in [dB]
191  else if (!strcmp (hdr->d_FMT, "MAGNITUDE") && !strcmp (hdr->d_UNT, "dB")) {
192  for (n = 0; n < var->getSize (); n++) {
193  nr_double_t r = real (var->get (n));
194  var->set (pow (10.0, r / 20.0), n);
195  }
196  }
197  // linear magnitude and angle in [degree]
198  else if (!strcmp (hdr->d_FMT, "MA")) {
199  for (n = 0; n < var->getSize (); n++) {
200  nr_double_t r = real (var->get (n));
201  nr_double_t i = imag (var->get (n));
202  var->set (polar (r, rad (i)), n);
203  }
204  }
205  // magnitude in [dB] and angle in [degree]
206  else if (!strcmp (hdr->d_FMT, "DB")) {
207  for (n = 0; n < var->getSize (); n++) {
208  nr_double_t r = real (var->get (n));
209  nr_double_t i = imag (var->get (n));
210  var->set (polar (pow (10.0, r / 20.0), rad (i)), n);
211  }
212  }
213  }
214 }
215 
216 /* This function is the overall ZVR data checker. It returns zero on
217  success, non-zero otherwise. */
218 int zvr_check (void) {
219  int errors = 0;
220  struct zvr_data_t * root;
221 
222  // create a dataset
223  zvr_result = new dataset ();
224 
225  // transfer ZVR tree data into the dataset
226  for (root = zvr_root; root; root = root->next) {
227  struct zvr_vector_t * vec = root->v;
228  vec->vi->setName (vec->nf);
229  vec->vd->setName (zvr_vector_txt (vec));
230  for (struct zvr_line_t * line = root->d; line; line = line->next) {
231  vec->vi->add (line->d);
232  vec->vd->add (rect (line->r, line->i));
233  }
234  vec->vd->setDependencies (zvr_create_dep (vec->nf));
235  zvr_result->appendDependency (vec->vi);
236  zvr_result->appendVariable (vec->vd);
237  }
238 
239  // handle dependency vectors
240  zvr_check_dependencies ();
241 
242  // perform data conversions
243  zvr_conversion (zvr_root);
244 
245  // free temporary memory
246  zvr_finalize ();
247  zvr_root = NULL;
248 
249  return errors ? -1 : 0;
250 }
251 
252 // Destroys data used by the ZVR checker.
253 void zvr_destroy (void) {
254  if (zvr_result != NULL) {
255  // delete associated dataset
256  delete zvr_result;
257  zvr_result = NULL;
258  }
259  if (zvr_root != NULL) {
260  zvr_finalize ();
261  zvr_root = NULL;
262  }
263 }
264 
265 // Initializes the ZVR checker.
266 void zvr_init (void) {
267  zvr_result = NULL;
268  zvr_root = NULL;
269 }