1 /*
2  * Copyright(C) 1999-2020 National Technology & Engineering Solutions
3  * of Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
4  * NTESS, the U.S. Government retains certain rights in this software.
5  *
6  * See packages/seacas/LICENSE for details
7  */
8 
9 #include "exodusII.h"     // for ex_err, etc
10 #include "exodusII_int.h" // for EX_FATAL, ATT_PROP_NAME, etc
11 
12 /*!
13 
14 The function ex_get_prop_names() returns names of integer properties
15 stored for an element block, node set, or side set. The number of
16 properties (needed to allocate space for the property names) can be
17 obtained via a call to ex_inquire() or ex_inquire_int().
18 
19 \return In case of an error, ex_get_prop_names() returns a negative number; a
20 warning will return a positive number.  Possible causes of errors
21 include:
22   -  data file not properly opened with call to ex_create() or ex_open()
23   -  invalid object type specified.
24 
25 \param[in]   exoid        exodus file ID returned from a previous call to
26 ex_create() or ex_open().
27 \param[in]   obj_type     Type of object; use one of the options in the table
28 below.
29 \param[out]  prop_names   Returned array containing num_props (obtained from
30 call to
31                           ex_inquire() or ex_inquire_int()) names (of maximum
32 length
33                           \p MAX_STR_LENGTH ) of properties to be stored. \b ID,
34 a
35                           reserved property name, will be the first name in the
36 array.
37 
38 | #ex_entity_type | description               |
39 | -------------- | ------------------------- |
40 |  #EX_NODE_SET   |  Node Set entity type     |
41 |  #EX_EDGE_BLOCK |  Edge Block entity type   |
42 |  #EX_EDGE_SET   |  Edge Set entity type     |
43 |  #EX_FACE_BLOCK |  Face Block entity type   |
44 |  #EX_FACE_SET   |  Face Set entity type     |
45 |  #EX_ELEM_BLOCK |  Element Block entity type|
46 |  #EX_ELEM_SET   |  Element Set entity type  |
47 |  #EX_SIDE_SET   |  Side Set entity type     |
48 |  #EX_ELEM_MAP   |  Element Map entity type  |
49 |  #EX_NODE_MAP   |  Node Map entity type     |
50 |  #EX_EDGE_MAP   |  Edge Map entity type     |
51 |  #EX_FACE_MAP   |  Face Map entity type     |
52 
53 As an example, the following code segment reads in properties assigned
54 to node sets:
55 
56 ~~~{.c}
57 int error, exoid, num_props, *prop_values;
58 char *prop_names[MAX_PROPS];
59 
60 \comment{read node set properties}
61 num_props = ex_inquire_int(exoid, EX_INQ_NS_PROP);
62 
63 for (i=0; i < num_props; i++) {
64    prop_names[i] = (char *) malloc ((MAX_STR_LENGTH+1), sizeof(char));
65    prop_values = (int *) malloc (num_node_sets, sizeof(int));
66 }
67 
68 error = ex_get_prop_names(exoid,EX_NODE_SET,prop_names);
69 
70 for (i=0; i < num_props; i++) {
71    error = ex_get_prop_array(exoid, EX_NODE_SET, prop_names[i],
72                              prop_values);
73 }
74 ~~~
75 
76 */
77 
ex_get_prop_names(int exoid,ex_entity_type obj_type,char ** prop_names)78 int ex_get_prop_names(int exoid, ex_entity_type obj_type, char **prop_names)
79 {
80   int     status;
81   int     i, num_props, propid;
82   char *  var_name;
83   size_t  att_len;
84   nc_type att_type;
85   int     api_name_size = ex_inquire_int(exoid, EX_INQ_MAX_READ_NAME_LENGTH);
86 
87   char errmsg[MAX_ERR_LENGTH];
88 
89   EX_FUNC_ENTER();
90   if (ex__check_valid_file_id(exoid, __func__) == EX_FATAL) {
91     EX_FUNC_LEAVE(EX_FATAL);
92   }
93 
94   /* determine which type of object property names are desired for */
95 
96   num_props = ex_get_num_props(exoid, obj_type);
97 
98   for (i = 0; i < num_props; i++) {
99     switch (obj_type) {
100     case EX_ELEM_BLOCK: var_name = VAR_EB_PROP(i + 1); break;
101     case EX_FACE_BLOCK: var_name = VAR_FA_PROP(i + 1); break;
102     case EX_EDGE_BLOCK: var_name = VAR_ED_PROP(i + 1); break;
103     case EX_NODE_SET: var_name = VAR_NS_PROP(i + 1); break;
104     case EX_SIDE_SET: var_name = VAR_SS_PROP(i + 1); break;
105     case EX_EDGE_SET: var_name = VAR_ES_PROP(i + 1); break;
106     case EX_FACE_SET: var_name = VAR_FS_PROP(i + 1); break;
107     case EX_ELEM_SET: var_name = VAR_ELS_PROP(i + 1); break;
108     case EX_ELEM_MAP: var_name = VAR_EM_PROP(i + 1); break;
109     case EX_FACE_MAP: var_name = VAR_FAM_PROP(i + 1); break;
110     case EX_EDGE_MAP: var_name = VAR_EDM_PROP(i + 1); break;
111     case EX_NODE_MAP: var_name = VAR_NM_PROP(i + 1); break;
112     default:
113       snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type,
114                exoid);
115       ex_err_fn(exoid, __func__, errmsg, EX_BADPARAM);
116       EX_FUNC_LEAVE(EX_FATAL);
117     }
118 
119     if ((status = nc_inq_varid(exoid, var_name, &propid)) != NC_NOERR) {
120       snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate property array %s in file id %d",
121                var_name, exoid);
122       ex_err_fn(exoid, __func__, errmsg, status);
123       EX_FUNC_LEAVE(EX_FATAL);
124     }
125 
126     /*   for each property, read the "name" attribute of property array variable
127      */
128     if ((status = nc_inq_att(exoid, propid, ATT_PROP_NAME, &att_type, &att_len)) != NC_NOERR) {
129       snprintf(errmsg, MAX_ERR_LENGTH,
130                "ERROR: failed to get property attributes (type, len) in file id %d", exoid);
131       ex_err_fn(exoid, __func__, errmsg, status);
132       EX_FUNC_LEAVE(EX_FATAL);
133     }
134 
135     if (att_len - 1 <= api_name_size) {
136       /* Client has large enough char string to hold text... */
137       if ((status = nc_get_att_text(exoid, propid, ATT_PROP_NAME, prop_names[i])) != NC_NOERR) {
138         snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get property name in file id %d", exoid);
139         ex_err_fn(exoid, __func__, errmsg, status);
140         EX_FUNC_LEAVE(EX_FATAL);
141       }
142     }
143     else {
144       /* FIXME */
145       snprintf(errmsg, MAX_ERR_LENGTH,
146                "ERROR: property name length exceeds space available to "
147                "store it in file id %d",
148                exoid);
149       ex_err_fn(exoid, __func__, errmsg, NC_ESTS);
150       EX_FUNC_LEAVE(EX_FATAL);
151     }
152   }
153   EX_FUNC_LEAVE(EX_NOERR);
154 }
155