📄 slstrops.c
字号:
/* -*- mode: C; mode: fold; -*- *//* string manipulation functions for S-Lang. *//* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */#include "slinclud.h"/*{{{ Include Files */#include <time.h>#ifndef __QNX__# if defined(__GO32__) || defined(__WATCOMC__)# include <dos.h># include <bios.h># endif#endif#if SLANG_HAS_FLOAT#include <math.h>#endif#include <string.h>#include <stdarg.h>#include <ctype.h>#ifndef isdigit# define isdigit(x) (((x) >= '0') && ((x) <= '9'))#endif#include "slang.h"#include "_slang.h"/*}}}*/#define USE_ALLOC_STSTRING 1/*{{{ Utility Functions */static unsigned char Utility_Char_Table [256];static unsigned char WhiteSpace_Lut[256];static void set_utility_char_table (char *pos) /*{{{*/{ register unsigned char *t = Utility_Char_Table; register unsigned char ch; memset ((char *) t, 0, sizeof (Utility_Char_Table)); while ((ch = (unsigned char) *pos++) != 0) t[ch] = 1;}/*}}}*/_INLINE_static unsigned char *make_whitespace_lut (void){ if (WhiteSpace_Lut[' '] != 1) { WhiteSpace_Lut[' '] = WhiteSpace_Lut['\r'] = WhiteSpace_Lut ['\n'] = WhiteSpace_Lut['\t'] = WhiteSpace_Lut ['\f'] = 1; } return WhiteSpace_Lut;}static unsigned char *make_lut (unsigned char *s, unsigned char *lut){ int reverse = 0; if (*s == '^') { reverse = 1; s++; } SLmake_lut (lut, s, reverse); return lut;}static unsigned int do_trim (char **beg, int do_beg, char **end, int do_end, char *white) /*{{{*/{ unsigned int len; char *a, *b; unsigned char *lut; if (white == NULL) lut = make_whitespace_lut (); else { set_utility_char_table (white); lut = Utility_Char_Table; } a = *beg; len = strlen (a); b = a + len; if (do_beg) while (lut[(unsigned char) *a]) a++; if (do_end) { b--; while ((b >= a) && (lut[(unsigned char) *b])) b--; b++; } len = (unsigned int) (b - a); *beg = a; *end = b; return len;}/*}}}*//*}}}*/static int pop_3_strings (char **a, char **b, char **c){ *a = *b = *c = NULL; if (-1 == SLpop_string (c)) return -1; if (-1 == SLpop_string (b)) { SLfree (*c); *c = NULL; return -1; } if (-1 == SLpop_string (a)) { SLfree (*b); SLfree (*c); *b = *c = NULL; return -1; } return 0;}static void free_3_strings (char *a, char *b, char *c){ SLfree (a); SLfree (b); SLfree (c);}static void strcat_cmd (void) /*{{{*/{ char *c, *c1; int nargs; int i; char **ptrs; unsigned int len;#if !USE_ALLOC_STSTRING char buf[256];#endif nargs = SLang_Num_Function_Args; if (nargs <= 0) nargs = 2; if (NULL == (ptrs = (char **)SLmalloc (nargs * sizeof (char *)))) return; memset ((char *) ptrs, 0, sizeof (char *) * nargs); c = NULL; i = nargs; len = 0; while (i != 0) { char *s; i--; if (-1 == SLang_pop_slstring (&s)) goto free_and_return; ptrs[i] = s; len += strlen (s); }#if USE_ALLOC_STSTRING if (NULL == (c = _SLallocate_slstring (len))) goto free_and_return;#else len++; /* \0 char */ if (len <= sizeof (buf)) c = buf; else if (NULL == (c = SLmalloc (len))) goto free_and_return;#endif c1 = c; for (i = 0; i < nargs; i++) { strcpy (c1, ptrs[i]); c1 += strlen (c1); } free_and_return: for (i = 0; i < nargs; i++) SLang_free_slstring (ptrs[i]); SLfree ((char *) ptrs);#if USE_ALLOC_STSTRING (void) _SLpush_alloced_slstring (c, len);#else if (c != buf) (void) SLang_push_malloced_string (c); /* NULL ok */ else (void) SLang_push_string (c);#endif}/*}}}*/static int _SLang_push_nstring (char *a, unsigned int len){ a = SLang_create_nslstring (a, len); if (a == NULL) return -1; return _SLang_push_slstring (a);}static void strtrim_cmd_internal (char *str, int do_beg, int do_end){ char *beg, *end, *white; int free_str; unsigned int len; /* Go through SLpop_string to get a private copy since it will be * modified. */ free_str = 0; if (SLang_Num_Function_Args == 2) { white = str; if (-1 == SLang_pop_slstring (&str)) return; free_str = 1; } else white = NULL; beg = str; len = do_trim (&beg, do_beg, &end, do_end, white); (void) _SLang_push_nstring (beg, len); if (free_str) SLang_free_slstring (str);} static void strtrim_cmd (char *str){ strtrim_cmd_internal (str, 1, 1);}static void strtrim_beg_cmd (char *str){ strtrim_cmd_internal (str, 1, 0);}static void strtrim_end_cmd (char *str){ strtrim_cmd_internal (str, 0, 1);}static void strcompress_cmd (void) /*{{{*/{ char *str, *white, *c; unsigned char *s, *beg, *end; unsigned int len; char pref_char; if (SLpop_string (&white)) return; if (SLpop_string (&str)) { SLfree (white); return; } /* The first character of white is the preferred whitespace character */ pref_char = *white; beg = (unsigned char *) str; (void) do_trim ((char **) &beg, 1, (char **) &end, 1, white); SLfree (white); /* Determine the effective length */ len = 0; s = (unsigned char *) beg; while (s < end) { len++; if (Utility_Char_Table[*s++]) { while ((s < end) && Utility_Char_Table[*s]) s++; } }#if USE_ALLOC_STSTRING c = _SLallocate_slstring (len);#else c = SLmalloc (len + 1);#endif if (c == NULL) { SLfree (str); return; } s = (unsigned char *) c; while (beg < end) { unsigned char ch = *beg++; if (0 == Utility_Char_Table[ch]) { *s++ = ch; continue; } *s++ = (unsigned char) pref_char; while ((beg < end) && Utility_Char_Table[*beg]) beg++; } *s = 0; #if USE_ALLOC_STSTRING (void) _SLpush_alloced_slstring (c, len);#else SLang_push_malloced_string(c);#endif SLfree(str);}/*}}}*/static int str_replace_cmd_1 (char *orig, char *match, char *rep, unsigned int max_num_replaces, char **new_strp) /*{{{*/{ char *s, *t, *new_str; unsigned int rep_len, match_len, new_len; unsigned int num_replaces; *new_strp = NULL; match_len = strlen (match); if (match_len == 0) return 0; num_replaces = 0; s = orig; while (num_replaces < max_num_replaces) { s = strstr (s, match); if (s == NULL) break; s += match_len; num_replaces++; } if (num_replaces == 0) return 0; max_num_replaces = num_replaces; rep_len = strlen (rep); new_len = (strlen (orig) - num_replaces * match_len) + num_replaces * rep_len; new_str = SLmalloc (new_len + 1); if (new_str == NULL) return -1; s = orig; t = new_str; for (num_replaces = 0; num_replaces < max_num_replaces; num_replaces++) { char *next_s; unsigned int len; next_s = strstr (s, match); /* cannot be NULL */ len = (unsigned int) (next_s - s); strncpy (t, s, len); t += len; strcpy (t, rep); t += rep_len; s = next_s + match_len; } strcpy (t, s); *new_strp = new_str; return (int) num_replaces;}/*}}}*/static void reverse_string (char *a){ char *b; b = a + strlen (a); while (b > a) { char ch; b--; ch = *a; *a++ = *b; *b = ch; }}static int strreplace_cmd (int *np){ char *orig, *match, *rep; char *new_str; int max_num_replaces; int ret; max_num_replaces = *np; if (-1 == pop_3_strings (&orig, &match, &rep)) return -1; if (max_num_replaces < 0) { reverse_string (orig); reverse_string (match); reverse_string (rep); ret = str_replace_cmd_1 (orig, match, rep, -max_num_replaces, &new_str); if (ret > 0) reverse_string (new_str); else if (ret == 0) reverse_string (orig); } else ret = str_replace_cmd_1 (orig, match, rep, max_num_replaces, &new_str); if (ret == 0) { if (-1 == SLang_push_malloced_string (orig)) ret = -1; orig = NULL; } else if (ret > 0) { if (-1 == SLang_push_malloced_string (new_str)) ret = -1; } free_3_strings (orig, match, rep); return ret;}static int str_replace_cmd (char *orig, char *match, char *rep){ char *s; int ret; ret = str_replace_cmd_1 (orig, match, rep, 1, &s); if (ret == 1) (void) SLang_push_malloced_string (s); return ret;} static void strtok_cmd (char *str){ _SLString_List_Type sl; unsigned char white_buf[256]; char *s; unsigned char *white; if (SLang_Num_Function_Args == 1) white = make_whitespace_lut (); else { white = white_buf; make_lut ((unsigned char *)str, white); if (-1 == SLang_pop_slstring (&str)) return; } if (-1 == _SLstring_list_init (&sl, 256, 1024)) goto the_return; s = str; while (*s != 0) { char *s0; s0 = s; /* Skip whitespace */ while ((*s0 != 0) && (0 != white[(unsigned char)*s0])) s0++; if (*s0 == 0) break; s = s0; while ((*s != 0) && (0 == white[(unsigned char) *s])) s++; /* sl deleted upon failure */ if (-1 == _SLstring_list_append (&sl, SLang_create_nslstring (s0, (unsigned int) (s - s0)))) goto the_return; } /* Deletes sl */ (void) _SLstring_list_push (&sl); the_return: if (white == white_buf) SLang_free_slstring (str);}/* This routine returns the string with text removed between single character comment delimiters from the set b and e. */static void str_uncomment_string_cmd (char *str, char *b, char *e) /*{{{*/{ unsigned char chb, che; unsigned char *s, *cbeg, *mark; if (strlen(b) != strlen(e)) { SLang_doerror ("Comment delimiter length mismatch."); return; } set_utility_char_table (b); if (NULL == (str = (char *) SLmake_string(str))) return; s = (unsigned char *) str; while ((chb = *s++) != 0) { if (Utility_Char_Table [chb] == 0) continue; mark = s - 1; cbeg = (unsigned char *) b; while (*cbeg != chb) cbeg++; che = (unsigned char) *(e + (int) (cbeg - (unsigned char *) b)); while (((chb = *s++) != 0) && (chb != che)); if (chb == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -