/* * Log <fmt> and the subsequent parameters through <logger>, *without* any * prefixes. Useful to continue a previous log message. */ void logAppend(Logger *logger, const char *fmt, ...) { va_list ap; pthread_mutex_lock(&logger->access); bufClear(&logger->scratch); va_start(ap, fmt); bufAddV(&logger->scratch, fmt, ap); va_end(ap); log_output(logger); pthread_mutex_unlock(&logger->access); }
/* * Send out a logging message using <fmt> and the subsequent parameters through * <logger>. <file>, <line> and <func> are filled in by the logWrite macro, * which should be used to call this function. */ void _logWrite(Logger *logger, const char *file, int line, const char *func, const char *fmt, ...) { va_list ap; pthread_mutex_lock(&logger->access); bufClear(&logger->scratch); log_write_prefixes(logger, file, line, func); va_start(ap, fmt); bufAddV(&logger->scratch, fmt, ap); va_end(ap); log_output(logger); pthread_mutex_unlock(&logger->access); }
int main(int argc, char *argv[]) { Buffer buf1 = { 0 }; Buffer buf2 = { 0 }; Buffer *buf3; bufClear(&buf1); make_sure_that(bufLen(&buf1) == 0); make_sure_that(bufIsEmpty(&buf1)); bufAdd(&buf1, "ABCDEF", 3); make_sure_that(bufLen(&buf1) == 3); make_sure_that(!bufIsEmpty(&buf1)); make_sure_that(strcmp(bufGet(&buf1), "ABC") == 0); bufAddC(&buf1, 'D'); make_sure_that(bufLen(&buf1) == 4); make_sure_that(strcmp(bufGet(&buf1), "ABCD") == 0); bufAddF(&buf1, "%d", 1234); make_sure_that(bufLen(&buf1) == 8); make_sure_that(strcmp(bufGet(&buf1), "ABCD1234") == 0); bufAddS(&buf1, "XYZ"); make_sure_that(bufLen(&buf1) == 11); make_sure_that(strcmp(bufGet(&buf1), "ABCD1234XYZ") == 0); bufSet(&buf1, "ABCDEF", 3); make_sure_that(bufLen(&buf1) == 3); make_sure_that(strcmp(bufGet(&buf1), "ABC") == 0); bufSetC(&buf1, 'D'); make_sure_that(bufLen(&buf1) == 1); make_sure_that(strcmp(bufGet(&buf1), "D") == 0); bufSetF(&buf1, "%d", 1234); make_sure_that(bufLen(&buf1) == 4); make_sure_that(strcmp(bufGet(&buf1), "1234") == 0); bufSetS(&buf1, "ABCDEF"); make_sure_that(bufLen(&buf1) == 6); make_sure_that(strcmp(bufGet(&buf1), "ABCDEF") == 0); bufClear(&buf1); make_sure_that(bufLen(&buf1) == 0); make_sure_that(strcmp(bufGet(&buf1), "") == 0); bufSet(&buf1, "ABC", 3); bufSet(&buf2, "DEF", 3); buf3 = bufCat(&buf1, &buf2); make_sure_that(&buf1 == buf3); make_sure_that(bufLen(&buf1) == 6); make_sure_that(strcmp(bufGet(&buf1), "ABCDEF") == 0); make_sure_that(bufLen(&buf2) == 3); make_sure_that(strcmp(bufGet(&buf2), "DEF") == 0); bufSetF(&buf1, "ABCDEF"); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 0, 0)), "ABCDEF") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 1, 0)), "BCDEF") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 0, 1)), "BCDE") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 1, 1)), "CD") == 0); make_sure_that(strcmp(bufGet(bufTrim(&buf1, 3, 3)), "") == 0); bufPack(&buf1, PACK_INT8, 0x01, PACK_INT16, 0x0123, PACK_INT32, 0x01234567, PACK_INT64, 0x0123456789ABCDEF, PACK_FLOAT, 0.0, PACK_DOUBLE, 0.0, PACK_STRING, "Hoi1", PACK_DATA, "Hoi2", 4, PACK_RAW, "Hoi3", 4, END); make_sure_that(bufLen(&buf1) == 47); make_sure_that(memcmp(bufGet(&buf1), "\x01" "\x01\x23" "\x01\x23\x45\x67" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x04Hoi1" "\x00\x00\x00\x04Hoi2" "Hoi3", 47) == 0); { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; float f32; double f64; char *string, *data, raw[4]; int data_size; bufUnpack(&buf1, PACK_INT8, &u8, PACK_INT16, &u16, PACK_INT32, &u32, PACK_INT64, &u64, PACK_FLOAT, &f32, PACK_DOUBLE, &f64, PACK_STRING, &string, PACK_DATA, &data, &data_size, PACK_RAW, &raw, sizeof(raw), END); make_sure_that(u8 == 0x01); make_sure_that(u16 == 0x0123); make_sure_that(u32 == 0x01234567); make_sure_that(u64 == 0x0123456789ABCDEF); make_sure_that(f32 == 0.0); make_sure_that(f64 == 0.0); make_sure_that(memcmp(string, "Hoi1", 5) == 0); make_sure_that(memcmp(data, "Hoi2", 4) == 0); make_sure_that(data_size == 4); make_sure_that(memcmp(raw, "Hoi3", 4) == 0); } { bufUnpack(&buf1, PACK_INT8, NULL, PACK_INT16, NULL, PACK_INT32, NULL, PACK_INT64, NULL, PACK_FLOAT, NULL, PACK_DOUBLE, NULL, PACK_STRING, NULL, PACK_DATA, NULL, NULL, PACK_RAW, NULL, 4, END); } { const char *name[] = { "Mills", "Berry", "Buck", "Stipe" }; bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, TRUE, "%s", name[0]); make_sure_that(strcmp(bufGet(&buf1), "Mills") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[1]); make_sure_that(strcmp(bufGet(&buf1), "Mills and Berry") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[1]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[2]); make_sure_that(strcmp(bufGet(&buf1), "Mills, Berry and Buck") == 0); bufClear(&buf1); bufList(&buf1, ", ", " and ", TRUE, FALSE, "%s", name[0]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[1]); bufList(&buf1, ", ", " and ", FALSE, FALSE, "%s", name[2]); bufList(&buf1, ", ", " and ", FALSE, TRUE, "%s", name[3]); make_sure_that(strcmp(bufGet(&buf1), "Mills, Berry, Buck and Stipe") == 0); } bufReset(&buf1); bufReset(&buf2); return errors; }
/* * Replace <buf> with a string formatted according to <fmt> and the subsequent parameters contained * in <ap>. */ Buffer *bufSetV(Buffer *buf, const char *fmt, va_list ap) { bufClear(buf); return bufAddV(buf, fmt, ap); }
/* * Set <buf> to the single character <c>. */ Buffer *bufSetC(Buffer *buf, char c) { bufClear(buf); return bufAdd(buf, &c, 1); }
/* * Replace <buf> with the <len> bytes starting at <data>. */ Buffer *bufSet(Buffer *buf, const void *data, size_t len) { bufClear(buf); return bufAdd(buf, data, len); }
/* * Process input from <in> and write the result to <out>. The name of the original file from which * prototypes are to be extracted is in <input>. */ static int process(const char *input, FILE *in, FILE *out) { char *current_file = strdup(input); Buffer comment = { 0 }, declaration = { 0 }; int c; while ((c = fgetc(in)) != EOF) { if (c == '#') { handle_preprocessor_line(in, ¤t_file); } else if (c == '/') { bufSetC(&comment, c); handle_comment(in, &comment); } else if (!isspace(c) && c != ';') { bufSetC(&declaration, c); handle_declaration(in, &declaration); if (strchr(bufGet(&declaration), '(') != NULL && strcmp(current_file, input) == 0) { const char *str; int len; while (TRUE) { str = bufGet(&declaration); len = bufLen(&declaration); if (isspace(str[0])) bufTrim(&declaration, 1, 0); else break; } while (TRUE) { str = bufGet(&declaration); len = bufLen(&declaration); if (isspace(str[len - 1])) bufTrim(&declaration, 0, 1); else break; } if (include_static == TRUE || strncmp(str, "static", 6) != 0) { fputc('\n', out); if (include_comment && bufLen(&comment) > 0) { fputs(bufGet(&comment), out); fputc('\n', out); } fputs(str, out); if (str[len - 1] != ';') fputc(';', out); fputc('\n', out); } } bufClear(&comment); } } bufReset(&comment); bufReset(&declaration); free(current_file); return 0; }