📄 utils.c
字号:
/* utils.c
* Copyright (c) 1997 David Cole
*
* Miscellaneous utilities
*/
#include <windows.h>
#include <ctype.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <direct.h>
#include "utils.h"
#include "dtelnet.h"
#include "term.h"
#include "log.h"
int strlcat(char* dst, const char* src, int size)
{
int len = size - strlen(dst);
if (len > 0) {
strncat(dst, src, len);
}
return strlen(dst);
}
int strlcpy(char* dst, const char* src, int size)
{
strncpy(dst, src, size);
return strlen(dst);
}
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
char* strsep(char** stringp, const char* delim)
{
char *s;
const char *spanp;
int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
/* Allocate some memory - abort program on failure
*
* Args:
* size - the amount of memory to allocate
*/
void* xmalloc(int size)
{
void* ret = malloc(size);
if (ret == NULL) {
MessageBox(termGetWnd(), "Out of memory", telnetAppName(),
MB_APPLMODAL | MB_ICONHAND | MB_OK);
telnetExit();
}
return ret;
}
/* Resize some previously allocated memory - abort program on failure
*
* Args:
* ptr - point to memory previously allocated
* size - the amount of memory to allocate
*/
void* xrealloc(void* ptr, int size)
{
void* ret = realloc(ptr, size);
if (ret == NULL) {
MessageBox(termGetWnd(), "Out of memory", telnetAppName(),
MB_APPLMODAL | MB_ICONHAND | MB_OK);
telnetExit();
}
return ret;
}
/* Free some previously allocated memory - abort program on failure
*
* Args:
* ptr - point to memory previously allocated
*/
void xfree(void* ptr)
{
if (ptr == NULL) {
MessageBox(termGetWnd(), "xfree: NULL pointer", telnetAppName(),
MB_APPLMODAL | MB_ICONHAND | MB_OK);
telnetExit();
}
free(ptr);
}
/* Copy a string using xmalloc - abort program on failure
*
* Args:
* str - point to string to be copied
*/
char* xstrdup(const char *str)
{
int len = strlen(str) + 1;
char* cp;
if (len == 0) {
MessageBox(termGetWnd(), "xstrdup: NULL pointer", telnetAppName(),
MB_APPLMODAL | MB_ICONHAND | MB_OK);
telnetExit();
}
cp = xmalloc(len);
strlcpy(cp, str, len);
return cp;
}
/* Determine the the directory that the application was started from
*
* Args:
* instance - application instance handle
* path - return directory application was started from
*/
void getExePath(HINSTANCE instance, char* path)
{
char* str; /* scan over application path */
int len; /* length of application path */
len = GetModuleFileName(instance, path, _MAX_PATH);
if (len == 0) {
/* Could not determine application path - just use current
* working directory
*/
getcwd(path, _MAX_PATH);
len = strlen(path);
if (path[len - 1] != '\\') {
path[len++] = '\\';
path[len] = '\0';
}
return;
}
/* Strip off filename leaving path
*/
for (str = path + len; str > path; len--, str--) {
if (*str == '\\' || *str == ':') {
*++str = '\0';
break;
}
}
}
/* Split a string into a number of fields using delimiter
*
* Args:
* str - string to be split in place
* delim - delimiter to split fields by
* fields - array to receive pointers to fields
* maxFields - number of fields that will fit in array
*/
int split(char* str, char delim, char** fields, int maxFields)
{
int num; /* iterate over fields */
for (num = 0; num < maxFields;) {
fields[num++] = str;
str = strchr(str, delim);
if (str == NULL)
break;
*str++ = '\0';
}
return num;
}
#ifdef USE_ASSERT
void assertFail(char* str, char* file, int line)
{
char where[256];
logStop();
sprintf(where, "In %s, line %d", file, line);
MessageBox(termGetWnd(), str, where, MB_APPLMODAL | MB_ICONHAND | MB_OK);
}
#endif
#ifdef USE_ODS
void ods(char* fmt, ...)
{
char msg[512];
va_list ap;
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
OutputDebugString(msg);
}
#endif
BOOL isNonBlank(char* str)
{
while (*str != '\0')
if (isalnum(*str++))
return TRUE;
return FALSE;
}
/* Utility functions for dealing with escape codes
*
* copied from termdef.c of Mark Melvin
*/
int escape (const char *from, int len, char* to, int maxlen)
{
char tohex[16] = "0123456789ABCDEF";
const char *cc;
char *co;
int c;
for (cc= from, co= to; len>0 && co-to<=maxlen; ++cc, --len) {
c = *(unsigned char *)cc;
if (c=='"') {
if (co-to+2>maxlen) break;
*co++ = '\\';
*co++ = '"';
} else if (c=='\r') {
if (co-to+2>maxlen) break;
*co++ = '\\';
*co++ = 'r';
} else if (c=='\n') {
if (co-to+2>maxlen) break;
*co++ = '\\';
*co++ = 'n';
} else if ((c >= 0x20 && c < 0x7F) ||
(c > 0xA0 && c < 0xFF)) {
*co++ = *cc;
} else {
if (co-to+4>maxlen) break;
*co++ = '\\';
*co++ ='x';
*co++ = tohex[(*cc & 0xF0)>>4];
*co++ = tohex[*cc & 0x0F];
}
}
if (co-to<maxlen)*co = 0; /* null-terminate result */
return (int)(co-to);
}
int fromhex (char hex)
{
if ((hex>='0') && (hex<='9')) return hex-'0';
else if((hex>='A') && (hex<='F')) return hex-'A'+10;
else if((hex>='a') && (hex<='f')) return hex-'a'+10;
else
return 0;
}
int unescape (const char* from, int len, char* to, int maxlen)
{
const char *cc;
char *co;
BOOL in_slash;
int in_hex, code;
cc = from;
co = to;
in_slash = FALSE;
in_hex = 0;
for (; len>0 && *cc && co-to<maxlen; ++cc, --len) {
if (in_hex==2) {
code = 16*fromhex (*cc);
in_hex = 1;
} else if (in_hex==1) {
code += fromhex (*cc);
*co++ = (char)code;
in_hex = 0;
} else if (!in_slash) {
if (*cc != '\\') *co++ = *cc;
else in_slash = TRUE;
} else { /* in_slash */
switch (*cc){
case 'n': *co++ = '\n'; break;
case 'r': *co++ = '\r'; break;
case '\\': *co++ = '\\'; break;
case 't': *co++ = '\t'; break;
case 'b': *co++ = '\b'; break;
case '\'': *co++ = '\''; break;
case '\"': *co++ = '\"'; break;
case 'x': in_hex = 2; break;
case '0': *co++ = '\0'; break;
default: *co++ = *cc;
}
in_slash = FALSE;
}
}
if (co-to<maxlen) *co='\0';
return (int)(co-to);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -