📄 longstr.c
字号:
/*Copyright (c) 2000, Red Hat, Inc.This file is part of Source-Navigator.Source-Navigator is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as publishedby the Free Software Foundation; either version 2, or (at your option)any later version.Source-Navigator is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith Source-Navigator; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <memory.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifndef WIN32#include <unistd.h>#endif /* WIN32 */#ifdef __MSVC__#include <io.h>#endif#include "longstr.h"#include "tcl.h"#define STRING_SLOT_SIZE 500 /* It must be greater then 0 ! */#define FIELD_POINTER_SLOT_SIZE 15 /* It must be greater then 0 ! */static unsigned intLongStringSplit(LongString *str, void *string, int length, int dup_flag, int separator, int maxfields){ int cou; char sep = (char)separator; char *p = (char *)string; if (dup_flag) { if (str->buf == (char *)string) { p = str->buf; } else { p = str->copy(str,(char *)string,length); } string = (void *)p; /* We have to remember to the beginning. */ } if (!str->field_value) { str->allocated_field_pointers = FIELD_POINTER_SLOT_SIZE; str->field_value = (char**)ckalloc(str->allocated_field_pointers * sizeof(char *)); str->field_size = (short*)ckalloc(str->allocated_field_pointers * sizeof(unsigned short)); } for (cou = 0, str->field_value[0] = p; *p; p++) { if (*p == sep) { if (dup_flag) *p = '\0'; if (cou + 1 == str->allocated_field_pointers) { str->allocated_field_pointers += FIELD_POINTER_SLOT_SIZE; str->field_value = (char**)ckrealloc((char*)str->field_value, str->allocated_field_pointers * sizeof(char *)); str->field_size = (short*)ckrealloc((char*)str->field_size, str->allocated_field_pointers * sizeof(unsigned short)); } str->field_size[cou] = (unsigned short)(p - str->field_value[cou]); str->field_value[++cou] = p + 1; /* The rest will be taken as one field. */ if (maxfields > 0 && cou == maxfields - 1) { /* We have to point to the end to compute correct size! */ if (dup_flag) { p = str->buf + str->len; } else if (length > 0) { p = (char *)string + length + 1; } else { p += strlen(p) + 1; } break; } } } str->field_size[cou] = (unsigned short)(p - str->field_value[cou]); str->total_fields = cou + 1; return (unsigned int)str->total_fields;}/* Duplicates the item. */static char *LongStringDup(LongString *ostr,LongString *istr){ memcpy((void *)ostr,(void *)istr,sizeof(LongString)); if (istr->buf) { int len = istr->len + 1; /* Include '\0' too ! */ ostr->buf = (char*)ckalloc(len); if (!ostr->buf) { ostr->free(ostr); return NULL; } memcpy((void *)ostr->buf,(void *)istr->buf,len); ostr->allocated = len; } if (istr->field_value) { int len; istr->allocated_field_pointers = istr->total_fields; len = istr->allocated_field_pointers * sizeof(char *); ostr->field_value = (char**)ckalloc(len); memcpy((void *)ostr->field_value,(void *)istr->field_value,len); len = istr->allocated_field_pointers * sizeof(unsigned short); ostr->field_size = (short*)ckalloc(len); memcpy((void *)ostr->field_size,(void *)istr->field_size,len); } return ostr->buf;}static voidLongStringFree(LongString *str){ if (str->buf) { ckfree(str->buf); str->buf = NULL; } if (str->field_value) { ckfree((char*)str->field_value); str->field_value = NULL; ckfree((char*)str->field_size); str->field_size = NULL; } str->allocated = 0; str->allocated_field_pointers = 0; str->total_fields = 0; str->len = 0;}/* Increases the buffer size when necessary */static char *LongStringMakespace(LongString *str,unsigned int siz){ siz++; /* Include '\0'! */ if (str->buf == NULL) { str->allocated = siz + str->slot_size; str->buf = (char*)ckalloc(str->allocated); *str->buf = '\0'; } else if (str->allocated < siz) { char *pb; str->allocated = siz + str->slot_size; pb = (char*)ckrealloc(str->buf,str->allocated); if (!pb) { str->free(str); return NULL; } str->buf = pb; } return str->buf;}/* Frees the not needed memory. */static char *LongStringMin(LongString *str){ if (str->buf) { char *bp = (char*)ckrealloc(str->buf,str->len + 1); if (bp) { str->buf = bp; } } return str->buf;}/* Append the string, and reallocate buffer when necessary! */static char *LongStringAppend(LongString *str,char *string,int len){ if (len == 0) { return str->buf; } if (len < 0) /* Copy until '\0'! */ { char *pi; char *po; int s; if (!str->buf) { str->allocated = str->slot_size; str->buf = (char*)ckalloc(str->allocated); if (!str->buf) { str->allocated = 0; return NULL; } } for (pi = string, po = &str->buf[str->len], s = str->allocated - (po - str->buf) - 1;;) { char *bf; /* Copy as much as possible! */ while (s-- > 0 && *pi) { *po++ = *pi++; } if (*pi == '\0') /* We have reached the end. */ break; /* The buffer must be reallocated! */ str->allocated += str->slot_size; bf = (char*)ckrealloc(str->buf,str->allocated); if (!bf) { str->free(str); return NULL; } po = bf + (po - str->buf); str->buf = bf; s = str->allocated - (po - str->buf) - 1; } *po = '\0'; str->len = po - str->buf; } else { /* +1 is necessary because we will append '\0' too. */ if (len >= (int)(str->allocated - str->len)) { char *bf; /* Allocate always bit more to reduce the number of reallocs! */ if (str->buf) { str->allocated += len + str->slot_size; bf = (char*)ckrealloc(str->buf,str->allocated); } else { str->allocated = len + str->slot_size; bf = (char*)ckalloc(str->allocated); } if (!bf) { str->free(str); return NULL; } str->buf = bf; } /* printf("COPY: <%*.*s>,%d\n",len,len,string,len); */ memcpy(&str->buf[str->len],string,len); str->len += len; str->buf[str->len] = '\0'; } return str->buf;}/* Copy the string! */static char *LongStringCopy(LongString *str,char *string,int len){ str->len = 0; return LongStringAppend(str, string, len);}/* Adds multiple strings, the list must be terminated by NULL. */static char *LongStringAppendStrings MX_VARARGS_DEF(LongString *, arg1){ LongString *str; va_list args; char *string; char *pe = NULL;/* str = MX_VARARGS_START(LongString *,arg1,args); rigo */ MX_VARARGS_START(str,LongString *,arg1,args); /* rigo */ while (1) { string = va_arg(args, char *); if (!string) break; pe = LongStringAppend(str,string,-1); } va_end(args); return pe;}/* Copies multiple strings, the list must be terminated by NULL. */static char *LongStringCopyStrings MX_VARARGS_DEF(LongString *, arg1){ LongString *str; va_list args; char *string; char *pe = NULL;/* str = MX_VARARGS_START(LongString *,arg1,args); rigo */ MX_VARARGS_START(str,LongString *,arg1,args); /* rigo */ str->len = 0; while (1) { string = va_arg(args, char *); if (!string) break; pe = LongStringAppend(str,string,-1); } va_end(args); return pe;}/* Reads the contents of a file into a dynamically allocated buffer. */static char *LongStringReadFile(LongString *str,char *filename){ struct stat statBuf; register unsigned char *p; register size_t len; int om = O_RDONLY; int fd; int rdb;#ifdef WIN32 om |= O_BINARY;#endif /* WIN32 */ fd = open(filename,om); if (fd < 0) { str->free(str); return NULL; } if (fstat(fd, &statBuf) == -1) { str->free(str); close(fd); return NULL; } if (!str->buf) { p = (char *)ckalloc((size_t)statBuf.st_size+1); } else { p = (char *)ckrealloc(str->buf,(size_t)statBuf.st_size+1); } if (!p) { str->free(str); close(fd); return NULL; } str->buf = p; str->len = (int)statBuf.st_size; for (p = str->buf,len = (size_t)str->len, rdb = 1; rdb > 0 && len > 0;) { rdb = (size_t)read(fd, p, len); if (rdb > 0) { len -= rdb; p += rdb; } } close(fd); str->buf[str->len] = '\0'; return str->buf;}/* Reads a line into a dynamically allocated buffer. */static char *LongStringTrim(LongString *str,char *trim_pat){ char *pbeg; char *pend; int len; if (!str->buf) return NULL; if (!trim_pat) trim_pat = "\040\t\n\r"; /* Skip leading characters ! */ for (pbeg = &str->buf[0]; *pbeg && strchr(trim_pat,(int)*pbeg); pbeg++); pend = &str->buf[str->len - 1]; if (pend < pbeg) { len = 0; } else { /* Skip traling characters ! */ for (; pend > pbeg && strchr(trim_pat,(int)*pend); pend--); len = pend - pbeg + 1; } if (pbeg > str->buf) { memmove(str->buf,pbeg,len); } str->buf[len] = '\0'; str->len = len; return str->buf;}/* Reads a line into a dynamically allocated buffer. */static char *LongStringFgets(LongString *str,FILE *fp){ char *bf; char *po; int c; int s; if (!fp) return NULL; if (!str->buf) { str->allocated = str->slot_size; str->buf = (char*)ckalloc(str->allocated); if (!str->buf) { str->allocated = 0; return NULL; } } for (c = EOF, po = str->buf, s = str->allocated - 1;;) { /* Read as much as possible! */ while (s > 0 && (c = getc(fp)) != EOF && c != '\n') { if ((unsigned char)c != '\r') { *po++ = (char)c; s--; } } if (s != 0) /* We have read either '\n' or EOF. */ break; /* The buffer must be reallocated! */ str->allocated += str->slot_size; bf = (char*)ckrealloc(str->buf,str->allocated); if (!bf) { ckfree(str->buf); return NULL; } po = bf + (po - str->buf); str->buf = bf; s = str->allocated - (po - str->buf) - 1; } *po = '\0'; str->len = po - str->buf; if (c == EOF && str->len == 0) return NULL; return str->buf;}voidLongStringInit(LongString *str,int slot_size){ static int default_slot_size = 0; if (!default_slot_size) { char *p; if ((p = getenv("LONGSTRING_SIZE"))) { default_slot_size = atoi(p); } if (default_slot_size <= 0) { default_slot_size = STRING_SLOT_SIZE; } } memset((void *)str,0,sizeof(*str)); str->slot_size = slot_size > 0 ? (unsigned short)slot_size : default_slot_size; str->append = (char * (*)(struct __LongString *,char *,unsigned int)) LongStringAppend; str->appendstrings = (char * (*)MX_VARARGS(struct __LongString *,str)) LongStringAppendStrings; str->copystrings = (char * (*)MX_VARARGS(struct __LongString *,str)) LongStringCopyStrings; str->copy = (char * (*)(struct __LongString *,char *string,unsigned int)) LongStringCopy; str->makespace = (char * (*)(struct __LongString *,unsigned int)) LongStringMakespace; str->min = (char *(*)(struct __LongString *)) LongStringMin; str->dup = (char *(*)(struct __LongString *,struct __LongString *)) LongStringDup; str->free = (void (*)(struct __LongString *)) LongStringFree; str->fgets = (char * (*)(struct __LongString *,FILE *)) LongStringFgets; str->trim = (char * (*)(struct __LongString *,char *)) LongStringTrim; str->readfile = (char * (*)(struct __LongString *,char *)) LongStringReadFile; str->split = (unsigned int (*)(struct __LongString *,void *,int,int,int,int)) LongStringSplit;}#undef TEST#define TEST 0#if TESTmain(){ LongString str; LongString str2; int cou,i; int len; LongStringInit(&str,1); for (i = 0, cou = str.split(&str,"1 2",-1,0,' ',0); i < cou; i++) { printf("<%*.*s>\n", str.field_size[i],str.field_size[i],str.field_value[i]); }; for (i = 0, cou = str.split(&str,"1 2 3def 4 5bcdef",-1,0,' ',0); i < cou; i++) { printf("<%*.*s>\n", str.field_size[i],str.field_size[i],str.field_value[i]); }; for (i = 0, cou = str.split(&str,"AA\001BB",4,0,'\001',0); i < cou; i++) { printf("<%*.*s>\n", str.field_size[i],str.field_size[i],str.field_value[i]); }; str.dup(&str2,&str); for (i = 0; i < cou; i++) { printf("<%*.*s>\n", str2.field_size[i],str2.field_size[i],str2.field_value[i]); printf("len: %d\n",str2.field_size[i]); };#if 1 str.appendstrings(&str,"1skfbjrhvbfr"," " "44442d,mn9"," " "3**",NULL); printf("<%s>\n",str.buf); str.copy(&str,"BAC",-1); str.append(&str,"Zsolt",-1); str.append(&str,"Hello",3); printf("<%s>\n",str.buf); str2.free(&str2); str.dup(&str2,&str); str2.min(&str2); printf("<%s>\n",str2.buf); str.copy(&str,"zk",-1); printf("<%s>\n",str.buf); str2.free(&str2); str.free(&str);/* printf("%s",str.readfile(&str,"longstr.h")); printf("%s",str.readfile(&str,"longstr.c"));*/#endif str.free(&str); exit(0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -