⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
(const char *)skip_token(const char *chp){  while (!isspace(*chp) && *chp != '\0')    chp++;  while (isspace(*chp) && *chp != '\0')    chp++;  return chp;}/* count the number of entries */STATIC_INLINE_TREE\(int)count_entries(device *current,	      const char *property_name,	      const char *property_value,	      int modulo){  const char *chp = property_value;  int nr_entries = 0;  while (*chp != '\0') {    nr_entries += 1;    chp = skip_token(chp);  }  if ((nr_entries % modulo) != 0) {    device_error(current, "incorrect number of entries for %s property %s, should be multiple of %d",		 property_name, property_value, modulo);  }  return nr_entries / modulo;}/* parse: <address> ::= <token> ; device dependant */STATIC_INLINE_TREE\(const char *)parse_address(device *current,	      device *bus,	      const char *chp,	      device_unit *address){  ASSERT(device_nr_address_cells(bus) > 0);  if (device_decode_unit(bus, chp, address) < 0)    device_error(current, "invalid unit address in %s", chp);  return skip_token(chp);}/* parse: <size> ::= <number> { "," <number> } ; */STATIC_INLINE_TREE\(const char *)parse_size(device *current,	   device *bus,	   const char *chp,	   device_unit *size){  int i;  int nr;  const char *curr = chp;  memset(size, 0, sizeof(*size));  /* parse the numeric list */  size->nr_cells = device_nr_size_cells(bus);  nr = 0;  ASSERT(size->nr_cells > 0);  while (1) {    char *next;    size->cells[nr] = strtoul(curr, &next, 0);    if (curr == next)      device_error(current, "Problem parsing <size> %s", chp);    nr += 1;    if (next[0] != ',')      break;    if (nr == size->nr_cells)      device_error(current, "Too many values in <size> %s", chp);    curr = next + 1;  }  ASSERT(nr > 0 && nr <= size->nr_cells);  /* right align the numbers */  for (i = 1; i <= size->nr_cells; i++) {    if (i <= nr)      size->cells[size->nr_cells - i] = size->cells[nr - i];    else      size->cells[size->nr_cells - i] = 0;  }  return skip_token(chp);}/* parse: <reg> ::= { <address> <size> } ; */STATIC_INLINE_TREE\(void)parse_reg_property(device *current,		   const char *property_name,		   const char *property_value){  int nr_regs;  int reg_nr;  reg_property_spec *regs;  const char *chp;  device *bus = device_parent(current);  /* determine the number of reg entries by counting tokens */  nr_regs = count_entries(current, property_name, property_value,			  1 + (device_nr_size_cells(bus) > 0));  /* create working space */  regs = zalloc(nr_regs * sizeof(*regs));  /* fill it in */  chp = property_value;  for (reg_nr = 0; reg_nr < nr_regs; reg_nr++) {    chp = parse_address(current, bus, chp, &regs[reg_nr].address);    if (device_nr_size_cells(bus) > 0)      chp = parse_size(current, bus, chp, &regs[reg_nr].size);    else      memset(&regs[reg_nr].size, sizeof (&regs[reg_nr].size), 0);  }  /* create it */  device_add_reg_array_property(current, property_name,				regs, nr_regs);  zfree(regs);}/* { <child-address> <parent-address> <child-size> }* */STATIC_INLINE_TREE\(void)parse_ranges_property(device *current,		      const char *property_name,		      const char *property_value){  int nr_ranges;  int range_nr;  range_property_spec *ranges;  const char *chp;    /* determine the number of ranges specified */  nr_ranges = count_entries(current, property_name, property_value, 3);  /* create a property of that size */  ranges = zalloc(nr_ranges * sizeof(*ranges));  /* fill it in */  chp = property_value;  for (range_nr = 0; range_nr < nr_ranges; range_nr++) {    chp = parse_address(current, current,			chp, &ranges[range_nr].child_address);    chp = parse_address(current, device_parent(current),			chp, &ranges[range_nr].parent_address);    chp = parse_size(current, current,		     chp, &ranges[range_nr].size);  }  /* create it */  device_add_range_array_property(current, property_name, ranges, nr_ranges);  zfree(ranges);}/* <integer> ... */STATIC_INLINE_TREE\(void)parse_integer_property(device *current,		       const char *property_name,		       const char *property_value){  int nr_entries;  unsigned_cell words[1024];  /* integer or integer array? */  nr_entries = 0;  while (1) {    char *end;    words[nr_entries] = strtoul(property_value, &end, 0);    if (property_value == end)      break;    nr_entries += 1;    if (nr_entries * sizeof(words[0]) >= sizeof(words))      device_error(current, "buffer overflow");    property_value = end;  }  if (nr_entries == 0)    device_error(current, "error parsing integer property %s (%s)",                 property_name, property_value);  else if (nr_entries == 1)    device_add_integer_property(current, property_name, words[0]);  else {    int i;    for (i = 0; i < nr_entries; i++) {      H2BE(words[i]);    }    /* perhaps integer array property is better */    device_add_array_property(current, property_name, words,                              sizeof(words[0]) * nr_entries);  }}/* <string> ... */STATIC_INLINE_TREE\(void)parse_string_property(device *current,		      const char *property_name,		      const char *property_value){  char **strings;  const char *chp;  int nr_strings;  int approx_nr_strings;  /* get an estimate as to the number of strings by counting double     quotes */  approx_nr_strings = 2;  for (chp = property_value; *chp; chp++) {    if (*chp == '"')      approx_nr_strings++;  }  approx_nr_strings = (approx_nr_strings) / 2;  /* create a string buffer for that many (plus a null) */  strings = (char**)zalloc((approx_nr_strings + 1) * sizeof(char*));  /* now find all the strings */  chp = property_value;  nr_strings = 0;  while (1) {    /* skip leading space */    while (*chp != '\0' && isspace(*chp))      chp += 1;    if (*chp == '\0')      break;    /* copy it in */    if (*chp == '"') {      /* a quoted string - watch for '\' et.al. */      /* estimate the size and allocate space for it */      int pos;      chp++;      pos = 0;      while (chp[pos] != '\0' && chp[pos] != '"') {	if (chp[pos] == '\\' && chp[pos+1] != '\0')	  pos += 2;	else	  pos += 1;      }      strings[nr_strings] = zalloc(pos + 1);      /* copy the string over */      pos = 0;      while (*chp != '\0' && *chp != '"') {	if (*chp == '\\' && *(chp+1) != '\0') {	  strings[nr_strings][pos] = *(chp+1);	  chp += 2;	  pos++;	}	else {	  strings[nr_strings][pos] = *chp;	  chp += 1;	  pos++;	}      }      if (*chp != '\0')	chp++;      strings[nr_strings][pos] = '\0';    }    else {      /* copy over a single unquoted token */      int len = 0;      while (chp[len] != '\0' && !isspace(chp[len]))	len++;      strings[nr_strings] = zalloc(len + 1);      strncpy(strings[nr_strings], chp, len);      strings[nr_strings][len] = '\0';      chp += len;    }    nr_strings++;    if (nr_strings > approx_nr_strings)      device_error(current, "String property %s badly formatted",		   property_name);  }  ASSERT(strings[nr_strings] == NULL); /* from zalloc */  /* install it */  if (nr_strings == 0)    device_add_string_property(current, property_name, "");  else if (nr_strings == 1)    device_add_string_property(current, property_name, strings[0]);  else {    const char **specs = (const char**)strings; /* stop a bogus error */    device_add_string_array_property(current, property_name,				     specs, nr_strings);  }  /* flush the created string */  while (nr_strings > 0) {    nr_strings--;    zfree(strings[nr_strings]);  }  zfree(strings);}/* <path-to-ihandle-device> */STATIC_INLINE_TREE\(void)parse_ihandle_property(device *current,		       const char *property,		       const char *value){  ihandle_runtime_property_spec ihandle;  /* pass the full path */  ihandle.full_path = value;  /* save this ready for the ihandle create */  device_add_ihandle_runtime_property(current, property,				      &ihandle);}EXTERN_TREE\(device *)tree_parse(device *current,	   const char *fmt,	   ...){  char device_specifier[1024];  name_specifier spec;  /* format the path */  {    va_list ap;    va_start(ap, fmt);    vsprintf(device_specifier, fmt, ap);    va_end(ap);    if (strlen(device_specifier) >= sizeof(device_specifier))      error("device_tree_add_deviced: buffer overflow\n");  }  /* construct the tree down to the final device */  current = split_fill_path(current, device_specifier, &spec);  /* is there an interrupt spec */  if (spec.property == NULL      && spec.value != NULL) {    char *op = split_value(&spec);    switch (op[0]) {    case '>':      {	char *my_port_name = split_value(&spec);	int my_port;	char *dest_port_name = split_value(&spec);	int dest_port;	name_specifier dest_spec;	char *dest_device_name = split_value(&spec);	device *dest;	/* find my name */	my_port = device_interrupt_decode(current, my_port_name,					  output_port);	/* find the dest device and port */	dest = split_fill_path(current, dest_device_name, &dest_spec);	dest_port = device_interrupt_decode(dest, dest_port_name,					    input_port);	/* connect the two */	device_interrupt_attach(current,				my_port,				dest,				dest_port,				permenant_object);      }      break;    default:      device_error(current, "unreconised interrupt spec %s\n", spec.value);      break;    }  }  /* is there a property */  if (spec.property != NULL) {    if (strcmp(spec.value, "true") == 0)      device_add_boolean_property(current, spec.property, 1);    else if (strcmp(spec.value, "false") == 0)      device_add_boolean_property(current, spec.property, 0);    else {      const device_property *property;      switch (spec.value[0]) {      case '*':	parse_ihandle_property(current, spec.property, spec.value + 1);	break;      case '[':	{	  unsigned8 words[1024];	  char *curr = spec.value + 1;	  int nr_words = 0;	  while (1) {	    char *next;	    words[nr_words] = H2BE_1(strtoul(curr, &next, 0));	    if (curr == next)	      break;	    curr = next;	    nr_words += 1;	  }	  device_add_array_property(current, spec.property,				    words, sizeof(words[0]) * nr_words);	}	break;      case '"':	parse_string_property(current, spec.property, spec.value);	break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -