📄 misc.c
字号:
/* * misc.c -- Miscellaneous routines. * * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. * * See the file "license.txt" for usage and redistribution license requirements *//********************************* Includes ***********************************/#if UEMF #include "uemf.h"#else #include "basic/basicInternal.h"#endif/********************************* Defines ************************************//* * Sprintf buffer structure. Make the increment 64 so that * a balloc can use a 64 byte block. */#define STR_REALLOC 0x1 /* Reallocate the buffer as required */#define STR_INC 64 /* Growth increment */typedef struct { char_t *s; /* Pointer to buffer */ int size; /* Current buffer size */ int max; /* Maximum buffer size */ int count; /* Buffer count */ int flags; /* Allocation flags */} strbuf_t;/* * Sprintf formatting flags */enum flag { flag_none = 0, flag_minus = 1, flag_plus = 2, flag_space = 4, flag_hash = 8, flag_zero = 16, flag_short = 32, flag_long = 64};/************************** Forward Declarations ******************************/static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize);static void put_char(strbuf_t *buf, char_t c);static void put_string(strbuf_t *buf, char_t *s, int len, int width, int prec, enum flag f);static void put_ulong(strbuf_t *buf, unsigned long int value, int base, int upper, char_t *prefix, int width, int prec, enum flag f);/************************************ Code ************************************//* * "basename" returns a pointer to the last component of a pathname * LINUX and LynxOS have their own basename function */#if ! LINUX && ! LYNX && ! __rtems__char_t *basename(char_t *name){ char_t *cp;#if NW || WIN if (((cp = gstrrchr(name, '\\')) == NULL) && ((cp = gstrrchr(name, '/')) == NULL)) { return name;#else if ((cp = gstrrchr(name, '/')) == NULL) { return name;#endif } else if (*(cp + 1) == '\0' && cp == name) { return name; } else if (*(cp + 1) == '\0' && cp != name) { return T(""); } else { return ++cp; }}#endif /* ! LINUX & ! LYNX *//******************************************************************************//* * Returns a pointer to the directory component of a pathname. bufsize is * the size of the buffer in BYTES! */char_t *dirname(char_t *buf, char_t *name, int bufsize){ char_t *cp; int len; a_assert(name); a_assert(buf); a_assert(bufsize > 0);#if WIN || NW if ((cp = gstrrchr(name, '/')) == NULL && (cp = gstrrchr(name, '\\')) == NULL)#else if ((cp = gstrrchr(name, '/')) == NULL)#endif { gstrcpy(buf, T(".")); return buf; } if ((*(cp + 1) == '\0' && cp == name)) { gstrncpy(buf, T("."), TSZ(bufsize)); gstrcpy(buf, T(".")); return buf; } len = cp - name; if (len < bufsize) { gstrncpy(buf, name, len); buf[len] = '\0'; } else { gstrncpy(buf, name, TSZ(bufsize)); buf[bufsize - 1] = '\0'; } return buf;}/******************************************************************************//* * sprintf and vsprintf are bad, ok. You can easily clobber memory. Use * fmtAlloc and fmtValloc instead! These functions do _not_ support floating * point, like %e, %f, %g... */int fmtAlloc(char_t **s, int n, char_t *fmt, ...){ va_list ap; int result; a_assert(s); a_assert(fmt); *s = NULL; va_start(ap, fmt); result = dsnprintf(s, n, fmt, ap, 0); va_end(ap); return result;}/******************************************************************************//* * Support a static buffer version for small buffers only! */int fmtStatic(char_t *s, int n, char_t *fmt, ...){ va_list ap; int result; a_assert(s); a_assert(fmt); a_assert(n <= 256); if (n <= 0) { return -1; } va_start(ap, fmt); result = dsnprintf(&s, n, fmt, ap, 0); va_end(ap); return result;}/******************************************************************************//* * This function appends the formatted string to the supplied string, * reallocing if required. */int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...){ va_list ap; int result; a_assert(s); a_assert(fmt); if (msize == -1) { *s = NULL; } va_start(ap, fmt); result = dsnprintf(s, n, fmt, ap, msize); va_end(ap); return result;}/******************************************************************************//* * A vsprintf replacement. */int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg){ a_assert(s); a_assert(fmt); *s = NULL; return dsnprintf(s, n, fmt, arg, 0);}/******************************************************************************//* * Dynamic sprintf implementation. Supports dynamic buffer allocation. * This function can be called multiple times to grow an existing allocated * buffer. In this case, msize is set to the size of the previously allocated * buffer. The buffer will be realloced, as required. If msize is set, we * return the size of the allocated buffer for use with the next call. For * the first call, msize can be set to -1. */static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize){ strbuf_t buf; char_t c; a_assert(s); a_assert(fmt); memset(&buf, 0, sizeof(buf)); buf.s = *s; if (*s == NULL || msize != 0) { buf.max = size; buf.flags |= STR_REALLOC; if (msize != 0) { buf.size = max(msize, 0); } if (*s != NULL && msize != 0) { buf.count = gstrlen(*s); } } else { buf.size = size; } while ((c = *fmt++) != '\0') { if (c != '%' || (c = *fmt++) == '%') { put_char(&buf, c); } else { enum flag f = flag_none; int width = 0; int prec = -1; for ( ; c != '\0'; c = *fmt++) { if (c == '-') { f |= flag_minus; } else if (c == '+') { f |= flag_plus; } else if (c == ' ') { f |= flag_space; } else if (c == '#') { f |= flag_hash; } else if (c == '0') { f |= flag_zero; } else { break; } } if (c == '*') { width = va_arg(arg, int); if (width < 0) { f |= flag_minus; width = -width; } c = *fmt++; } else { for ( ; gisdigit((int)c); c = *fmt++) { width = width * 10 + (c - '0'); } } if (c == '.') { f &= ~flag_zero; c = *fmt++; if (c == '*') { prec = va_arg(arg, int); c = *fmt++; } else { for (prec = 0; gisdigit((int)c); c = *fmt++) { prec = prec * 10 + (c - '0'); } } } if (c == 'h' || c == 'l') { f |= (c == 'h' ? flag_short : flag_long); c = *fmt++; } if (c == 'd' || c == 'i') { long int value; if (f & flag_short) { value = (short int) va_arg(arg, int); } else if (f & flag_long) { value = va_arg(arg, long int); } else { value = va_arg(arg, int); } if (value >= 0) { if (f & flag_plus) { put_ulong(&buf, value, 10, 0, T("+"), width, prec, f); } else if (f & flag_space) { put_ulong(&buf, value, 10, 0, T(" "), width, prec, f); } else { put_ulong(&buf, value, 10, 0, NULL, width, prec, f); } } else { put_ulong(&buf, -value, 10, 0, T("-"), width, prec, f); } } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') { unsigned long int value; if (f & flag_short) { value = (unsigned short int) va_arg(arg, unsigned int); } else if (f & flag_long) { value = va_arg(arg, unsigned long int); } else { value = va_arg(arg, unsigned int); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -