MISR Toolkit  1.5.1
prtlabel.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  PrintLabel: Prints a PDS label in the Object Description Language
4  to a terminal device.
5 
6  Input:
7  base_node - Pointer to aggregate node of the ODL tree with which
8  printing is to begin. This node, and all aggregates
9  beneath it will be printed.
10 
11  Output: There are no output parameters and no function value is returned.
12  The label is written to the terminal using output routine
13  ODLPrintStmt. The default version of this output routine writes
14  to the 'stdout' file, but developers can substitute their own
15  versions of ODLPrintStmt to support workstations and such.
16 
17  Author: Randy Davis, University of Colorado LASP
18 
19  Creation Date: 11 October 1990
20  Last Modified: 18 May 1991
21 
22  History:
23 
24  Creation - This routine was introduced in Version 2.0 of the ODLC library.
25  a) In Version 1 of the ODLC software, the routine WriteLabel could be
26  called (and still can be called) to print to a terminal as well as
27  a file device. PrintLabel has been added to allow for output to
28  workstations and such without disturbing the file writing capabilities
29  found in WriteLabel. PrintLabel and WriteLabel are identical except
30  for the routine called to perform output.
31 
32  Version 2.1 - 13 March 1991 - Randy Davis, U. of Colorado LASP
33  a) Now prints out comments associated with an aggregate or parameter.
34  b) Eliminated use of the 'level' field, which has been deleted
35  from aggregate nodes.
36  c) Modified so that if both a name and class are specified for an
37  object, they are printed out in the PDS standard format, ie:
38 
39  OBJECT = class
40  NAME = name
41  ... other parameters ...
42  END_OBJECT = class
43 
44  If an object class is not given, then the old-style is used:
45 
46  OBJECT = name
47  ... parameters ...
48  END_OBJECT
49 
50  The latter style is always used for groups, since they don't have
51  a class.
52 
53  Version 2.2 - 18 May 1991 - M. DeMore, Jet Propulsion Laboratory
54  Removed include statements that were Unix specific and placed them
55  in odldef.h. Removed function prototypes of ODL routines and added
56  include file odlinter.h.
57 
58  Version 2.3 - 13 October 1991 - M. DeMore, Jet Propulsion Laboratory
59  Modified to handle new argument list to ODLFormatString, in order
60  to handle backslashes in DOS file names. Added pds_finish_label
61  test for toolbox use.
62 
63  ****************************************************************************/
64 
65 #include "odldef.h"
66 #include "odlinter.h"
67 
68 /* The following define the maximum number of characters in a label line, the
69  number of characters to indent on the left margin for each step up in
70  aggregate nesting level, and the minimum spacing for a parameter name */
71 
72 #define MAXLABLINE 70
73 #define INDENTSIZE 2
74 #define MINAMESIZE 20
75 
76 #ifdef PDS_TOOLBOX
77 
78 extern int pds_finish_label;
79 
80 #endif
81 
82 /* The following macro is used to space in properly from the left margin */
83 
84 #define indentf(X) for (i=0 ; i < X ; i++) stmt[len++] = ' '
85 
86 
87 void PrintLabel (
88 
89  AGGREGATE base_node)
90 
91 {
92 
93  AGGREGATE node; /* Pointer to current node */
94  AGGREGATE old_node; /* Pointer to previous node */
95  PARAMETER parameter; /* Pointer to current parameter node */
96  VALUE data; /* Pointer to current parameter value */
97  int i; /* Loop index */
98  int ip; /* Number of parens to print for sequence */
99  int ncol; /* Current output line column number */
100  int nindent; /* Indentation for parameter names */
101  int nl; /* Length of current parameter name */
102  int nlv; /* Length of current value */
103  int no; /* Alignment on OBJECT/END_OBJECT lines */
104  int ns; /* Alignment for parameter assignments */
105  int nv; /* Alignment for parameter values */
106  int vindent; /* Indentation for values */
107  int col_count; /* Count of array columns processed */
108  char stmt[ODLMAXSTMT]; /* Buffer to hold each statement */
109  int len; /* Number of characters in output statement */
110 
111  if (base_node == NULL)
112  {
113  return;
114  }
115 
116  /* Process the base node first and then all the nodes beneath it */
117 
118  old_node = base_node->parent;
119  node = base_node;
120  nindent = 0;
121 
122  while (node != NULL)
123  {
124  /* Put out any END_OBJECTs or END_GROUPs that are needed */
125 
126  if (node != base_node && node->parent == old_node)
127  {
128  /* The new object or group belongs to the old node. We defer the
129  END_OBJECT or END_GROUP for the old node until we're done
130  processing all of its dependent nodes, so we don't do anything
131  here except put a blank line before the OBJECT or GROUP line
132  if we're not going to put out a comment first */
133 
134  if (node->comment == NULL)
135  {
136  ODLPrintStmt ("\n");
137  }
138  }
139  else
140  {
141  /* The new object or group is at the same or lower level than the old
142  object or group. Put out the END_OBJECT or END_GROUP for the
143  old node and all of its ancestors, up to and including the node
144  at the same level as the new node */
145 
146  while (node->parent != old_node)
147  {
148  len = 0;
149  nindent -= INDENTSIZE;
150  indentf (nindent);
151  no = MINAMESIZE + INDENTSIZE;
152 
153  if (old_node->kind == KA_OBJECT &&
154  old_node->objClass != NULL && old_node->objClass[0] != '\0')
155  {
156  sprintf (&stmt[len], "%-*s = %s\n\n",
157  no,
158  "END_OBJECT",
159  old_node->objClass);
160  }
161  else
162  {
163  sprintf (&stmt[len], "%-*s = %s\n\n",
164  no,
165  (old_node->kind==KA_OBJECT)?"END_OBJECT":"END_GROUP",
166  old_node->name);
167  }
168 
169  ODLPrintStmt (stmt);
170  old_node = ParentAggregate (old_node);
171  }
172  }
173 
174  /* Put out the comment, if any associated with the new aggregate node */
175 
176  if (node->comment != NULL)
177  {
178  ODLFormatComment (stmt, node->comment, nindent+1, MAXLABLINE);
179  ODLPrintStmt (stmt);
180  }
181 
182  /* Put in the OBJECT = name or GROUP = name line for the new node,
183  unless this is a root node */
184 
185  if (node->parent != NULL)
186  {
187  len = 0;
188  indentf (nindent);
189  nindent += INDENTSIZE;
190  no = MINAMESIZE + INDENTSIZE;
191 
192  if (node->kind == KA_OBJECT &&
193  node->objClass != NULL && node->objClass[0] != '\0')
194  {
195  sprintf (&stmt[len], "%-*s = %s\n",
196  no,
197  "OBJECT",
198  node->objClass);
199  len = strlen (stmt);
200 
201  indentf (nindent);
202  sprintf (&stmt[len], "%-*s = %s\n",
203  MINAMESIZE,
204  "NAME",
205  node->name);
206  }
207  else
208  {
209  sprintf (&stmt[len], "%-*s = %s\n",
210  no,
211  (node->kind == KA_OBJECT) ? "OBJECT" : "GROUP",
212  node->name);
213  }
214 
215  ODLPrintStmt (stmt);
216  }
217 
218  /* Generate the attribute and pointer assignment statements for
219  the current object or group */
220 
221  parameter = FirstParameter (node);
222 
223  while (parameter != NULL)
224  {
225  /* Print out the comment associated with the parameter, if any */
226 
227  if (parameter->comment != NULL)
228  {
229  ODLFormatComment (stmt, parameter->comment, nindent+1, MAXLABLINE);
230  ODLPrintStmt (stmt);
231  }
232 
233  len = 0;
234 
235  /* Determine the padding necessary to make the equal sign and
236  values for this assignment line up nicely */
237 
238  ns = (parameter->node_kind==KP_POINTER) ? MINAMESIZE-1 : MINAMESIZE;
239 
240  /* Calculate the indentation to the start of the value for this
241  assignment. This amount of indentation will be applied if
242  the value continues onto second and subsequent lines so that
243  values will line up better */
244 
245  nl = strlen (parameter->name);
246  nv = ((nl > ns)? nl : ns) + 3;
247  vindent = nindent + nv;
248 
249  /* Write out the parameter name with appropriate indentation and
250  padding */
251 
252  indentf (nindent);
253 
254  if (parameter->node_kind == KP_POINTER)
255  {
256  stmt[len++] = '^';
257  }
258 
259  sprintf (&stmt[len], "%-*s = ",
260  ns,
261  parameter->name);
262  len += nv;
263 
264  /* Perform value-kind dependent formatting */
265 
266  switch (parameter->value_kind)
267  {
268  case KV_SEQUENCE:
269  ip = (parameter->rows > 0)? parameter->rows : 1;
270  if (ip > 2) ip = 2;
271  for (i=0; (i < ip); i++)
272  {
273  stmt[len++] = '(';
274  vindent++;
275  }
276  break;
277 
278  case KV_SET:
279  stmt[len++] = '{';
280  vindent++;
281  break;
282 
283  default:
284  break;
285  }
286 
287  /* Process every value for this assignment */
288 
289  col_count = 0;
290  ncol = vindent;
291 
292  data = FirstValue (parameter);
293 
294  while (data != NULL)
295  {
296  if (data->item.type != TV_STRING)
297  {
298  /* Determine the number of character spaces the new value
299  will occupy on the current line */
300 
301  nlv = data->item.length;
302  if (data->item.type == TV_SYMBOL && data->item.format == 0)
303  {
304  /* This is a quoted symbolic literal: account for the
305  space occupied by the delimiting apostrophes */
306 
307  nlv += 2;
308  }
309 
310  ncol += nlv;
311 
312  if (ncol >= MAXLABLINE)
313  {
314  /* Adding the new value would overflow the current line,
315  so start a new line */
316 
317  stmt[len++] = '\n';
318  indentf (vindent);
319  ncol = vindent + nlv;
320  }
321  }
322 
323  /* Format the data value, according to its data type */
324 
325  switch (data->item.type)
326  {
327  case TV_INTEGER:
328  len += ODLFormatInteger (&stmt[len], &data->item);
329  break;
330 
331  case TV_REAL:
332  len += ODLFormatReal (&stmt[len], &data->item);
333  break;
334 
335  case TV_SYMBOL:
336  len += ODLFormatSymbol (&stmt[len], &data->item);
337  break;
338 
339  case TV_STRING:
340  if (parameter->node_kind == KP_POINTER)
341  len += ODLFormatString (&stmt[len], &data->item, &ncol,
342  nindent+2*INDENTSIZE, MAXLABLINE-2, 1, 1);
343  else
344  len += ODLFormatString (&stmt[len], &data->item, &ncol,
345  nindent+2*INDENTSIZE, MAXLABLINE-2, 1, 0);
346  break;
347 
348  case TV_DATE:
349  len += ODLFormatDate (&stmt[len], &data->item);
350  break;
351 
352  case TV_TIME:
353  len += ODLFormatTime (&stmt[len], &data->item);
354  break;
355 
356  case TV_DATE_TIME:
357  len += ODLFormatDateTime (&stmt[len], &data->item);
358  break;
359  }
360 
361  /* Get the next data value for this assignment, if any */
362 
363  data = NextValue (data);
364 
365  /* Add any formatting that might be necessary to separate
366  values */
367 
368  if (data != NULL)
369  {
370  switch (parameter->value_kind)
371  {
372  case KV_SEQUENCE:
373  col_count++;
374  if (col_count >= parameter->columns)
375  {
376  stmt[len++] = ')';
377  stmt[len++] = '\n';
378  indentf (vindent-1);
379  stmt[len++] = '(';
380  ncol = vindent;
381  col_count = 0;
382  }
383  else
384  {
385  stmt[len++] = ',';
386  stmt[len++] = ' ';
387  ncol += 2;
388  }
389  break;
390 
391  default:
392  stmt[len++] = ',';
393  stmt[len++] = ' ';
394  ncol += 2;
395  break;
396  }
397  }
398  }
399 
400  /* We've processed all the values for this assignment. Put
401  out any necessary end-of-assignment formatting */
402 
403  switch (parameter->value_kind)
404  {
405  case KV_SEQUENCE:
406  for (i=0; (i < ip); i++)
407  {
408  stmt[len++] = ')';
409  }
410  break;
411 
412  case KV_SET:
413  stmt[len++] = '}';
414  break;
415 
416  default:
417  break;
418  }
419 
420  stmt[len++] = '\n';
421  stmt[len] = '\0';
422  ODLPrintStmt (stmt);
423 
424  /* Get the next parameter for this object, if any */
425 
426  parameter = NextParameter (parameter);
427  }
428 
429  /* Get the next object or group node, if any */
430 
431  old_node = node;
432  node = NextSubAggregate (base_node, node);
433  }
434 
435  /* Print out any END_OBJECTs or END_GROUPs that we have pending */
436 
437  while (old_node != base_node)
438  {
439  len = 0;
440  nindent -= INDENTSIZE;
441  indentf (nindent);
442  sprintf (&stmt[len], "%-*s = %s\n\n",
443  no,
444  (old_node->kind == KA_OBJECT) ? "END_OBJECT" : "END_GROUP",
445  old_node->name);
446  ODLPrintStmt (stmt);
447  old_node = ParentAggregate (old_node);
448  }
449 
450  /* Print out the terminating END statement */
451 
452 #ifdef PDS_TOOLBOX
453  if (pds_finish_label)
454  ODLPrintStmt ("END\n");
455 #else
456  ODLPrintStmt ("END\n");
457 #endif
458 
459  return;
460 }
AGGREGATE ParentAggregate(AGGREGATE base_node)
Definition: a_nodesa.c:295
HDFFCLIBAPI intf * len
#define MINAMESIZE
Definition: prtlabel.c:74
char format
Definition: odldef.h:215
if((msg=H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL) if((H5E_DATASET_g
Definition: odldef.h:97
int ODLFormatString(char stmt[], VALUE_DATA *item, int *column, int left_margin, int right_margin, int format_flag, int is_pointer)
Definition: fmtvalue.c:636
PARAMETER FirstParameter()
#define MAXLABLINE
Definition: prtlabel.c:72
Definition: odldef.h:97
char * name
Definition: odldef.h:138
int ODLFormatSymbol(char *stmt, VALUE_DATA *item)
Definition: fmtvalue.c:355
short length
Definition: odldef.h:217
char * comment
Definition: odldef.h:139
char * comment
Definition: odldef.h:114
AGGREGATE_KIND kind
Definition: odldef.h:115
int ODLFormatDateTime(char *stmt, VALUE_DATA *item)
Definition: fmtvalue.c:582
int ns
Definition: misr_init.c:6
Definition: odldef.h:96
int ODLFormatDate(char *stmt, VALUE_DATA *item)
Definition: fmtvalue.c:409
#define INDENTSIZE
Definition: prtlabel.c:73
#define ODLMAXSTMT
Definition: odldef.h:74
int ODLFormatReal(char *stmt, VALUE_DATA *item)
Definition: fmtvalue.c:181
void ODLPrintStmt()
short rows
Definition: odldef.h:144
int ODLFormatInteger(char stmt[], VALUE_DATA *item)
Definition: fmtvalue.c:80
struct Value_Data item
Definition: odldef.h:229
struct Aggregate_Node * parent
Definition: odldef.h:118
#define indentf(X)
Definition: prtlabel.c:84
VALUE_TYPE type
Definition: odldef.h:213
char * objClass
Definition: odldef.h:113
int ODLFormatTime(char *stmt, VALUE_DATA *item)
Definition: fmtvalue.c:484
HDFFCLIBAPI void * data
PARAMETER NextParameter()
VALUE FirstValue()
int ODLFormatComment(char *stmt, char *comment, int left_margin, int right_margin)
Definition: fmtvalue.c:854
VALUE NextValue()
Definition: odldef.h:93
VALUE_KIND value_kind
Definition: odldef.h:141
PARAMETER_KIND node_kind
Definition: odldef.h:140
short columns
Definition: odldef.h:143
AGGREGATE NextSubAggregate(AGGREGATE base_node, AGGREGATE start_node)
Definition: a_nodesa.c:410
char * name
Definition: odldef.h:112
void PrintLabel(AGGREGATE base_node)
Definition: prtlabel.c:87

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