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

📄 int_str.c

📁 LastWave
💻 C
📖 第 1 页 / 共 4 页
字号:
/*..........................................................................*//*                                                                          *//*      L a s t W a v e   K e r n e l   3 . 0                               *//*                                                                          *//*      Copyright (C) 1998-2003 Emmanuel Bacry.                             *//*      email : lastwave@cmap.polytechnique.fr                              *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a 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 (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*//***************************************************************** * *  The String content * *****************************************************************/  #include "lastwave.h"#include <stdarg.h>#include "signals.h"#include "images.h"#include "int_fsilist.h" /* Type of a string */char *strType = "&string";/* Types used only for specifying procedure arguments types */char *listType = "&list";char *wordType = "&word";char *wordlistType = "&wordlist";char *valType = "&val";char *valobjType = "&valobj";/* * Answers to the different print messages */#define StrShortPrintLength 10#define StrPrintLength 200 void PrintStrContent(STRVALUE sc){  Printf("'%s'\n",sc->str);}static void _PrintStr(char *strOut, char *str,int length){  int n;  char c;    if (strlen(str)<length) sprintf(strOut,"'%s'",str);  else {    n = MIN(strlen(str),length-2);    c = str[n];    str[n] = '\0';     sprintf(strOut,"'%s...'",str);    str[n] = c;  }}char *ToStrStrContent(STRVALUE sc, char flagShort){  static char str[StrPrintLength];    if (flagShort) _PrintStr(str,sc->str,StrShortPrintLength);  else _PrintStr(str,sc->str,StrPrintLength);    return(str);}void PrintInfoStrContent(STRVALUE sc){  Printf("   length =  %d\n",strlen(sc->str));}/* * The different extract options  */static char *extractOptionsStr[] = {"*nolimit","*bperiodic","*bmirror","*bmirror1","*list",NULL};enum {  FSIOptStrNoLimit = FSIOption1,  FSIOptStrBPer = FSIOption2,  FSIOptStrBMir = FSIOption3,  FSIOptStrBMir1 = FSIOption4,  FSIOptStrList = FSIOption5}; /*  * The function that manages setting a string using explicit parameters */char *SetStr_(char **strLeft,FSIList *fsiList, LWFLOAT flt, VALUE val,char *equal, char *fieldName){  FSI_DECL;  int _j,j,k,_iold;  char *strRight,*str,*type;  int lRight,lLeft,length;  LISTV lv;  static STRVALUE sc1 = NULL;  static STRVALUE sc2 = NULL;      /* Get the type of the right value  */  if (val == NULL) type = numType;  else {    type = GetTypeValue(val);    if (type == numType) flt = CastValue(val,NUMVALUE)->f;  }    /*************************   *   * Case right value is a LWFLOAT   *   *   s *= 3   *   *************************/     if (type == numType) {      if (*equal != '*') {       SetErrorf("The '<string> %s <number>' syntax is not adequate",equal);      return(NULL);    }    if (fsiList != NULL) {       SetErrorf("The '%s' syntax is not adequate on a string[range]",equal);      return(NULL);    }    if (flt != (int) flt) {      SetErrorf("Right handside of assignement should be an integer");      return(NULL);    }        if (sc1 == NULL) {      sc1 = NewNullStrValue();      sc2 = NewNullStrValue();    }    sc1->str = *strLeft;    InitStrValue(sc2);    MultStrValue(sc1, (int) flt,sc2);    Free(*strLeft);    *strLeft = sc2->str;    sc1->str = NULL;    sc2->str = NULL;    return(strType);  }  /*************************   *   * Case right value is a string   *   *************************/    if (type == strType) {       /* Get the right handside string and its length */    strRight = CastValue(val,STRVALUE)->str;    lRight = strlen(strRight);        /* Get left handside length */    lLeft = strlen(*strLeft);        /*     * Case simple assignement 'strLeft... op strRight'     */        /* 'strLeft op strRight' or 'strLeft[] op strRight' */    if (fsiList == NULL || fsiList->nx == 0) {      if (*equal == '=') { /* 'strLeft = strRight' or 'strLeft[] = strRight' */        if (lLeft >= lRight) strcpy(*strLeft,strRight);        else {          Free(*strLeft);          *strLeft = CharAlloc(MAX(lRight,MinStringSize)+1);          strcpy(*strLeft,strRight);        }      }      else if (*equal == '+') { /* 'strLeft += strRight' or 'strLeft[] += strRight' */        str = CharAlloc(MAX(lRight+lLeft,MinStringSize)+1);        strcpy(str,*strLeft);        strcpy(str+lLeft,strRight);        Free(*strLeft);        *strLeft = str;      }      else {        SetErrorf("The '%s' syntax is not adequate",equal);        return(NULL);      }      return(strType);    }    if (*equal != ':' && *equal != '=') {      SetErrorf("The '%s' syntax is not adequate for operating on strings",equal);      return(NULL);    }            /*      * Case of an extraction strLeft[1:3,7]=strRight (i.e., SAME SIZE)     */       if (*equal == '=') {      if (lRight != fsiList->nx) {        SetErrorf("String lengths do not match");        return(NULL);      }      _j = 0;      FSI_FOR_START(fsiList);       (*strLeft)[_i] = strRight[_j++];      FSI_FOR_END;      return(strType);    }         /*      * Case of an extraction s[1:3,7] := "ab" (i.e., NOT SAME SIZE)     */        /* In the case s[1,2,6,9] := "a" it is particularly simple */    if (fsiList->nx == fsiList->size && lRight == 1) {      FSI_FOR_START(fsiList);      (*strLeft)[_i]= *strRight;      FSI_FOR_END;      return(strType);    }      /* We first need to compute the new length */    length = strlen(*strLeft) - fsiList->nx + fsiList->nx*lRight;    str = CharAlloc(MAX(length,MinStringSize)+1);      /* Then we perform the set */    j = 0; /* Index in the *strLeft string */    k = 0; /* Index in the str string */    _iold = -1;    FSI_FOR_START(fsiList);      /* We check the fsiList is sorted */      if (_i <= _iold) {        SetErrorf("Sorry, this operation with non sorted indexes is not implemented");        Free(str);        return(NULL);      }      _iold = _i;      strncpy(str+k,*strLeft+j,_i-j);      k+=_i-j;      strcpy(str+k,strRight);      k+=lRight;      j=_i+1;    FSI_FOR_END;    strcat(str+k,*strLeft+j);    Free(*strLeft);    *strLeft = str;    return(strType);  }          /*************************   *   * Case val is a listv   *   *   *************************/  else if (type == listvType) {    lv = CastValue(val,LISTV);        if (fsiList == NULL) {      SetErrorf("Syntax 'string = listv' not valid");      return(NULL);          }        /* Must be of the type s[1:3,4,2:4] = {"a" "bb" "c"} or s[1:3,4,2:4] := {"a"} */    if (*equal == '=' && lv->length != fsiList->size) {      SetErrorf("Length of extraction list should be the same as length of &listv");      return(NULL);    }    if (*equal == ':' && lv->length != 1) {      SetErrorf("Length of right handside &listv should be 1");      return(NULL);    }           /* We first need to compute the length of the listv */    lRight = 0;    for (j=0;j<lv->length;j++) {      if (lv->values[j] == NULL || GetTypeValue(lv->values[j]) != strType) {        SetErrorf("The &listv should contain only &string elements");        return(NULL);      }      lRight += strlen(CastValue(lv->values[j],STRVALUE)->str);    }    if (*equal ==':') lRight*=fsiList->size;    /* Then we go */    lRight += strlen(*strLeft)-fsiList->nx;    str = CharAlloc(MAX(lRight,MinStringSize)+1);      /* Then we perform the set */    j = 0; /* Index in the *strLeft string */    k = 0; /* Index in the str string */    _iold = -1;    FSI_FOR_START1(fsiList);    if (*equal == ':') strRight = CastValue(lv->values[0],STRVALUE)->str;    else strRight = CastValue(lv->values[_n],STRVALUE)->str;    switch(fsi->type) {    case FSIFloat :       _j = (int) fsi->val.f;      if (_j<=_iold) {        SetErrorf("Sorry, this operation with non sorted indexes is not implemented");        Free(str);        return(NULL);      }      _iold = _j;      strncpy(str+k,*strLeft+j,_j-j);      k+=_j-j;      strcpy(str+k,strRight);      k+=strlen(strRight);      j=_j+1;      break;    case FSIRange :       _j = (int) fsi->val.r->first;      if (_j<=_iold) {        SetErrorf("Sorry, this operation with non sorted indexes is not implemented");        Free(str);        return(NULL);      }      if (fsi->val.r->step != 1) {        SetErrorf("Sorry, only ranges with a step of 1 are valid indexes for this operation");        Free(str);        return(NULL);      }      _iold = _j+fsi->val.r->size-1;      strncpy(str+k,*strLeft+j,_j-j);      k+=_j-j;      strcpy(str+k,strRight);      k+=strlen(strRight);      j=_j+fsi->val.r->size;      break;    case FSISignal :      SetErrorf("Sorry, only ranges or numbers are valid indexes for this operation");      Free(str);      return(NULL);    }    FSI_FOR_END1;      strcat(str+k,*strLeft+j);        Free(*strLeft);    *strLeft = str;    return(strType);  }    else {      if (fieldName == NULL) SetErrorf("Cannot assign '%s' to string",GetTypeValue(val));    else SetErrorf("Cannot assign field '%s' with non string argument (type is '%s')",GetTypeValue(val));    return(NULL);  }}/* * Basic routine to deal with setting a string field (with eventual extraction) */void *SetStrField(char **pstr, void **arg){   char *field = NULL;   FSIList *fsiList = ARG_S_GetFsiList(arg);   char *type = ARG_S_GetRightType(arg);         LWFLOAT flt = ARG_S_GetRightFloat(arg);      VALUE val = ARG_S_GetRightValue(arg);  char *equal = ARG_S_GetEqual(arg);   char **pstrRes = ARG_S_GetResPStr(arg);      if (SetStr_(pstr,fsiList,flt,val,equal,field) == NULL) return(NULL);   *pstrRes = *pstr;   return(strType);}/*  * Routine to deal with setting of strings */static char *doc = "{[*opt,...] [:]= (<string> | <listv>)} {Get/Set characters}"; static void *SetExtractStrV(VALUE val,void **arg){   char *field;   FSIList *fsiList;   char *type;   LWFLOAT flt;  char *equal;   char **pstrRes;   VALUE val1;   STRVALUE sc;     /* Doc */  if (val == NULL) return(doc);  sc = (STRVALUE) val;  field = ARG_S_GetField(arg);  fsiList = ARG_S_GetFsiList(arg);  type = ARG_S_GetRightType(arg);        flt = ARG_S_GetRightFloat(arg);     val1 = ARG_S_GetRightValue(arg);  equal = ARG_S_GetEqual(arg);  pstrRes = ARG_S_GetResPStr(arg);     if (SetStr_(&(sc->str),fsiList,flt,val1,equal,field) == NULL) return(NULL);  *pstrRes = sc->str;  if (sc->list) {    DeleteList(sc->list);    sc->list = NULL;  }  return(strType);}/* * Basic routine to deal with getting a string field */static void *GetStrFieldExtract_(char *str, void **arg,STRVALUE sc){  char **list;  int max,sizeList;  FSI_DECL;  BorderType bt;    char *str1,*str2,*str0;  FSIList *fsiList;  LWFLOAT *pFlt;  char **pStr;  char **list1,**list2;  VALUE *pValue;      fsiList = ARG_G_GetFsiList(arg);  pFlt = ARG_G_GetResPFloat(arg);  pStr = ARG_G_GetResPStr(arg);  pValue = ARG_G_GetResPValue(arg);     /* case of no extraction and no field */  if (fsiList == NULL) {    *pStr = str;    return(strType);  }    /* case of an empty extraction */  if (fsiList != NULL && fsiList->nx == 0) {    *pValue = (VALUE) TNewStrValue();    return(strType);  }    if (fsiList->options & FSIOptStrBPer) bt = BorderPer;  else if (fsiList->options & FSIOptStrBMir) bt = BorderMir;  else if (fsiList->options & FSIOptStrBMir1) bt = BorderMir1;  else bt = BorderNone;  /*   * Case the '*list' option is off    */  if (!(fsiList->options & FSIOptStrList)) {    /* Allocation of the result */    if (!(fsiList->options & (FSIOptStrBPer | FSIOptStrBMir | FSIOptStrBMir1))) *pStr = StrValueStrAlloc(fsiList->nx1);    else *pStr = StrValueStrAlloc(fsiList->nx);            /* Get the max size */    max = strlen(str);    /* The loop in the case of *nolimit */    if (fsiList->options & FSIOptStrNoLimit) {      FSI_FOR_START1(fsiList);       if (fsi->type == FSIRange && fsi->val.r->step == 1) {        if (RangeFirst(fsi->val.r) >= max || RangeLast(fsi->val.r) < 0) continue;        memcpy((*pStr)+_k,str+(int) (MAX(RangeFirst(fsi->val.r),0)),((int) (MIN(RangeLast(fsi->val.r),max-1)-MAX(RangeFirst(fsi->val.r),0)+1))*sizeof(char));        _k+= (int) (MIN(RangeLast(fsi->val.r),max-1)-MAX(RangeFirst(fsi->val.r),0)+1);      }      else {        FSI_FOR_START2(fsiList);         if (_i<0 || _i > max-1) continue;        (*pStr)[_k] = str[_i];               FSI_FOR_END2;      }      FSI_FOR_END1;    }    /* The loop in the generic case */    else {      /* ????? AMELIORATION : utiliser memcpy pour les effets de bords aussi */      FSI_FOR_START1(fsiList);       if (fsi->type == FSIRange && fsi->val.r->step == 1 && RangeFirst(fsi->val.r) >= 0 && RangeLast(fsi->val.r) < max) {        memcpy((*pStr)+_k,str+(int) (RangeFirst(fsi->val.r)),((int) (RangeLast(fsi->val.r)-RangeFirst(fsi->val.r)+1))*sizeof(char));        _k+= (int) (MIN(RangeLast(fsi->val.r),max-1)-MAX(RangeFirst(fsi->val.r),0)+1);      }      else {        FSI_FOR_START2(fsiList);         switch (bt) {        case BorderPer : (*pStr)[_k] = str[BPER(_i,max)]; break;        case BorderMir : (*pStr)[_k] = str[BMIR(_i,max)]; break;        case BorderMir1 : (*pStr)[_k] = str[BMIR1(_i,max)]; break;        default : (*pStr)[_k] = str[_i];        }        FSI_FOR_END2;      }      FSI_FOR_END1;    }        (*pStr)[_k] = '\0';            /* We want to return a STRVALUE so that we do not need to temp the string */    *pValue = (VALUE) NewNullStrValue();    ((STRVALUE) *pValue)->str = *pStr;    TempValue(*pValue);    *pStr = NULL;    return(strType);  }  /*   * Case the '*list' option is  on    */  else {    /* Get the list and its size */    if (sc == NULL) {      SetErrorf("*list option not yet implemented in this case... sorry!");      return(NULL);    }    list = GetListFromStrValue(sc);    if (list == NULL) return(NULL);    max = GetListSize(list);          

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -