void biffMove(const char *destKey, const char *err, const char *srcKey) { unsigned int ii; size_t len; // to match signature of strlen() on 64 bits size_t max; char me[] = "biffMove", *buf; _biffEntry *dest, *src; _biffInit(); _biffCheckKey(destKey); _biffCheckKey(srcKey); /* if srcKey and destKey are the same, this degenerates to biffAdd() */ if (!strcmp(destKey, srcKey)) { biffAdd(srcKey, err); return; } dest = _biffFindKey(destKey); if (!dest) { dest = _biffAddKey(destKey); } src = _biffFindKey(srcKey); if (!src) { fprintf(stderr, "%s: WARNING: key \"%s\" unknown\n", me, srcKey); return; } max = 0; for (ii=0; ii<src->num; ii++) { len = strlen(src->err[ii]) + strlen(src->key) + 4; max = AIR_MAX(max, len); } buf = (char*)calloc(max+1, sizeof(char)); if (!buf) { fprintf(stderr, "%s: PANIC: can't allocate buffer\n", me); exit(1); } for (ii=0; ii<src->num; ii++) { sprintf(buf, "[%s] %s", srcKey, src->err[ii]); /* printf("%s: HEY: moving \"%s\" to %s\n", me, buf, destKey); */ _biffAddErr(dest, buf); } if (err) { _biffAddErr(dest, err); } biffDone(srcKey); free(buf); return; }
/* ******** biffSetStr() ** ** for when you want to allocate the buffer for the biff string, this is ** how you get the error message itself */ void biffSetStr(char *str, const char *key) { unsigned int max, sum; char me[] = "biffSetStr", *buf; _biffEntry *ent; if (!str) { fprintf(stderr, "%s: ERROR: got NULL buffer \"%s\"\n", me, key); return; } _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { /* error: not a key we remember seeing */ fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key); return; } _biffFindMaxAndSum(&max, &sum, ent); buf = (char*)calloc(max, sizeof(char)); if (!buf) { fprintf(stderr, "%s: PANIC: unable to allocate buffer\n", me); exit(1); } _biffGetStr(str, buf, ent); free(buf); return; }
/* ******** biffGet() ** ** creates a string which records all the errors at given key and ** returns it. Returns NULL in case of error. This function should ** be considered a glorified strdup(): it is the callers responsibility ** to free this string later */ char * biffGet(const char *key) { unsigned int max, sum; char me[] = "biffGet", *ret, *buf; _biffEntry *ent; _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { /* error: not a key we remember seeing */ fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key); return NULL; } _biffFindMaxAndSum(&max, &sum, ent); buf = (char*)calloc(max, sizeof(char)); ret = (char*)calloc(sum, sizeof(char)); if (!(buf && ret)) { fprintf(stderr, "%s: PANIC: unable to allocate buffers\n", me); exit(1); } _biffGetStr(ret, buf, ent); free(buf); return ret; }
/* ******** biffCheck() ** ** sees how many messages there are for a given key ** returns 0 if the key doesn't exist. */ int biffCheck(const char *key) { _biffEntry *ent; _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { return 0; } return ent->num; }
/* ******** biffAdd() ** ** Adds string "err" at key "key", whether or not there are any ** existing messages there. Since biffSet() was killed ** Wed Apr 20 11:11:51 EDT 2005, this has become the main biff ** function. */ void biffAdd(const char *key, const char *err) { _biffEntry *ent; _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { ent = _biffAddKey(key); } /* add the new message */ _biffAddErr(ent, err); return; }
/* ******** biffGetStrlen() ** ** for when you want to allocate the buffer for the biff string, this is ** how you learn its length */ int biffGetStrlen(const char *key) { unsigned int max, sum; char me[] = "biffGetStrlen"; _biffEntry *ent; _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { /* error: not a key we remember seeing */ fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key); return 0; } _biffFindMaxAndSum(&max, &sum, ent); return sum; }
/* ******** biffDone() ** ** frees everything associated with given key, and shrinks list of keys */ void biffDone(const char *key) { char me[]="biffDone"; int i, idx; _biffEntry *ent; _biffInit(); _biffCheckKey(key); ent = _biffFindKey(key); if (!ent) { fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key); return; } idx = _biffIdx; _biffNukeEntry(ent); for (i=idx; i<(int)_biffNum-1; i++) { _biffErr[i] = _biffErr[i+1]; } airArrayLenIncr(_biffAA, -1); return; }