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

📄 hw-tree.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* The common simulator framework for GDB, the GNU Debugger.   Copyright 2002 Free Software Foundation, Inc.   Contributed by Andrew Cagney and Red Hat.   This file is part of GDB.   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.  */#include "hw-main.h"#include "hw-base.h"#include "hw-tree.h"#include "sim-io.h"#include "sim-assert.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 *family;  char *name;  char *unit;  char *args;    /* previous device */  char *last_name;  char *last_family;  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 intsplit_device_specifier (struct hw *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 != '/')    {      struct hw *aliases = hw_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))	    hw_abort (NULL, "split_device_specifier: buffer overflow");	}      alias[len] = '\0';      if (aliases != NULL	  && hw_find_property (aliases, alias))	{	  strcpy (spec->buf, hw_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))    hw_abort (NULL, "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->family = NULL;  spec->unit = NULL;  spec->args = NULL;  spec->last_name = NULL;  spec->last_family = 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 intsplit_property_specifier (struct hw *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 struct hw */static intsplit_device_name (name_specifier *spec){  char *chp;  /* remember what came before */  spec->last_name = spec->name;  spec->last_family = spec->family;  spec->last_unit = spec->unit;  spec->last_args = spec->args;  /* finished? */  if (spec->path[0] == '\0')    {      spec->name = NULL;      spec->family = 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->family = spec->name;	}      else	{	  *chp = '\0';	  spec->family = spec->name + 1;	  spec->name = chp + 1;	}    }  else    {      spec->family = 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 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 struct hw *split_find_device (struct hw *current,		   name_specifier *spec){  /* strip off (and process) any leading ., .., ./ and / */  while (1)    {      if (strncmp (spec->path, "/", strlen ("/")) == 0)	{	  /* cd /... */	  while (current != NULL && hw_parent (current) != NULL)	    current = hw_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 && hw_parent (current) != NULL)	    current = hw_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 && hw_parent (current) != NULL)	    current = hw_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))    {      struct hw *child;      for (child = hw_child (current);	   child != NULL; child = hw_sibling (child))	{	  if (strcmp (spec->name, hw_name (child)) == 0)	    {	      if (spec->unit == NULL)		break;	      else		{		  hw_unit phys;		  hw_unit_decode (current, spec->unit, &phys);		  if (memcmp (&phys, hw_unit_address (child),			      sizeof (hw_unit)) == 0)		    break;		}	    }	}      if (child == NULL)	return current; /* search failed */      current = child;    }    return current;}static struct hw *split_fill_path (struct hw *current,		 const char *device_specifier,		 name_specifier *spec){  /* break it up */  if (!split_device_specifier (current, device_specifier, spec))    hw_abort (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	{	  if (current != NULL && !hw_finished_p (current))	    hw_finish (current);	  current = hw_create (NULL,			       current,			       spec->family,			       spec->name,			       spec->unit,			       spec->args);	}      while (split_device_name (spec));    }    return current;}/* <non-white-space> */static const char *skip_token(const char *chp){  while (!isspace(*chp) && *chp != '\0')    chp++;  while (isspace(*chp) && *chp != '\0')    chp++;  return chp;

⌨️ 快捷键说明

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