MISR Toolkit  1.5.1
parsact.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Description: This file contains action routines for the Object
4  Description Language parser. The routines are
5  called by the parser when specific production
6  rules are triggered.
7 
8  Author: Randy Davis, University of Colorado LASP
9 
10  Creation Date: 20 March 1989
11  Last Modified: 18 May 1991
12 
13  History:
14 
15  Creation - This set of routines was introduced in Version 1 of
16  the ODLC library.
17 
18  Version 2.0 - 26 November 1990 - R. Davis, U. of Colorado LASP
19  a) Upgraded routines to be compatible with Version 2 of ODL. Some
20  of the routine names and calling sequences have changes as a
21  result of this upgrade.
22  b) Converted to use new warning and error reporting scheme.
23  c) Created routine ODLCheckSequence to perform checks on
24  sequences previously performed as part of ODLMarkAttribute.
25  d) Defined global variables in this module rather than in ReadLabel.
26 
27  Version 2.1 - 13 March 1991 - R. Davis, U. of Colorado LASP
28  a) Modified the calling sequence to these routines so that only
29  pointers to value data structures are passed as arguments,
30  rather than having the entire structure copied in.
31  b) Added a new global variable ODLcurrent_comment to hold a pointer to
32  the most recently encountered comment. Also added code to
33  ODLBeginAggregate and ODLBeginParameter to attach the current
34  comment, if any, to the new aggregate or parameter node.
35  c) Moved the definition of global variables ODLerror_count and
36  ODLwarning_count out of this module.
37 
38  Version 2.2 - 18 May 1991 - M. DeMore, Jet Propulsion Laboratory
39  a) Removed include statements that were Unix specific and placed them
40  in odldef.h. Removed function prototypes that are now in an
41  include file and added include file odlinter.h.
42  b) Added PDS_TOOLBOX options to store a line number in each parameter
43  and aggregate structure.
44 
45 *****************************************************************************/
46 
47 #include <stdlib.h>
48 #include "odldef.h"
49 #include "odlinter.h"
50 
51 /* The following variables are defined in this module and referenced
52  in other modules. Note that their presence makes ODL parsing
53  non-re-entrant */
54 
55 AGGREGATE ODLroot_node; /* Pointer to root node of ODL tree */
56 AGGREGATE ODLcurrent_aggregate; /* Pointer to current aggregate node */
57 PARAMETER ODLcurrent_parameter; /* Pointer to current parameter node */
58 VALUE ODLcurrent_value; /* Pointer to current value node */
59 char *ODLcurrent_comment; /* Pointer to current comment */
60 
61 /* The following variables are defined in the module containing the output
62  routines ODLPrintError and ODLPrintWarning */
63 
64 extern int ODLerror_count; /* Cumulative count of errors */
65 extern int ODLwarning_count; /* Cumulative count of warnings */
66 
67 /* >>>>>>>>>>>>>>>>>>>>>>>>>> BEGIN CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
68 /* >>>>> MDD 5/14/91 Added external definition of yylineno so >>>>> */
69 /* >>>>> line numbers could be placed in aggregates >>>>> */
70 /* >>>>> and parameters. >>>>> */
71 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
72 
73 #ifdef PDS_TOOLBOX
74 
75 extern int yylineno;
76 
77 #endif
78 
79 /* >>>>>>>>>>>>>>>>>>>>>>>>>> END OF CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
80 
81 
82 /*****************************************************************************
83 
84  Routine: ODLBeginAggregate
85 
86  Description: Creates a new aggregate node on the ODL tree in response to
87  the processing of an OBJECT = name or GROUP = name line.
88 
89  Input: kind - Aggregate kind: object (KA_OBJECT) or group (KA_GROUP).
90  item - Pointer to a value data structure containing a string
91  with the name of the new object or group.
92 
93  Output: None. A new aggregate node is attached to the ODL tree.
94 
95 *****************************************************************************/
96 
97 
99 
100  AGGREGATE_KIND kind,
101  VALUE_DATA *item)
102 
103 {
104 
105  /* Create a new aggregate node */
106 
107  ODLcurrent_aggregate = NewAggregate (ODLcurrent_aggregate, kind,
108  item->value.string, "");
109 
110  /* Free up the memory space used to hold the aggregate name */
111 
112  free (item->value.string);
113 
114  /* Attach the current comment, if any, to the new aggregate */
115 
116  ODLcurrent_aggregate->comment = ODLcurrent_comment;
117  ODLcurrent_comment = NULL;
118 
119 /* >>>>>>>>>>>>>>>>>>>>>>>>>> BEGIN CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
120 /* >>>>> MDD 5/14/91 Added code to set the appl1 field in the >>>>> */
121 /* >>>>> aggregate to the current line number >>>>> */
122 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
123 
124 #ifdef PDS_TOOLBOX
125 
126  ODLcurrent_aggregate -> appl1 = yylineno;
127 
128 #endif
129 
130 /* >>>>>>>>>>>>>>>>>>>>>>>>>> END OF CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
131 
132  return;
133 }
134 
135 
136 
137 
138 /*****************************************************************************
139 
140  Routine: ODLEndAggregate
141 
142  Description: Closes out processing for the current aggregate node
143  and reverts to its parent.
144 
145  Input: kind - Aggregate kind: indicates whether an END_OBJECT or
146  END_GROUP statement was seen by the parser.
147  item - Pointer to a value data structure containing a string
148  with the object/group name found in the END_OBJECT or
149  END_GROUP (if any).
150 
151  Output: None.
152 
153 *****************************************************************************/
154 
155 
157 
158  AGGREGATE_KIND kind,
159  VALUE_DATA *item)
160 
161 {
162  char errmsg[120]; /* Error message text */
163 
164 
165  if (ODLcurrent_aggregate != ODLroot_node)
166  {
167  if (ODLcurrent_aggregate->kind == kind)
168  {
169  /* Make sure that the name in the END_OBJECT or END_GROUP part
170  matches the name that was given previously in the OBJECT
171  or GROUP part */
172 
173  if (item->value.string != NULL)
174  {
175  if (strcmp (item->value.string, ODLcurrent_aggregate->name) != 0)
176  {
177  sprintf (errmsg,
178  "END_%s = %s doesn't match %s = %s",
179  (kind==KA_OBJECT) ? "OBJECT" : "GROUP",
180  item->value.string,
181  (kind==KA_OBJECT) ? "OBJECT" : "GROUP",
182  ODLcurrent_aggregate->name);
183  ODLPrintWarning (errmsg);
184  }
185 
186  /* Free up the memory space used to hold the name */
187 
188  free (item->value.string);
189  }
190 
191  /* Revert to the parent object or group */
192 
193  ODLcurrent_aggregate = ParentAggregate (ODLcurrent_aggregate);
194  }
195  else
196  {
197  /* Found an END_GROUP when expecting END_OBJECT, or vice versa */
198 
199  sprintf (errmsg,
200  "Found END_%s when expecting END_%s - Ignored",
201  (kind==KA_OBJECT) ? "OBJECT" : "GROUP",
202  (ODLcurrent_aggregate->kind==KA_OBJECT) ? "OBJECT" : "GROUP");
203  ODLPrintError (errmsg);
204  }
205  }
206  else
207  {
208  /* Found an extra END_GROUP or END_OBJECT */
209 
210  sprintf (errmsg,
211  "Encountered an extra END_%s - Ignored",
212  (kind==KA_OBJECT) ? "OBJECT" : "GROUP");
213  ODLPrintError (errmsg);
214  }
215 
216  /* Get rid of any 'dangling' comment, since we don't have any parameter
217  to attach it to */
218 
219  if (ODLcurrent_comment != NULL)
220  {
221  free (ODLcurrent_comment);
222  ODLcurrent_comment = NULL;
223  }
224 
225  return;
226 }
227 
228 
229 
230 
231 /*****************************************************************************
232 
233  Routine: ODLBeginParameter
234 
235  Description: Creates a new parameter node for the current object or group.
236 
237  Input: kind - Parameter kind: attribute (KP_ATTRIBUTE) or
238  pointer (KP_POINTER).
239  item - Pointer to a value data structure containing a string
240  with the name of the new parameter.
241 
242  Output: None. A new parameter node is attached to the current object
243  or group node.
244 
245 *****************************************************************************/
246 
247 
249 
250  PARAMETER_KIND kind,
251  VALUE_DATA *item)
252 
253 {
254  char warning[120]; /* Warning message text */
255 
256 
257  /* Look to see if a parameter with this name already exists for the
258  current object or group */
259 
260  if (FindParameter (ODLcurrent_aggregate, item->value.string) != NULL)
261  {
262  /* It does: issue a warning */
263 
264  sprintf (warning,
265  "A parameter named %s already exists for %s %s.",
266  item->value.string,
267  (ODLcurrent_aggregate->kind==KA_OBJECT) ? "object" : "group",
268  ODLcurrent_aggregate->name);
269  ODLPrintWarning (warning);
270  }
271 
272  /* Create the new parameter node */
273 
274  ODLcurrent_parameter = NewParameter (ODLcurrent_aggregate, kind,
275  item->value.string);
276 
277  /* Free up the memory space used to hold the parameter name */
278 
279  free (item->value.string);
280 
281  /* Attach the current comment, if any, to the new parameter */
282 
283  ODLcurrent_parameter->comment = ODLcurrent_comment;
284  ODLcurrent_comment = NULL;
285 
286 /* >>>>>>>>>>>>>>>>>>>>>>>>>> BEGIN CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
287 /* >>>>> MDD 5/14/91 Added code to set the appl1 field in the >>>>> */
288 /* >>>>> parameter to the current line number >>>>> */
289 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
290 
291 #ifdef PDS_TOOLBOX
292 
293  ODLcurrent_parameter -> appl1 = yylineno;
294 
295 #endif
296 
297 /* >>>>>>>>>>>>>>>>>>>>>>>>>> END OF CN CHANGES >>>>>>>>>>>>>>>>>>>>>>>>> */
298 
299  return;
300 }
301 
302 
303 
304 
305 /*****************************************************************************
306 
307  Routine: ODLMarkParameter
308 
309  Description: Puts information about the kind of parameter value into
310  the current parameter node.
311 
312  Input: kind - Kind of parameter value: scalar (KV_SCALAR),
313  sequence (KV_SEQUENCE) or set (KV_SET)
314 
315  Output: None. The current parameter node is modified.
316 
317 *****************************************************************************/
318 
319 
321 
322  VALUE_KIND kind)
323 
324 {
325 
326  /* Save the parameter value kind */
327 
328  ODLcurrent_parameter->value_kind = kind;
329 
330  return;
331 }
332 
333 
334 
335 
336 /*****************************************************************************
337 
338  Routine: ODLStoreValue
339 
340  Description: Adds a value to the current parameter and records
341  information about the value.
342 
343  Input: item - An value data structure containing the value to be stored.
344 
345  Output: None. A new value is attached to the current parameter node.
346 
347 *****************************************************************************/
348 
349 
351 
352  VALUE_DATA *item)
353 
354 {
355 
356  /* Attach the new value node to the current parameter */
357 
358  ODLcurrent_value = NewValue (ODLcurrent_parameter, item);
359 
360  return;
361 }
362 
363 
364 
365 
366 /*****************************************************************************
367 
368  Routine: ODLStoreUnits1
369 
370  Description: Store a units value without an exponent.
371 
372  Input:
373  name - Pointer to a value data structure with a string
374  specifying the units name.
375 
376  Output: None. A units field descriptor structure is created.
377 
378 *****************************************************************************/
379 
380 
382 
383  VALUE_DATA *name)
384 
385 {
386  VALUE_DATA exponent; /* A value data structure for default exponent */
387 
388  /* Since no exponent was specified we will set it to the default value +1 */
389 
390  exponent.type = TV_INTEGER;
391  exponent.value.integer.number = 1;
392 
393  /* Now we can call our sister routine to create and store the new units
394  field descriptor */
395 
396  ODLStoreUnits2 (name, &exponent);
397 
398  return;
399 }
400 
401 
402 
403 
404 /*****************************************************************************
405 
406  Routine: ODLStoreUnits2
407 
408  Description: Store a units value with an exponent.
409 
410  Input:
411  name - Pointer to a value data structure containing a
412  string with the units name.
413  exponent - Pointer to a value data structure containing the
414  integer exponent value.
415 
416  Output: None. A units field descriptor structure is created.
417 
418 *****************************************************************************/
419 
420 
422 
423  VALUE_DATA *name,
424  VALUE_DATA *exponent)
425 
426 {
427  struct ODLUnits *new_units; /* Pointer to new units field descriptor */
428  struct ODLUnits *current_units; /* Pointer to current field descriptor */
429 
430 
431  /* Allocate memory in which to store the units field descriptor */
432 
433  new_units = (struct ODLUnits *) malloc (sizeof(struct ODLUnits));
434  if (new_units == NULL)
435  {
436  ODLPrintWarning ("Memory allocation failure while storing units");
437  }
438  else
439  {
440  /* Copy the pointer to the units designator */
441 
442  new_units->designator = name->value.string;
443 
444  /* Set the units exponent */
445 
446  new_units->exponent = exponent->value.integer.number;
447 
448  /* Indicate that this is the last units field descriptor in the chain */
449 
450  new_units->next_field = NULL;
451 
452  /* Store the units field descriptor */
453 
454  switch (ODLcurrent_value->item.type)
455  {
456  case TV_REAL:
457 
458  current_units = ODLcurrent_value->item.value.real.units;
459  if (current_units != NULL)
460  {
461  break;
462  }
463 
464  /* This is the first units field for a real value */
465 
466  ODLcurrent_value->item.value.real.units = new_units;
467  return;
468 
469  case TV_INTEGER:
470 
471  current_units = ODLcurrent_value->item.value.integer.units;
472  if (current_units != NULL)
473  {
474  break;
475  }
476 
477  /* This is the first units field for an integer value */
478 
479  ODLcurrent_value->item.value.integer.units = new_units;
480  return;
481 
482  default:
483  /* This should never happen */
484 
485  free (new_units->designator);
486  free (new_units);
487  return;
488  }
489 
490  /* There is already at least one units field: find the end of the
491  chain and tack this units field onto the end */
492 
493  while (current_units->next_field != NULL)
494  {
495  current_units = current_units->next_field;
496  }
497 
498  current_units->next_field = new_units;
499  }
500 
501  return;
502 }
503 
504 
505 
506 
507 /*****************************************************************************
508 
509  Routine: ODLMarkUnits
510 
511  Description: Modifies the sign of the exponent for the most recently
512  recorded units field to indicate whether the units field
513  is a multiplier or a divisor relative to the previous
514  units expression. For example, if a units expression of
515  <KM/SEC> is encountered, this routine will be called with
516  a value of -1 to indicate that the exponent associated
517  with the units field for seconds must be negated. The
518  expression will then be stored internally as KM^1, SEC^-1.
519 
520  Input:
521  exponent_sign - Set to +1 if the units field is a multiplier (for
522  which the units exponent is given a positive value)
523  or -1 if the units field is to be a divisor (for
524  which the units exponent needs to be negative).
525 
526  Output: None. The last units field descriptor structure may be modified.
527 
528 *****************************************************************************/
529 
530 
532 
533  int exponent_sign)
534 
535 {
536  struct ODLUnits *current_units; /* Pointer to current field descriptor */
537 
538 
539  /* If the units field is acting as a multiplier then the exponent sign
540  is already set properly and we don't have to do anything. Otherwise,
541  we need to negate the sign of the last units field exponent. */
542 
543  if (exponent_sign < 0)
544  {
545  /* We need to negate the exponent sign: find the last
546  units field descriptor */
547 
548  if (ODLcurrent_value->item.type == TV_REAL)
549  {
550  current_units = ODLcurrent_value->item.value.real.units;
551  }
552  else if (ODLcurrent_value->item.type == TV_INTEGER)
553  {
554  current_units = ODLcurrent_value->item.value.integer.units;
555  }
556  else
557  {
558  current_units = NULL;
559  }
560 
561  if (current_units != NULL)
562  {
563  while (current_units->next_field != NULL)
564  {
565  current_units = current_units->next_field;
566  }
567 
568  /* Negate the exponent */
569 
570  current_units->exponent = -current_units->exponent;
571  }
572  }
573 
574  return;
575 }
576 
577 
578 
579 
580 /*****************************************************************************
581 
582  Routine: ODLCheckSequence
583 
584  Description: Keeps track of number of rows and columns in a sequence.
585 
586  Input: None.
587 
588  Output: Warning message printed if problem detected.
589 
590 *****************************************************************************/
591 
592 
594 {
595  char warning[120]; /* Character string to hold warning message */
596 
597 
598  /* Increment the count of rows. If this is the first row, establish the
599  number of columns per row. All further rows should have the same
600  number of columns. */
601 
602  ODLcurrent_parameter->rows++;
603  if (ODLcurrent_parameter->rows == 1)
604  {
605  ODLcurrent_parameter->columns = ODLcurrent_parameter->value_count;
606  }
607  else if (ODLcurrent_parameter->rows*ODLcurrent_parameter->columns !=
608  ODLcurrent_parameter->value_count)
609  {
610  sprintf (warning,
611  "Row %d of sequence has different number of columns than first row",
612  ODLcurrent_parameter->rows);
613  ODLPrintWarning (warning);
614  }
615 
616  return;
617 }
618 
619 
620 
621 
622 /*****************************************************************************
623 
624  Routine: ODLCheckRange
625 
626  Description: Checks the low and high range values.
627 
628  Input:
629  low - Value data structure containing the low value of the range.
630  high - Value data structure containing the high value of the range.
631 
632  Output: Warning message printed if a problem is detected.
633 
634 *****************************************************************************/
635 
636 
638 
639  VALUE_DATA *low,
640  VALUE_DATA *high)
641 
642 {
643 
644  /* Check the high and low range values */
645 
646  if (high->value.integer.number < low->value.integer.number)
647  {
648  ODLPrintWarning ("Low value of range is greater than high value");
649  }
650 
651  /* Since there is no special range value kind in ODL Version 2, establish
652  that the range value will be represented as a sequence. */
653 
654  ODLCheckSequence ();
655 
656  return;
657 }
658 
659 
660 
661 
662 /*****************************************************************************
663 
664  Routine: ODLEndLabel
665 
666  Description: Finishes processing when the end of a label is found.
667 
668  Input: None.
669 
670  Output: The function value is set to 1 if no errors occurred during
671  parsing; otherwise the value is set to 0.
672 
673 *****************************************************************************/
674 
675 
677 {
678  char error_msg[120]; /* Error message text */
679 
680 
681  while (ODLcurrent_aggregate != ODLroot_node)
682  {
683  /* Put out an error message for each missing END_OBJECT or END_GROUP */
684 
685  sprintf (error_msg,
686  "Missing END_%s for %s %s.",
687  (ODLcurrent_aggregate->kind==KA_OBJECT) ? "OBJECT" : "GROUP",
688  (ODLcurrent_aggregate->kind==KA_OBJECT) ? "object" : "group",
689  ODLcurrent_aggregate->name);
690  ODLPrintError(error_msg);
691 
692  /* Point to the current aggregate node's parent */
693 
694  ODLcurrent_aggregate = ParentAggregate (ODLcurrent_aggregate);
695  }
696 
697  return ((ODLerror_count+ODLwarning_count) == 0);
698 }
AGGREGATE ParentAggregate(AGGREGATE base_node)
Definition: a_nodesa.c:295
void ODLStoreUnits2(VALUE_DATA *name, VALUE_DATA *exponent)
Definition: parsact.c:421
void ODLStoreValue(VALUE_DATA *item)
Definition: parsact.c:350
void ODLMarkUnits(int exponent_sign)
Definition: parsact.c:531
int ODLwarning_count
Definition: output.c:59
void ODLStoreUnits1(VALUE_DATA *name)
Definition: parsact.c:381
int ODLEndLabel()
Definition: parsact.c:676
struct ODLInteger integer
Definition: odldef.h:219
long value_count
Definition: odldef.h:142
enum Parameter_Kind PARAMETER_KIND
Definition: odldef.h:91
char * comment
Definition: odldef.h:139
PARAMETER NewParameter()
char * comment
Definition: odldef.h:114
AGGREGATE_KIND kind
Definition: odldef.h:115
void ODLCheckRange(VALUE_DATA *low, VALUE_DATA *high)
Definition: parsact.c:637
int ODLerror_count
Definition: output.c:58
int yylineno
Definition: lexan.c:1951
Definition: odldef.h:96
struct ODLUnits * next_field
Definition: odldef.h:178
HDFFCLIBAPI _fcd name
void ODLMarkParameter(VALUE_KIND kind)
Definition: parsact.c:320
short rows
Definition: odldef.h:144
struct ODLReal real
Definition: odldef.h:220
void ODLBeginAggregate(AGGREGATE_KIND kind, VALUE_DATA *item)
Definition: parsact.c:98
struct Value_Data item
Definition: odldef.h:229
long exponent
Definition: odldef.h:177
enum Aggregate_Kind AGGREGATE_KIND
Definition: odldef.h:88
void ODLCheckSequence()
Definition: parsact.c:593
char * string
Definition: odldef.h:222
AGGREGATE ODLcurrent_aggregate
Definition: parsact.c:56
PARAMETER ODLcurrent_parameter
Definition: parsact.c:57
AGGREGATE ODLroot_node
Definition: parsact.c:55
VALUE_TYPE type
Definition: odldef.h:213
char * designator
Definition: odldef.h:176
PARAMETER FindParameter()
struct ODLUnits * units
Definition: odldef.h:185
struct ODLUnits * units
Definition: odldef.h:192
H5TOOLS_DLL void error_msg(const char *fmt,...)
char * ODLcurrent_comment
Definition: parsact.c:59
void ODLBeginParameter(PARAMETER_KIND kind, VALUE_DATA *item)
Definition: parsact.c:248
VALUE NewValue()
VALUE_KIND value_kind
Definition: odldef.h:141
void ODLPrintWarning()
AGGREGATE NewAggregate(AGGREGATE base_node, AGGREGATE_KIND kind, char *name, char *classType)
Definition: a_nodesa.c:75
short columns
Definition: odldef.h:143
void ODLEndAggregate(AGGREGATE_KIND kind, VALUE_DATA *item)
Definition: parsact.c:156
union Value_Data::@2 value
VALUE ODLcurrent_value
Definition: parsact.c:58
char * name
Definition: odldef.h:112
void ODLPrintError()
enum Value_Kind VALUE_KIND
Definition: odldef.h:94
long number
Definition: odldef.h:191

MISR Toolkit - Copyright © 2005 - 2020 Jet Propulsion Laboratory
Generated on Fri Jun 19 2020 22:49:51