1 /* 2  * CDDL HEADER START 3  * 4  * The contents of this file are subject to the terms of the 5  * Common Development and Distribution License, Version 1.0 only 6  * (the "License"). You may not use this file except in compliance 7  * with the License. 8  * 9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10  * or http://www.opensolaris.org/os/licensing. 11  * See the License for the specific language governing permissions 12  * and limitations under the License. 13  * 14  * When distributing Covered Code, include this CDDL HEADER in each 15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16  * If applicable, add the following below this CDDL HEADER, with the 17  * fields enclosed by brackets "[]" replaced with your own identifying 18  * information: Portions Copyright [yyyy] [name of copyright owner] 19  * 20  * CDDL HEADER END 21  */ 22 /* 23  * Copyright (c) 2000-2001 by Sun Microsystems, Inc. 24  * All rights reserved. 25  */ 26  27 #pragma ident "%Z%%M% %I% %E% SMI" 28  29 #include <stdlib.h> 30 #include <string.h> 31  32 #include "Ancestor.ext1" 33  34 /* ========================================================================= */ 35 /* Ancestor object definitions. */ 36  Ancestor(Str field,fru_tag_t t,const fru_regdef_t * d)37 Ancestor::Ancestor(Str field, fru_tag_t t, const fru_regdef_t *d) 38  : field_name(field), 39  tag(t), 40  def(d), 41  numInstances(0), 42  numBufs(1), 43  next(NULL) 44 { 45  offsets = (uint32_t *)malloc(sizeof (uint32_t) 46  * ANCESTOR_INST_BUF_SIZE); 47  paths = (char **)malloc(sizeof (char *) 48  * ANCESTOR_INST_BUF_SIZE); 49 } 50  ~Ancestor()51 Ancestor::~Ancestor() 52 { 53  free(offsets); 54  if (paths != NULL) { 55  for (int i = 0; i < numInstances && i < 0xFFFFFF; i++) { 56  free(paths[i]); 57  } 58  } 59  free(paths); 60  delete next; 61 } 62  63 /* 64 void 65 Ancestor::print(void) 66 { 67  fprintf(stderr, "Ancestor Information\n"); 68  fprintf(stderr, "Tag Name: %s\n", def->name); 69  fprintf(stderr, "Tag Type: %s\n", 70  get_tagtype_str(get_tag_type(&tag))); 71  fprintf(stderr, "Num instances: %d\n", numInstances); 72  fprintf(stderr, " offsets:\n"); 73  for (int i = 0; i < numInstances; i++) { 74  fprintf(stderr, " %d\n", offsets[i]); 75  } 76  77  if (next != NULL) { 78  next->print(); 79  } 80 } 81 */ 82  83 void addInstance(const char * path,uint32_t offset)84 Ancestor::addInstance(const char *path, uint32_t offset) 85 { 86  if (numInstances >= ANCESTOR_INST_BUF_SIZE) { 87  numBufs++; 88  offsets = (uint32_t *)realloc(offsets, 89  (sizeof (uint32_t) * 90  (ANCESTOR_INST_BUF_SIZE * numBufs))); 91  paths = (char **)realloc(offsets, 92  (sizeof (char *) * 93  (ANCESTOR_INST_BUF_SIZE * numBufs))); 94  } 95  offsets[numInstances] = offset; 96  paths[numInstances++] = strdup(path); 97 } 98  99 Str getFieldName(void)100 Ancestor::getFieldName(void) 101 { 102  return (field_name); 103 } 104  105 fru_tag_t getTag(void)106 Ancestor::getTag(void) 107 { 108  return (tag); 109 } 110  111 const fru_regdef_t * getDef(void)112 Ancestor::getDef(void) 113 { 114  return (def); 115 } 116  117 int getNumInstances(void)118 Ancestor::getNumInstances(void) 119 { 120  return (numInstances); 121 } 122  123 uint32_t getInstOffset(int num)124 Ancestor::getInstOffset(int num) 125 { 126  if (num < numInstances) 127  return (offsets[num]); 128  else 129  return (offsets[numInstances]); 130 } 131  132 const char * getPath(int num)133 Ancestor::getPath(int num) 134 { 135  if (num < numInstances) 136  return (paths[num]); 137  else 138  return (paths[numInstances]); 139 } 140  141  142 Ancestor * listTaggedAncestors(char * element)143 Ancestor::listTaggedAncestors(char *element) 144 { 145  Ancestor *rc = NULL; 146  fru_regdef_t *def = NULL; 147  int i = 0; 148  149  unsigned int number = 0; 150  char **data_elems = fru_reg_list_entries(&number); 151  152  if (data_elems == NULL) { 153  return (NULL); 154  } 155  156  // look through all the elements. 157  for (i = 0; i < number; i++) { 158  def = (fru_regdef_t *) 159  fru_reg_lookup_def_by_name(data_elems[i]); 160  Ancestor *ant = createTaggedAncestor(def, element); 161  if (ant != NULL) { 162  if (rc == NULL) { 163  rc = ant; 164  } else { 165  Ancestor *tmp = rc; 166  while (tmp->next != NULL) { 167  tmp = tmp->next; 168  } 169  tmp->next = ant; 170  } 171  } 172  } 173  174  for (i = 0; i < number; i++) { 175  free(data_elems[i]); 176  } 177  free(data_elems); 178  179  return (rc); 180 } 181  182 Ancestor * createTaggedAncestor(const fru_regdef_t * def,Str element)183 Ancestor::createTaggedAncestor(const fru_regdef_t *def, Str element) 184 { 185  // ancestors have to be tagged. 186  if (def->tagType == FRU_X) 187  return (NULL); 188  189  fru_tag_t tag; 190  mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag); 191  Ancestor *rc = new Ancestor(element, tag, def); 192  193  if (element.compare(def->name) == 0) { 194  rc->addInstance("", 0); 195  return (rc); 196  } 197  198  int found = 0; 199  if (def->dataType == FDTYPE_Record) { 200  uint32_t offset = 0; 201  for (int i = 0; i < def->enumCount; i++) { 202  const fru_regdef_t *tmp 203  = fru_reg_lookup_def_by_name 204  ((char *)def->enumTable[i].text); 205  Str path = "/"; 206  path << def->name; 207  int f = definitionContains(tmp, def, element, 208  offset, rc, path); 209  if (f == 1) found = 1; // found needs to latch at one. 210  offset += tmp->payloadLen; 211  } 212  } 213  214  if (!found) { 215  delete rc; 216  return (NULL); 217  } 218  219  return (rc); 220 } 221  222 int definitionContains(const fru_regdef_t * def,const fru_regdef_t * parent_def,Str element,uint32_t offset,Ancestor * ant,Str path)223 Ancestor::definitionContains(const fru_regdef_t *def, 224  const fru_regdef_t *parent_def, 225  Str element, 226  uint32_t offset, 227  Ancestor *ant, 228  Str path) 229 { 230  if (element.compare(def->name) == 0) { 231  if (parent_def->iterationType != FRU_NOT_ITERATED) { 232  offset += 4; 233  for (int i = 0; i < parent_def->iterationCount; i++) { 234  Str tmp = path; 235  tmp << "[" << i << "]/"; 236  ant->addInstance(tmp.peak(), offset); 237  offset += (parent_def->payloadLen - 4) / 238  parent_def->iterationCount; 239  } 240  } else { 241  path << "/"; 242  ant->addInstance(path.peak(), offset); 243  } 244  return (1); 245  } 246  247  int found = 0; 248  if (def->dataType == FDTYPE_Record) { 249  for (int i = 0; i < def->enumCount; i++) { 250  const fru_regdef_t *tmp 251  = fru_reg_lookup_def_by_name 252  ((char *)def->enumTable[i].text); 253  Str newPath = path; 254  newPath << "/" << def->name; 255  int f = definitionContains(tmp, def, element, 256  offset, ant, newPath); 257  if (f == 1) found = 1; // found needs to latch at one. 258  offset += tmp->payloadLen; 259  } 260  } 261  262  int d = 42; 263  int o = 052; 264  int x = 0x2a; 265  int X = 0X2A; 266  int b = 0b101010; // C++14 267  unsigned long long l1 = 18446744073709550592ull; // C++11 268  unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14 269  unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14 270  unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14 271  double d = 0x1.2p3; // hex frac 1.2 (dec 1.125) scaled by 2^3, i.e. 9.0 272  d = 123.456e-67; 273  d = .1E4f; 274  d = 58.; 275  d = -4e2; 276  277  return (found); 278 } 279  280 /*http://example.com*/ 281