📄 stringtools.c
字号:
/* stringtools.c - convenient string utility functions Copyright (C) 1996-2000 Paul Sheer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "global.h"#include <stdio.h>#include <stdlib.h>#include "my_string.h"#include <stdarg.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <errno.h>#include "stringtools.h"#include "regex.h"#include "time.h"#include "mad.h"/* This cats a whole lot of strings together. It has the advantage that the return result will be free'd automatically, and MUST NOT be free'd by the caller. It will hold the most recent NUM_STORED strings. */#define NUM_STORED 256static char *stacked[NUM_STORED] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};char *catstrs (const char *first,...){ static int i = 0; va_list ap; int len; char *data; if (!first) return 0; len = strlen (first); va_start (ap, first); while ((data = va_arg (ap, char *)) != 0) len += strlen (data); len++; i = (i + 1) % NUM_STORED; if (stacked[i]) free (stacked[i]); stacked[i] = malloc (len); va_end (ap); va_start (ap, first); strcpy (stacked[i], first); while ((data = va_arg (ap, char *)) != 0) strcat (stacked[i], data); va_end (ap); return stacked[i];}void catstrs_clean (void){ int i; for (i = 0; i < NUM_STORED; i++) if (stacked[i]) { free (stacked[i]); stacked[i] = 0; }}char *space_string (const char *s){ char *r, *p; int i; if (!s) return 0; p = r = malloc (strlen (s) + 3); while (*s == ' ') s++; *r++ = ' '; while (*s) { if (*s != '&') *r++ = *s; s++; } *r = '\0'; for (i = strlen (p) - 1; i > 0; i--) { if (p[i] == ' ') p[i] = '\0'; else break; } r = p + strlen (p); *r++ = ' '; *r = '\0'; return p;}/* alternative to free() */void destroy (void **p){ if (*p) { free (*p); *p = 0; }}char *strcasechr (const char *p, int c){ unsigned char *s = (unsigned char *) p; for (; my_lower_case ((int) *s) != my_lower_case ((int) c); ++s) if (*s == '\0') return 0; return (char *) s;}char *itoa (int i){ static char t[20]; char *s = t + 19; int j = i; i = abs (i); *s-- = 0; do { *s-- = i % 10 + '0'; } while ((i = i / 10)); if (j < 0) *s-- = '-'; return ++s;}/* this comes from the Midnight Commander src/tools.c */char *get_current_wd (char *buffer, int size){ char *p;#ifdef HAVE_GETCWD p = getcwd (buffer, size - 1);#else p = (char *) getwd (buffer);#endif p[size - 1] = '\0'; return p;}/* cd's to path and sets current_dir variable if getcwd works, else set current_dir to "". */extern char current_dir[];int change_directory (const char *path){ int e; e = chdir (path); if (e < 0) return e; if (!get_current_wd (current_dir, MAX_PATH_LEN)) strcpy (current_dir, "/"); return 0;}short *shortset (short *s, int c, size_t n){ short *r = s; while (n--) *s++ = c; return r;}char *name_trunc (const char *txt, int trunc_len){ static char x[1024]; int txt_len, y; txt_len = strlen (txt); if (txt_len <= trunc_len) { strcpy (x, txt); return x; } y = trunc_len % 2; strncpy (x, txt, (trunc_len / 2) + y); strncpy (x + (trunc_len / 2) + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); x[(trunc_len / 2) + y] = '~'; x[trunc_len] = 0; return x;}int prop_font_strcolmove (unsigned char *str, int i, int column);int strcolmove (unsigned char *str, int i, int column){ return prop_font_strcolmove (str, i, column);}/*move to col character from beginning of line with i in the line somewhere. *//*If col is past the end of the line, it returns position of end of line */long strfrombeginline (const char *s, int i, int col){ unsigned char *str = (unsigned char *) s; if (i < 0) {/* NLS ? */ fprintf (stderr, "strfrombeginline called with negative index.\n"); exit (1); } while (i--) if (str[i] == '\n') { i++; break; } if (i < 0) i = 0; if (!col) return i; return strcolmove (str, i, col);}/* strip backspaces from the nroff file to produce normal text. returns strlen(result) if l is non null */char *str_strip_nroff (char *t, int *l){ unsigned char *s = (unsigned char *) t; unsigned char *r, *q; int p; q = r = malloc (strlen (t) + 2); if (!r) return 0; for (p = 0; s[p]; p++) { while (s[p + 1] == '\b' && isprint (s[p + 2]) && isprint (s[p])) p += 2; *q++ = s[p]; } *q = 0; if (l) *l = ((unsigned long) q - (unsigned long) r); return (char *) r;}long countlinesforward (const char *text, long from, long amount, long lines, int width){ if (amount) { int i = 0; amount += from; for (;;) { from = strcolmove ((unsigned char *) text, from, width); if (from >= amount || !text[from]) return i; i++; from++; } } else if (lines) { int i; for (i = 0; i < lines; i++) { int q; q = strcolmove ((unsigned char *) text, from, width); if (!text[q]) break; from = q + 1; } return from; } return 0;}/* returns pos of begin of line moved to *//* move forward from i, `lines' can be negative --- moveing backward */long strmovelines (const char *str, long from, long lines, int width){ int p, q; if (lines > 0) return countlinesforward (str, from, 0, lines, width); if (lines == 0) return from; else { int line = 0; p = from; for (; p > 0;) { q = p; p = strfrombeginline (str, q - 1, 0); line += countlinesforward (str, p, q - p, 0, width); if (line > -lines) return countlinesforward (str, p, 0, line + lines, width); if (line == -lines) return p; } return 0; }}/*returns a positive or negative count of lines */long strcountlines (const char *str, long i, long amount, int width){ int lines, p; if (amount > 0) { return countlinesforward (str, i, amount, 0, width); } if (amount == 0) return 0; if (i + amount < 0) amount = -i; p = strfrombeginline (str, i + amount, 0); lines = countlinesforward (str, p, i + amount - p, 0, width); return -countlinesforward (str, p, i - p, 0, width) + lines;}/* returns a null terminated string. The string is a copy of the line beginning at p and ending at '\n' in the string src. The result must not be free'd. This routine caches the last four results. */char *strline (const char *src, int p){ static char line[4][1024]; static int last = 0; int i = 0; char *r; while (src[p] != '\n' && src[p] && i < 1000) { i++; p++; } r = line[last & 3]; memcpy (r, src + p - i, i); r[i] = 0; last++; return r;}size_t strnlen (const char *s, size_t count){ const char *sc; for (sc = s; count-- && *sc != '\0'; ++sc) /* nothing */ ; return sc - s;}#ifdef CRASHES_ON_STARTUPsize_t vfmtlen (const char *fmt, va_list ap){ char *p, *s; size_t i; p = malloc (8192); vsprintf (p, fmt, ap); i = strlen (p); free (p); return i;}#else#define is_digit(x) ((x) >= '0' && (x) <= '9')#define scount(v) { \ *p1++ = *p++; \ *p1++ = '%'; \ *p1++ = 'n'; \ *p1 = 0; \ sprintf(s,q1,v,&n); \ count += n; \ }/* Returns the length of a string that would be printed if this command was vprintf, but prints nothing */size_t vfmtlen (const char *fmt, va_list ap){ char *q, *p, s[66]; int n; char q1[32]; char *p1; size_t count = 0; int min, max; p = q = (char *) fmt; while ((p = strchr (p, '%'))) { count += (size_t) ((unsigned long) p - (unsigned long) q); q = p; p1 = q1; *p1++ = *p++; if (*p == '%') { p++; count++; q = p; continue; } if (*p == 'n') { p++; q = p; *va_arg (ap, int *) = count; continue; } if (*p == '#') *p1++ = *p++; if (*p == '0') *p1++ = *p++; if (*p == '-') *p1++ = *p++; if (*p == '+') *p1++ = *p++; min = 0; max = (1 << 30); if (*p == '*') { p++; strcpy (p1, itoa (min = va_arg (ap, int))); p1 += strlen (p1); } else { char *g = p1; while (is_digit (*p)) *p1++ = *p++; *p1 = 0; if (*g) min = atoi (g); } if (*p == '.') *p1++ = *p++; if (*p == '*') { p++; strcpy (p1, itoa (max = va_arg (ap, int))); p1 += strlen (p1); } else { char *g = p1; while (is_digit (*p)) *p1++ = *p++; *p1 = 0; if (*g) max = atoi (g); } if (*p == 's') { if ((n = strnlen (va_arg (ap, char *), max)) < min) n = min; count += n; p++; } else if (*p == 'h') { if (strchr ("diouxX", *p))#if 0 /* this is not allowed by ANSI */ scount (va_arg (ap, short));#else scount (va_arg (ap, int));#endif } else if (*p == 'l') { *p1++ = *p++; if (strchr ("diouxX", *p)) scount (va_arg (ap, long)); } else if (strchr ("cdiouxX", *p)) { scount (va_arg (ap, int)); } else if (*p == 'L') { *p1++ = *p++; if (strchr ("EefgG", *p)) scount (va_arg (ap, double)); /* should be long double, but gives warnings on some machines */ } else if (strchr ("EefgG", *p)) { scount (va_arg (ap, double)); } else if (strchr ("DOU", *p)) { scount (va_arg (ap, long)); } else if (*p == 'p') { scount (va_arg (ap, void *)); } q = p; } return count + strlen (q);}#endif /* !CRASHES_ON_STARTUP *//* #define DEBUG_VFMTLEN *//* vsprintf with memory allocation. result must be free'd */#ifdef HAVE_MADchar *mad_vsprintf_alloc (const char *fmt, va_list ap, char *file, int line)#elsechar *vsprintf_alloc (const char *fmt, va_list ap)#endif{ char *s; size_t l;#ifdef HAVE_MAD s = mad_alloc ((l = vfmtlen (fmt, ap)) + 1, file, line);#else s = malloc ((l = vfmtlen (fmt, ap)) + 1);#endif if (!s)/* NLS ? */ fprintf (stderr, "cooledit:%s:%d: malloc return zero\n", __FILE__, __LINE__); s[l] = 0; vsprintf (s, fmt, ap); if (s[l]#ifdef DEBUG_VFMTLEN || strlen (s) != l#endif )/* this is just in case there is a bug in vfmtlen above (it also happens if you pass a incorrect format string) *//* NLS ? */ fprintf (stderr, "cooledit:%s:%d: vsprintf wrote out of bounds\n", __FILE__, __LINE__); return s;}char *sprintf_alloc (const char *fmt,...){ char *s; va_list ap; va_start (ap, fmt); s = vsprintf_alloc (fmt, ap); va_end (ap); return s;}int readall (int fd, char *buf, int len){ int count; int total = 0; if (len <= 0) return 0; for (;;) { count = read (fd, buf, len); if (count == -1) { if (errno == EINTR) continue; return -1; } buf += count; len -= count; total += count; if (len <= 0) break; } return total;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -