void features_t::set_from_string(const wcstring &str) { wcstring_list_t entries = split_string(str, L','); const wchar_t *whitespace = L"\t\n\v\f\r "; for (wcstring entry : entries) { if (entry.empty()) continue; // Trim leading and trailing whitespace entry.erase(0, entry.find_first_not_of(whitespace)); entry.erase(entry.find_last_not_of(whitespace) + 1); const wchar_t *name = entry.c_str(); bool value = true; // A "no-" prefix inverts the sense. if (string_prefixes_string(L"no-", name)) { value = false; name += 3; // wcslen(L"no-") } // Look for a feature with this name. If we don't find it, assume it's a group name and set // all features whose group contain it. Do nothing even if the string is unrecognized; this // is to allow uniform invocations of fish (e.g. disable a feature that is only present in // future versions). // The special name 'all' may be used for those who like to live on the edge. if (const metadata_t *md = metadata_for(name)) { this->set(md->flag, value); } else { for (const metadata_t &md : metadata) { if (wcsstr(md.groups, name) || !wcscmp(name, L"all")) { this->set(md.flag, value); } } } } }
PUBLIC int get_inode_metadata(struct fs_info *fsi, uint32_t inode, struct inode_metadata *imd) { struct path p; struct key key; int ret; set_inode_key(inode, &key); ret = search_slot(&fsi->fs_root, &key, &p, 0); if (ret == KEY_NOT_FOUND) ret = -ENOENT; if (ret == KEY_FOUND) { memmove(imd, metadata_for(&p), sizeof(*imd)); } if (ret == KEY_FOUND || ret == KEY_NOT_FOUND) { free_path(&p); } assert(KEY_FOUND == SUCCESS); return ret; }
/* inserts a directory entry. * dir_inode - inode of the directory in which to insert * name - of the inserted file or directory * ent_inode - inode of the inserted file or directory * returns 0 for success, or negative errno. */ PUBLIC int insert_dir_ent(struct fs_info *fsi, uint32_t dir_inode, char *name, uint32_t ent_inode) { struct path p; struct key key; struct dir_ent_metadata *demd; int len = strlen(name), ret; if (len > MAX_FILE_NAME_LENGTH) { return -ENAMETOOLONG; } set_dir_ent_key(dir_inode, name, &key); ret = insert_empty_item_allowing_duplicates(&fsi->fs_root, &key, &p, sizeof(struct item) + sizeof(*demd) + len); if (ret) return ret; demd = (struct dir_ent_metadata *) metadata_for(&p); demd->inode = ent_inode; memmove(&demd->name, name, len); free_path(&p); return 0; /* failure, with errno */ }
PUBLIC int insert_inode(struct fs_info *fsi, uint32_t inode, uint16_t inode_type) { struct path p; struct key key; struct inode_metadata *imd; int ins_len = sizeof(struct item) + sizeof(*imd); int ret; set_inode_key(inode, &key); ret = insert_empty_item(&fsi->fs_root, &key, &p, ins_len); if (ret) return ret; imd = (struct inode_metadata *) metadata_for(&p); imd->inode_type = inode_type; imd->ctime = get_time(); imd->mtime = get_time(); free_path(&p); return SUCCESS; }
/* gets the inode of a directory entry, or 0 if errno. * (inode 0 is the root dir, which is not an entry in any dir) */ PUBLIC uint32_t get_dir_ent_inode(struct fs_info *fsi, uint32_t dir_inode, char *name) { struct path p; struct key key; struct dir_ent_metadata *demd; int ret; set_dir_ent_key(dir_inode, name, &key); ret = search_slot(&fsi->fs_root, &key, &p, 0); if (ret == KEY_NOT_FOUND) { free_path(&p); /* only for search_slot(), not step_to_next_slot() */ } while (TRUE) { if (ret == KEY_NOT_FOUND) { errno = ENOENT; } if (ret < 0) { errno = -ret; } if (ret != KEY_FOUND) { return 0; /* failure, with errno */ } demd = (struct dir_ent_metadata *) metadata_for(&p); if (!strcmp(name, demd->name)) { /* name matches */ ret = demd->inode; free_path(&p); return ret; } ret = step_to_next_slot(&p); if (ret == KEY_FOUND && compare_keys(&key, item_key(&p))) { errno = ENOENT; free_path(&p); return 0; /* failure, with errno */ } } }