/*....................................................................... * Allocate a free-list for use in allocating hash tables and their nodes. * * Input: * list_count int The number of HashTable containers per free-list * block. * node_count int The number of HashTable nodes per free-list block. * Output: * return HashMemory * The new free-list for use in allocating hash tables * and their nodes. */ HashMemory *_new_HashMemory(int hash_count, int node_count) { HashMemory *mem; /* * Allocate the free-list container. */ mem = (HashMemory *) malloc(sizeof(HashMemory)); if(!mem) { errno = ENOMEM; return NULL; }; /* * Initialize the container at least up to the point at which it can * safely be passed to _del_HashMemory(). */ mem->hash_memory = NULL; mem->node_memory = NULL; mem->string_memory = NULL; /* * Allocate the two free-lists. */ mem->hash_memory = _new_FreeList(sizeof(HashTable), hash_count); if(!mem->hash_memory) return _del_HashMemory(mem, 1); mem->node_memory = _new_FreeList(sizeof(HashNode), node_count); if(!mem->node_memory) return _del_HashMemory(mem, 1); mem->string_memory = _new_StringMem(64); if(!mem->string_memory) return _del_HashMemory(mem, 1); /* * Return the free-list container. */ return mem; }
/*....................................................................... * Create a new GlCharQueue object. * * Output: * return GlCharQueue * The new object, or NULL on error. */ GlCharQueue *_new_GlCharQueue(void) { GlCharQueue *cq; /* The object to be returned */ /* * Allocate the container. */ cq = malloc(sizeof(GlCharQueue)); if(!cq) { errno = ENOMEM; return NULL; }; /* * Before attempting any operation that might fail, initialize the * container at least up to the point at which it can safely be passed * to del_GlCharQueue(). */ cq->err = NULL; cq->bufmem = NULL; cq->buffers.head = NULL; cq->buffers.tail = NULL; cq->nflush = cq->ntotal = 0; /* * Allocate a place to record error messages. */ cq->err = _new_ErrMsg(); if(!cq->err) return _del_GlCharQueue(cq); /* * Allocate the freelist of CqCharBuff structures. */ cq->bufmem = _new_FreeList(sizeof(CqCharBuff), 1); if(!cq->bufmem) return _del_GlCharQueue(cq); return cq; }
/*....................................................................... * Create a string free-list container and the first block of its free-list. * * Input: * blocking_factor int The blocking_factor argument specifies how * many strings of length SM_STRLEN * bytes (see stringmem.h) are allocated in each * free-list block. * For example if blocking_factor=64 and * SM_STRLEN=16, then each new * free-list block will take 1K of memory. * Output: * return StringMem * The new free-list container, or NULL on * error. */ StringMem *_new_StringMem(unsigned blocking_factor) { StringMem *sm; /* The container to be returned. */ /* * Check arguments. */ if(blocking_factor < 1) { errno = EINVAL; return NULL; }; /* * Allocate the container. */ sm = (StringMem *) malloc(sizeof(StringMem)); if(!sm) { errno = ENOMEM; return NULL; }; /* * Before attempting any operation that might fail, initialize * the container at least up to the point at which it can safely * be passed to _del_StringMem(). */ sm->nmalloc = 0; sm->fl = NULL; /* * Allocate the free-list. */ sm->fl = _new_FreeList(SM_STRLEN, blocking_factor); if(!sm->fl) return _del_StringMem(sm, 1); /* * Return the free-list container. */ return sm; }
/*....................................................................... * Create the resources needed to expand filenames. * * Output: * return ExpandFile * The new object, or NULL on error. */ ExpandFile *new_ExpandFile(void) { ExpandFile *ef; /* The object to be returned */ /* * Allocate the container. */ ef = (ExpandFile *) malloc(sizeof(ExpandFile)); if(!ef) { fprintf(stderr, "new_ExpandFile: Insufficient memory.\n"); return NULL; }; /* * Before attempting any operation that might fail, initialize the * container at least up to the point at which it can safely be passed * to del_ExpandFile(). */ ef->sg = NULL; ef->cache.mem = NULL; ef->cache.head = NULL; ef->cache.next = NULL; ef->cache.tail = NULL; ef->path = NULL; ef->home = NULL; ef->result.files = NULL; ef->result.nfile = 0; ef->usrnam[0] = '\0'; ef->envnam[0] = '\0'; ef->errmsg[0] = '\0'; /* * Allocate a list of string segments for storing filenames. */ ef->sg = _new_StringGroup(_pu_pathname_dim()); if(!ef->sg) return del_ExpandFile(ef); /* * Allocate a freelist for allocating directory cache nodes. */ ef->cache.mem = _new_FreeList("new_ExpandFile", sizeof(DirNode), DIR_CACHE_BLK); if(!ef->cache.mem) return del_ExpandFile(ef); /* * Allocate a pathname buffer. */ ef->path = _new_PathName(); if(!ef->path) return del_ExpandFile(ef); /* * Allocate an object for looking up home-directories. */ ef->home = _new_HomeDir(); if(!ef->home) return del_ExpandFile(ef); /* * Allocate an array for files. This will be extended later if needed. */ ef->files_dim = MATCH_BLK_FACT; ef->result.files = (char **) malloc(sizeof(ef->result.files[0]) * ef->files_dim); if(!ef->result.files) { fprintf(stderr, "new_ExpandFile: Insufficient memory to allocate array of files.\n"); return del_ExpandFile(ef); }; return ef; }