⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 dtelent是开源的开发项目
💻 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 + -