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

📄 tree.c

📁 gdb-6.0 linux 下的调试工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  This file is part of the program psim.    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.     You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     */#ifndef _PARSE_C_#define _PARSE_C_#include <stdio.h>#include <stdarg.h>#include "basics.h"#include "device.h"#include "tree.h"#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif#include <ctype.h>/* manipulate/lookup device names */typedef struct _name_specifier {  /* components in the full length name */  char *path;  char *property;  char *value;  /* current device */  char *name;  char *base;  char *unit;  char *args;  /* previous device */  char *last_name;  char *last_base;  char *last_unit;  char *last_args;  /* work area */  char buf[1024];} name_specifier;/* Given a device specifier, break it up into its main components:   path (and if present) property name and property value. */STATIC_INLINE_TREE\(int)split_device_specifier(device *current,		       const char *device_specifier,		       name_specifier *spec){  char *chp = NULL;  /* expand any leading alias if present */  if (current != NULL      && *device_specifier != '\0'      && *device_specifier != '.'      && *device_specifier != '/') {    device *aliases = tree_find_device(current, "/aliases");    char alias[32];    int len = 0;    while (device_specifier[len] != '\0'	   && device_specifier[len] != '/'	   && device_specifier[len] != ':'	   && !isspace(device_specifier[len])) {      alias[len] = device_specifier[len];      len++;      if (len >= sizeof(alias))	error("split_device_specifier: buffer overflow");    }    alias[len] = '\0';    if (aliases != NULL	&& device_find_property(aliases, alias)) {      strcpy(spec->buf, device_find_string_property(aliases, alias));      strcat(spec->buf, device_specifier + len);    }    else {      strcpy(spec->buf, device_specifier);    }  }  else {    strcpy(spec->buf, device_specifier);  }  /* check no overflow */  if (strlen(spec->buf) >= sizeof(spec->buf))    error("split_device_specifier: buffer overflow\n");  /* strip leading spaces */  chp = spec->buf;  while (*chp != '\0' && isspace(*chp))    chp++;  if (*chp == '\0')    return 0;  /* find the path and terminate it with null */  spec->path = chp;  while (*chp != '\0' && !isspace(*chp))    chp++;  if (*chp != '\0') {    *chp = '\0';    chp++;  }  /* and any value */  while (*chp != '\0' && isspace(*chp))    chp++;  spec->value = chp;  /* now go back and chop the property off of the path */  if (spec->value[0] == '\0') {    spec->property = NULL; /*not a property*/    spec->value = NULL;  }  else if (spec->value[0] == '>'	   || spec->value[0] == '<') {    /* an interrupt spec */    spec->property = NULL;  }  else {    chp = strrchr(spec->path, '/');    if (chp == NULL) {      spec->property = spec->path;      spec->path = strchr(spec->property, '\0');    }    else {      *chp = '\0';      spec->property = chp+1;    }  }  /* and mark the rest as invalid */  spec->name = NULL;  spec->base = NULL;  spec->unit = NULL;  spec->args = NULL;  spec->last_name = NULL;  spec->last_base = NULL;  spec->last_unit = NULL;  spec->last_args = NULL;  return 1;}/* given a device specifier break it up into its main components -   path and property name - assuming that the last `device' is a   property name. */STATIC_INLINE_DEVICE\(int)split_property_specifier(device *current,			 const char *property_specifier,			 name_specifier *spec){  if (split_device_specifier(current, property_specifier, spec)) {    if (spec->property == NULL) {      /* force the last name to be a property name */      char *chp = strrchr(spec->path, '/');      if (chp == NULL) {	spec->property = spec->path;	spec->path = strrchr(spec->property, '\0');;      }      else {	*chp = '\0';	spec->property = chp+1;      }    }    return 1;  }  else    return 0;}/* device the next device name and split it up, return 0 when no more   names to device */STATIC_INLINE_TREE\(int)split_device_name(name_specifier *spec){  char *chp;  /* remember what came before */  spec->last_name = spec->name;  spec->last_base = spec->base;  spec->last_unit = spec->unit;  spec->last_args = spec->args;  /* finished? */  if (spec->path[0] == '\0') {    spec->name = NULL;    spec->base = NULL;    spec->unit = NULL;    spec->args = NULL;    return 0;  }  /* break the current device spec from the path */  spec->name = spec->path;  chp = strchr(spec->name, '/');  if (chp == NULL)    spec->path = strchr(spec->name, '\0');  else {    spec->path = chp+1;    *chp = '\0';  }  /* break out the base */  if (spec->name[0] == '(') {    chp = strchr(spec->name, ')');    if (chp == NULL) {      spec->base = spec->name;    }    else {      *chp = '\0';      spec->base = spec->name + 1;      spec->name = chp + 1;    }  }  else {    spec->base = spec->name;  }  /* now break out the unit */  chp = strchr(spec->name, '@');  if (chp == NULL) {    spec->unit = NULL;    chp = spec->name;  }  else {    *chp = '\0';    chp += 1;    spec->unit = chp;  }  /* finally any args */  chp = strchr(chp, ':');  if (chp == NULL)    spec->args = NULL;  else {    *chp = '\0';    spec->args = chp+1;  }  return 1;}/* device the value, returning the next non-space token */STATIC_INLINE_TREE\(char *)split_value(name_specifier *spec){  char *token;  if (spec->value == NULL)    return NULL;  /* skip leading white space */  while (isspace(spec->value[0]))    spec->value++;  if (spec->value[0] == '\0') {    spec->value = NULL;    return NULL;  }  token = spec->value;  /* find trailing space */  while (spec->value[0] != '\0' && !isspace(spec->value[0]))    spec->value++;  /* chop this value out */  if (spec->value[0] != '\0') {    spec->value[0] = '\0';    spec->value++;  }  return token;}/* traverse the path specified by spec starting at current */STATIC_INLINE_TREE\(device *)split_find_device(device *current,		  name_specifier *spec){  /* strip off (and process) any leading ., .., ./ and / */  while (1) {    if (strncmp(spec->path, "/", strlen("/")) == 0) {      /* cd /... */      while (current != NULL && device_parent(current) != NULL)	current = device_parent(current);      spec->path += strlen("/");    }    else if (strncmp(spec->path, "./", strlen("./")) == 0) {      /* cd ./... */      current = current;      spec->path += strlen("./");    }    else if (strncmp(spec->path, "../", strlen("../")) == 0) {      /* cd ../... */      if (current != NULL && device_parent(current) != NULL)	current = device_parent(current);      spec->path += strlen("../");    }    else if (strcmp(spec->path, ".") == 0) {      /* cd . */      current = current;      spec->path += strlen(".");    }    else if (strcmp(spec->path, "..") == 0) {      /* cd . */      if (current != NULL && device_parent(current) != NULL)	current = device_parent(current);      spec->path += strlen("..");    }    else      break;  }  /* now go through the path proper */  if (current == NULL) {    split_device_name(spec);    return NULL;  }  while (split_device_name(spec)) {    device *child;    for (child = device_child(current);	 child != NULL; child = device_sibling(child)) {      if (strcmp(spec->name, device_name(child)) == 0) {	if (spec->unit == NULL)	  break;	else {	  device_unit phys;	  device_decode_unit(current, spec->unit, &phys);	  if (memcmp(&phys, device_unit_address(child),		     sizeof(device_unit)) == 0)	    break;	}      }    }    if (child == NULL)      return current; /* search failed */    current = child;  }  return current;}STATIC_INLINE_TREE\(device *)split_fill_path(device *current,		const char *device_specifier,		name_specifier *spec){  /* break it up */  if (!split_device_specifier(current, device_specifier, spec))    device_error(current, "error parsing %s\n", device_specifier);  /* fill our tree with its contents */  current = split_find_device(current, spec);  /* add any additional devices as needed */  if (spec->name != NULL) {    do {      current = device_create(current, spec->base, spec->name,			      spec->unit, spec->args);    } while (split_device_name(spec));  }  return current;}INLINE_TREE\(void)tree_init(device *root,	  psim *system){  TRACE(trace_device_tree, ("tree_init(root=0x%lx, system=0x%lx)\n",			    (long)root,			    (long)system));  /* remove the old, rebuild the new */  tree_traverse(root, device_clean, NULL, system);  tree_traverse(root, device_init_static_properties, NULL, system);  tree_traverse(root, device_init_address, NULL, system);  tree_traverse(root, device_init_runtime_properties, NULL, system);  tree_traverse(root, device_init_data, NULL, system);}/* <non-white-space> */STATIC_INLINE_TREE\

⌨️ 快捷键说明

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