📄 output.c
字号:
/* * output.c * Global utility functions. * * Copyright (c) 2003 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include "disktype.h"#include <stdarg.h>/* * output functions */#define LEVELS (8)static const char *insets[LEVELS] = { "", " ", " ", " ", " ", " ", " ", " ", };static char line_akku[4096];void print_line(int level, const char *fmt, ...) { va_list par; va_start(par, fmt); vsnprintf(line_akku, 4096, fmt, par); va_end(par); if (level >= LEVELS) bailout("Recursion loop caught"); printf("%s%s\n", insets[level], line_akku);}void start_line(const char *fmt, ...) { va_list par; va_start(par, fmt); vsnprintf(line_akku, 4096, fmt, par); va_end(par);}void continue_line(const char *fmt, ...) { va_list par; int len = strlen(line_akku); va_start(par, fmt); vsnprintf(line_akku + len, 4096 - len, fmt, par); va_end(par);}void finish_line(int level) { if (level >= LEVELS) bailout("Recursion loop caught"); printf("%s%s\n", insets[level], line_akku);}/* * formatting functions *//* TODO: make all of this safe from buffer overruns... *//* * format_raw_size() does the actual unit-suffix formatting. * * Returns an indicator for the format used: * 0 - rounded to some unit * 1 - whole multiple of some unit (return code limited to KiB) * 2 - plain bytes */static int format_raw_size(char *buf, U64 size) { int unit_index, dd; U64 unit_size, card; const char *unit_names[] = { "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", NULL }; const int dd_mult[4] = { 1, 10, 100, 1000 }; /* just a few bytes */ if (size < 1024) { sprintf(buf, "%llu bytes", size); return 2; } /* find a suitable unit */ for (unit_index = 0, unit_size = 1024; unit_names[unit_index] != NULL; unit_index++, unit_size <<= 10) { /* size is at least one of the next unit -> use that */ if (size >= 1024 * unit_size) continue; /* check integral multiples */ if ((size % unit_size) == 0) { card = size / unit_size; sprintf(buf, "%d %s", (int)card, unit_names[unit_index]); return unit_index ? 0 : 1; } /* find suitable number of decimal digits */ for (dd = 3; dd >= 1; dd--) { card = (size * dd_mult[dd] + (unit_size >> 1)) / unit_size; if (card >= 10000) continue; /* more than four significant digits */ sprintf(buf, "%d.%0*d %s", (int)(card / dd_mult[dd]), dd, (int)(card % dd_mult[dd]), unit_names[unit_index]); return 0; } } /* fallback (something wrong with the numbers?) */ strcpy(buf, "off the scale"); return 0;}void format_blocky_size(char *buf, U64 count, U32 blocksize, const char *blockname, const char *append) { int used; U64 total_size; char *p; char blocksizebuf[32]; total_size = count * blocksize; used = format_raw_size(buf, total_size); p = strchr(buf, 0); *p++ = ' '; *p++ = '('; if (used != 2) { sprintf(p, "%llu bytes, ", total_size); p = strchr(buf, 0); } if (blocksize == 512 && strcmp(blockname, "sectors") == 0) { sprintf(p, "%llu %s", count, blockname); } else { if (blocksize < 64*1024 && (blocksize % 1024) != 0) sprintf(blocksizebuf, "%lu bytes", blocksize); else format_raw_size(blocksizebuf, blocksize); sprintf(p, "%llu %s of %s", count, blockname, blocksizebuf); } p = strchr(buf, 0); if (append != NULL) { strcpy(p, append); p = strchr(buf, 0); } *p++ = ')'; *p++ = 0;}void format_size(char *buf, U64 size) { int used; used = format_raw_size(buf, size); if (used > 0) return; sprintf(strchr(buf, 0), " (%llu bytes)", size);}void format_size_verbose(char *buf, U64 size) { int used; used = format_raw_size(buf, size); if (used == 2) return; sprintf(strchr(buf, 0), " (%llu bytes)", size);}void format_ascii(void *from, char *to) { U8 *p = (U8 *)from; U8 *q = (U8 *)to; int c; while ((c = *p++)) { if (c >= 127 || c < 32) { *q++ = '<'; *q++ = "0123456789ABCDEF"[c >> 4]; *q++ = "0123456789ABCDEF"[c & 15]; *q++ = '>'; } else { *q++ = c; } } *q = 0;}void format_unicode(void *from, char *to) { U16 *p = (U16 *)from; U8 *q = (U8 *)to; U16 c; for (;;) { c = get_be_short(p); if (c == 0) break; p++; /* advance 2 bytes */ if (c >= 127 || c < 32) { *q++ = '<'; *q++ = "0123456789ABCDEF"[c >> 12]; *q++ = "0123456789ABCDEF"[(c >> 8) & 15]; *q++ = "0123456789ABCDEF"[(c >> 4) & 15]; *q++ = "0123456789ABCDEF"[c & 15]; *q++ = '>'; } else { *q++ = (U8)c; } } *q = 0;}void format_uuid(void *uuid, char *to, char* type, int ver) { U8 *from = uuid; int i, c, variant, version; if (memcmp(uuid, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) { strcpy(to, "nil"); return; } variant = from[8] >> 5; version = from[6] >> 4; for (i = 0; i < 16; i++) { c = *from++; *to++ = "0123456789ABCDEF"[c >> 4]; *to++ = "0123456789ABCDEF"[c & 15]; if (i == 3 || i == 5 || i == 7 || i == 9) *to++ = '-'; } ver = 0; if ((variant & 4) == 0) { /* 0 x x */ strcpy(type, "NCS"); } else if ((variant & 2) == 0) { /* 1 0 x */ strcpy(type, "DCE"); ver = version; } else if ((variant & 1) == 0) { /* 1 1 0 */ strcpy(type, "MS GUID"); } else { /* 1 1 1 */ strcpy(type, "(Reserved)"); }}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -