void hw_vabort (struct hw *me, const char *fmt, va_list ap) { const char *name; char *msg; /* find an identity */ if (me != NULL && hw_path (me) != NULL && hw_path (me) [0] != '\0') name = hw_path (me); else if (me != NULL && hw_name (me) != NULL && hw_name (me)[0] != '\0') name = hw_name (me); else if (me != NULL && hw_family (me) != NULL && hw_family (me)[0] != '\0') name = hw_family (me); else name = "device"; /* construct an updated format string */ msg = alloca (strlen (name) + strlen (": ") + strlen (fmt) + 1); strcpy (msg, name); strcat (msg, ": "); strcat (msg, fmt); /* report the problem */ sim_engine_vabort (hw_system (me), STATE_HW (hw_system (me))->cpu, STATE_HW (hw_system (me))->cia, msg, ap); }
static const char * full_name_of_hw (struct hw *leaf, char *buf, unsigned sizeof_buf) { /* get a buffer */ char full_name[1024]; if (buf == (char*)0) { buf = full_name; sizeof_buf = sizeof (full_name); } /* use head recursion to construct the path */ if (hw_parent (leaf) == NULL) /* root */ { if (sizeof_buf < 1) hw_abort (leaf, "buffer overflow"); *buf = '\0'; } else /* sub node */ { char unit[1024]; full_name_of_hw (hw_parent (leaf), buf, sizeof_buf); if (hw_unit_encode (hw_parent (leaf), hw_unit_address (leaf), unit + 1, sizeof (unit) - 1) > 0) unit[0] = '@'; else unit[0] = '\0'; if (strlen (buf) + strlen ("/") + strlen (hw_name (leaf)) + strlen (unit) >= sizeof_buf) hw_abort (leaf, "buffer overflow"); strcat (buf, "/"); strcat (buf, hw_name (leaf)); strcat (buf, unit); } /* return it usefully */ if (buf == full_name) buf = hw_strdup (leaf, full_name); return buf; }
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; }