const char * remap_debug_filename (const char *filename) { debug_prefix_map *map; for (map = debug_prefix_maps; map; map = map->next) if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) { const char *name = filename + map->old_len; return concat (map->new_prefix, name, NULL); } return xstrdup (filename); }
static int interface_strcmp (const char* s) { /* Set the interface/implementation bits for this scope. */ struct impl_files *ifiles; const char *s1; for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) { const char *t1 = ifiles->filename; s1 = s; if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0) continue; while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0) s1++, t1++; /* A match. */ if (*s1 == *t1) return 0; /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ if (strchr (s1, '.') || strchr (t1, '.')) continue; if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') continue; /* A match. */ return 0; } /* No matches. */ return 1; }
const char * child_path (const char *parent, const char *child) { /* The child path must start with the parent path. */ size_t parent_len = strlen (parent); if (filename_ncmp (parent, child, parent_len) != 0) return NULL; /* The parent path must be a directory and the child must contain at least one component underneath the parent. */ const char *child_component; if (IS_DIR_SEPARATOR (parent[parent_len - 1])) { /* The parent path ends in a directory separator, so it is a directory. The first child component starts after the common prefix. */ child_component = child + parent_len; } else { /* The parent path does not end in a directory separator. The first character in the child after the common prefix must be a directory separator. Note that CHILD must hold at least parent_len characters for filename_ncmp to return zero. If the character at parent_len is nul due to CHILD containing the same path as PARENT, the IS_DIR_SEPARATOR check will fail here. */ if (!IS_DIR_SEPARATOR (child[parent_len])) return NULL; /* The first child component starts after the separator after the common prefix. */ child_component = child + parent_len + 1; } /* The child must contain at least one non-separator character after the parent. */ while (*child_component != '\0') { if (!IS_DIR_SEPARATOR (*child_component)) return child_component; child_component++; } return NULL; }
const char * remap_debug_filename (const char *filename) { debug_prefix_map *map; char *s; const char *name; size_t name_len; for (map = debug_prefix_maps; map; map = map->next) if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) break; if (!map) return xstrdup (filename); name = filename + map->old_len; name_len = strlen (name) + 1; s = (char *) xmalloc (name_len + map->new_len); memcpy (s, map->new_prefix, map->new_len); memcpy (s + map->new_len, name, name_len); return s; }
static const char * remap_filename (file_prefix_map *maps, const char *filename) { file_prefix_map *map; char *s; const char *name; size_t name_len; for (map = maps; map; map = map->next) if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) break; if (!map) return filename; name = filename + map->old_len; name_len = strlen (name) + 1; s = (char *) ggc_alloc_atomic (name_len + map->new_len); memcpy (s, map->new_prefix, map->new_len); memcpy (s + map->new_len, name, name_len); return s; }
/* Compute the locations of init files that GDB should source and return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT. If there is no system gdbinit (resp. home gdbinit and local gdbinit) to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to NULL. */ static void get_init_files (const char **system_gdbinit, const char **home_gdbinit, const char **local_gdbinit) { static const char *sysgdbinit = NULL; static char *homeinit = NULL; static const char *localinit = NULL; static int initialized = 0; if (!initialized) { struct stat homebuf, cwdbuf, s; char *homedir; if (SYSTEM_GDBINIT[0]) { int datadir_len = strlen (GDB_DATADIR); int sys_gdbinit_len = strlen (SYSTEM_GDBINIT); char *relocated_sysgdbinit; /* If SYSTEM_GDBINIT lives in data-directory, and data-directory has been provided, search for SYSTEM_GDBINIT there. */ if (gdb_datadir_provided && datadir_len < sys_gdbinit_len && filename_ncmp (SYSTEM_GDBINIT, GDB_DATADIR, datadir_len) == 0 && IS_DIR_SEPARATOR (SYSTEM_GDBINIT[datadir_len])) { /* Append the part of SYSTEM_GDBINIT that follows GDB_DATADIR to gdb_datadir. */ char *tmp_sys_gdbinit = xstrdup (SYSTEM_GDBINIT + datadir_len); char *p; for (p = tmp_sys_gdbinit; IS_DIR_SEPARATOR (*p); ++p) continue; relocated_sysgdbinit = concat (gdb_datadir, SLASH_STRING, p, (char *) NULL); xfree (tmp_sys_gdbinit); } else { relocated_sysgdbinit = relocate_path (gdb_program_name, SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE); } if (relocated_sysgdbinit && stat (relocated_sysgdbinit, &s) == 0) sysgdbinit = relocated_sysgdbinit; else xfree (relocated_sysgdbinit); } homedir = getenv ("HOME"); /* If the .gdbinit file in the current directory is the same as the $HOME/.gdbinit file, it should not be sourced. homebuf and cwdbuf are used in that purpose. Make sure that the stats are zero in case one of them fails (this guarantees that they won't match if either exists). */ memset (&homebuf, 0, sizeof (struct stat)); memset (&cwdbuf, 0, sizeof (struct stat)); if (homedir) { homeinit = xstrprintf ("%s/%s", homedir, gdbinit); if (stat (homeinit, &homebuf) != 0) { xfree (homeinit); homeinit = NULL; } } if (stat (gdbinit, &cwdbuf) == 0) { if (!homeinit || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) localinit = gdbinit; } initialized = 1; } *system_gdbinit = sysgdbinit; *home_gdbinit = homeinit; *local_gdbinit = localinit; }
static void remote_fileio_func_rename (char *buf) { CORE_ADDR old_ptr, new_ptr; int old_len, new_len; char *oldpath, *newpath; int ret, of, nf; struct stat ost, nst; /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */ if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len)) { remote_fileio_ioerror (); return; } /* 2. Parameter: Ptr to newpath / length incl. trailing zero */ if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len)) { remote_fileio_ioerror (); return; } /* Request oldpath using 'm' packet */ oldpath = alloca (old_len); if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0) { remote_fileio_ioerror (); return; } /* Request newpath using 'm' packet */ newpath = alloca (new_len); if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0) { remote_fileio_ioerror (); return; } /* Only operate on regular files and directories. */ of = stat (oldpath, &ost); nf = stat (newpath, &nst); if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode)) || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode))) { remote_fileio_reply (-1, FILEIO_EACCES); return; } remote_fio_no_longjmp = 1; ret = rename (oldpath, newpath); if (ret == -1) { /* Special case: newpath is a non-empty directory. Some systems return ENOTEMPTY, some return EEXIST. We coerce that to be always EEXIST. */ if (errno == ENOTEMPTY) errno = EEXIST; #ifdef __CYGWIN__ /* Workaround some Cygwin problems with correct errnos. */ if (errno == EACCES) { if (!of && !nf && S_ISDIR (nst.st_mode)) { if (S_ISREG (ost.st_mode)) errno = EISDIR; else { char oldfullpath[PATH_MAX]; char newfullpath[PATH_MAX]; int len; cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath, PATH_MAX); cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath, PATH_MAX); len = strlen (oldfullpath); if (IS_DIR_SEPARATOR (newfullpath[len]) && !filename_ncmp (oldfullpath, newfullpath, len)) errno = EINVAL; else errno = EEXIST; } } } #endif remote_fileio_return_errno (-1); } else remote_fileio_return_success (ret); }
static unsigned int get_filenum (const char *filename, unsigned int num) { static unsigned int last_used, last_used_dir_len; const char *file; size_t dir_len; unsigned int i, dir; if (num == 0 && last_used) { if (! files[last_used].dir && filename_cmp (filename, files[last_used].filename) == 0) return last_used; if (files[last_used].dir && filename_ncmp (filename, dirs[files[last_used].dir], last_used_dir_len) == 0 && IS_DIR_SEPARATOR (filename [last_used_dir_len]) && filename_cmp (filename + last_used_dir_len + 1, files[last_used].filename) == 0) return last_used; } file = lbasename (filename); /* Don't make empty string from / or A: from A:/ . */ #ifdef HAVE_DOS_BASED_FILE_SYSTEM if (file <= filename + 3) file = filename; #else if (file == filename + 1) file = filename; #endif dir_len = file - filename; dir = 0; if (dir_len) { #ifndef DWARF2_DIR_SHOULD_END_WITH_SEPARATOR --dir_len; #endif for (dir = 1; dir < dirs_in_use; ++dir) if (filename_ncmp (filename, dirs[dir], dir_len) == 0 && dirs[dir][dir_len] == '\0') break; if (dir >= dirs_in_use) { if (dir >= dirs_allocated) { dirs_allocated = dir + 32; dirs = (char **) xrealloc (dirs, (dir + 32) * sizeof (const char *)); } dirs[dir] = (char *) xmalloc (dir_len + 1); memcpy (dirs[dir], filename, dir_len); dirs[dir][dir_len] = '\0'; dirs_in_use = dir + 1; } } if (num == 0) { for (i = 1; i < files_in_use; ++i) if (files[i].dir == dir && files[i].filename && filename_cmp (file, files[i].filename) == 0) { last_used = i; last_used_dir_len = dir_len; return i; } } else i = num; if (i >= files_allocated) { unsigned int old = files_allocated; files_allocated = i + 32; files = (struct file_entry *) xrealloc (files, (i + 32) * sizeof (struct file_entry)); memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry)); } files[i].filename = num ? file : xstrdup (file); files[i].dir = dir; if (files_in_use < i + 1) files_in_use = i + 1; last_used = i; last_used_dir_len = dir_len; return i; }