CTRACE(tfp, "HTAA_readGroupFile: reading group file `%s'\n", filename);
CTRACE((tfp, "HTAA_readGroupFile: reading group file `%s'\n", filename));
PUBLIC GroupDefList *HTAA_readGroupFile ARGS1(CONST char *, filename){    FILE *fp;    GroupCache *group_cache;    if (!filename || !*filename) return NULL;    if (!group_cache_list)	group_cache_list = HTList_new();    else {	GroupCacheList *cur = group_cache_list;	while (NULL != (group_cache = (GroupCache*)HTList_nextObject(cur))) {	    if (!strcmp(filename, group_cache->group_filename)) {		CTRACE(tfp, "%s '%s' %s\n",			    "HTAA_readGroupFile: group file",			    filename, "already found in cache");		return group_cache->group_list;	    } /* if cache match */	} /* while cached files remain */    } /* cache exists */    CTRACE(tfp, "HTAA_readGroupFile: reading group file `%s'\n",		filename);    if (!(fp = fopen(filename, "r"))) {	CTRACE(tfp, "%s '%s'\n",		    "HTAA_readGroupFile: unable to open group file",		    filename);	return NULL;    }    if (!(group_cache = (GroupCache*)calloc(1, sizeof(GroupCache))))	outofmem(__FILE__, "HTAA_readGroupFile");    group_cache->group_filename = NULL;    StrAllocCopy(group_cache->group_filename, filename);    group_cache->group_list = parse_group_file(fp);    HTList_addObject(group_cache_list, (void*)group_cache);    fclose(fp);    CTRACE(tfp, "Read group file '%s', results follow:\n", filename);    if (TRACE)	print_group_def_list(group_cache->group_list);    return group_cache->group_list;}