Author Topic: C Basic Class Library  (Read 59897 times)

Offline Charles Pegge

  • BASIC Developer
  • Posts: 69
C Basic Class Library
« on: November 11, 2013, 01:01:45 PM »
This code is still very volatile but I will start posting here.

The strings are simpler - one global controls the character width.

The sequence of file is important: - sort of linear hierarchy:

It will now compile with both GCC 4.7.0 and VC10 (without using compiler switches)

Code: [Select]
  #include <stdarg.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <math.h>
  #include "BasicDefine.h"
  #include "GenericClass.c"
  #include "PoolClass.c"
  #include "StringClass.c"
  #include "LexiClass.c"

Objects are generally contained within a single memory block and have the same base header. An object may contain any number of items in a contiguous block. For instance, strings contain an array of characters; a particle object will contain an array of particles.

If the array needs to be stretch then the whole object is re-dimensioned into a new memory block, and the original is freed.

Code: [Select]
  types ClassStruct
  begin
  ref f;  // pointer to methods/function table
  int type;   // dynamic type code
  int offset; // size of this header (jump to data)
  int nbytes; // buffer size for body of data
  int count;  // number of elements
  int size;   // size of each element
  end
  Class,*Object;
« Last Edit: November 18, 2013, 01:42:51 AM by Charles Pegge »

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #1 on: November 11, 2013, 01:11:22 PM »
Thanks Charles !!!

Sorry for losing faith.  :-X

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #2 on: November 11, 2013, 01:19:07 PM »
Works on Ubuntu 64.

Code: [Select]
jrs@laptop:~/C_BASIC/cbc$ gcc Test.c -o test1
jrs@laptop:~/C_BASIC/cbc$ ./test1

LO
HELLO
HELLOHELLOHELLO
9
helloLOhellohello
hellohellohello
42.000000
42.000000
AbcAbcAbcAbcAbcAbcAbc
LOLOLOLOLOLOLO
AbcAbcAbcAbcAbcAbcAbc
<
>
  Hello World!
<HELLO WORLD!>
<<HELLO WORLD!>>
HELLO
HELLOH
abc
       \abc
WORD:       aa
Class Size: 80
Char Width: 1
Word Len:   2
Word Start: 38547666
Word End:   38547668
Text End:   38547672
=
jrs@laptop:~/C_BASIC/cbc$

Offline Charles Pegge

  • BASIC Developer
  • Posts: 69
Re: C Basic Class Library
« Reply #3 on: November 11, 2013, 01:29:36 PM »
It okay, John. Thanks for testing. I can see that the control chars come out invisible - presumably its the forum display.

I'm doing quite a lot of conceptual work, to take out as much entropy as possible from the code which involves extended  periods of gazing through the (void*)  :)

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #4 on: November 11, 2013, 01:37:04 PM »
You can see them in the attached screenshot.


kryton9

  • Guest
Re: C Basic Class Library
« Reply #5 on: November 11, 2013, 01:53:03 PM »
Can't wait to test it out later when I have time.

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #6 on: November 11, 2013, 02:52:00 PM »
Charles,

I have reformatted your StringClass.c to be friendlier to CINT's parser. If it wouldn't be too much trouble, can your follow this format going forward?

John

Code: [Select]

  typedef char StringType,*CharArray;

  typedef struct StringClassTableStruct StringClassTable,*StringMethods;

  int CharWidth=1; // 1 or 2

 class StringClassStruct
  begin
//BASE MEMBERS
  StringMethods f; // pointer to methods table
  int type;        // dynamic type code
  int offset;      // size of this header
  int nbytes;      // buffer ze for body of data
  int count;       // number of elements
  int size;        // size of each element
  end
  StringClass,*StringObject;


  types StringArrayStruct
  begin
  StringMethods f;
  int offset;
  int nbytes;
  int count;
  int size;
  end
  StringArrayType,  *StringArrayObject;



  #define Left(S,I)   GetMid(S,1,(I))
  #define Right(S,I)  GetMid(S,-(I),-1)


  dim StringMethods pStringMethods=0;


  sub CopyWidth(char *t, int tw, char *s, int sw, int count)
  begin
    //itr 32bit char widths?
    int i;
    if(tw==2)
    begin
      if (sw==2)
      begin
        short *ss=(ref) s;
        short *ts=(ref) t;
        for (i=0; to i<count; step incr i)
        begin
          *ts= *ss;
          incr ts;
          incr ss;
        end
        return;
      end
      if (sw==1)
        begin
        short *ts=(ref) t;
        for (i=0; to i<count; step incr i)
        begin
          *ts= *s;
          incr ts;
          incr s;
        end
        return;
      end
    end
    // otherwise copy lower bytes only
    for (i=0; to i<count; step incr i)
    begin
      *t= *s;
      t+=tw;
      s+=sw;
    end
  end


  function CharArray strptr(StringObject s)
  begin
    return (ref) s + s->offset;
  end


  function StringObject *straptr(StringArrayObject s)
  begin
    return (ref) s + s->offset;
  end


  function StringObject StringTransfer(StringObject *r,StringObject s)
  begin
    return Transfer((ref *)r, (ref) s);
  end


  function char* CharTransfer(char **r, char *s)
  begin
    return Transfer((ref) *r, (ref) s);
  end



  function StringMethods StringClassInit();


  function StringObject NewString(int nc)
  begin
    if (pStringMethods==0) then StringClassInit();
    return NewObject(pStringMethods, nc, CharWidth, sizeof(StringClass));
  end


  function StringArrayObject NewStringArray(int nc)
  begin
    if (pStringMethods==0) then StringClassInit();
    return NewObject(pStringMethods, nc, sizeof(ref), sizeof(StringArrayType));
  end


  //methods


  method StringObject StringFree(StringObject *pthis)
  begin
    StringObject this= *pthis;
    if (this==0) FreeSpace(this);
    *pthis=0;
    return 0;
  end


  method StringObject StringFreeN(StringObject *pthis, int n)
  begin
    int i;
    for (i==0; to i<n; incr i)
    begin
      StringObject this=pthis[i];
      if (this==0) FreeSpace(this);
      pthis[i]=0;
    end
    return 0;
  end


  method StringArrayObject StringArrayFree(StringArrayObject *pthis)
  begin
    StringArrayObject this= *pthis;
    if (this==0) then return 0;
    StringObject *ps = straptr(this);
    StringObject s;
    int n=this->count;
    if (n==0) then return 0;
    int i;
    for (i=0; to i<n; step incr i)
    begin
      s=ps[i];
      if (s) then free(s);
    end
    free(this);
    *pthis=0;
    return 0;
  end


  method StringObject StringCopy(StringObject *pthis, StringObject s)
  begin
    StringObject this= *pthis;
    int le=0, lt=0, wi=1, wt=1, oc=sizeof(StringClass);
    if (s)
    begin
      le=s->count;
      wi=s->size;
    end
    if (this)
    begin
      lt=this->count;
      wt=this->size;
      oc=this->offset;
    end;
    if ((this==0)or(lt *wt < le *wi)) then this = NewObject(pStringMethods, le, wt, oc);
    if (s) then CopyWidth(strptr(this), wt, strptr(s), wi,le);
    return StringTransfer(pthis,this);
  end


  method char *StringGetChars(StringObject *pthis, char **r)
  begin
    StringObject this= *pthis;
    int tc=0;
    if (this) then tc=this->count;
    char *s = NewSpace(CharWidth * tc +2);
    if (this) then CopyWidth(s, CharWidth, strptr(this), this->size, this->count+1);
    return CharTransfer(r,s);
  end


  method StringObject StringSetChars(StringObject *pthis, char *s)
  begin
    StringObject this= *pthis;
    int le;
    if (CharWidth==2)
    begin
      le=WordLen(s);
    end
    else
    begin
      le=ByteLen(s);
    end     
    int wt=CharWidth;
    if (this) then wt=this->size;
    if ((this==0)or(this->count < le)) then this = NewString(le);
    char *k=strptr(this);
    CopyWidth(k, wt, s, CharWidth, le); // autoconvert
    this->count=le;
    NullTerminate(k+le*wt);
    return StringTransfer(pthis,this);
  end


 method StringObject StringGetMid(StringObject *pthis, StringObject s, int i, int le)
  begin
    int lt=0;
    int wi=CharWidth;
    if (s) then lt=s->count;
    if ((s)and(wi<0)) then wi=s->size;  // default to s size
    if (le<0) then le=lt;         // default max
    if (i<0) then i+=lt+1;        // offset from right
    decr i;                       // indexbase 0
    if (le+i>lt) then le=lt-i;    // clip length
    if (i<0)  then i=0;           //clamp lower offset
    if (le<0) then le=0;          //clamp length >=0
    StringObject this= *pthis;
    if (wi<1) then wi=1;          // in case of null s
    if ((this==0)or(this->nbytes < le*wi)) then this = NewString(le);
    char *k=strptr(this);
    if (s) then CopyWidth(k, wi, strptr(s) + i * s->size, s->size, le);
    NullTerminate(k+le*wi);
    this->count=le;
    this->size=wi;
    return StringTransfer(pthis, this);
  end


  method StringObject StringSetMid(StringObject *pthis, int i, StringObject s)
  begin
    StringObject this= *pthis;
    if (this==0) then return 0;
    int lt=this member count;
    int le=s member count;
    if (i<0) then i+=1+lt;
    decr i;
    char *k = strptr(this)+ i * this->size;
    if (le+i>=lt) then le = lt-i;
    CopyWidth(k, this->size, strptr(s), s->size, le);
    return this;
  end


/* non-ellipsis Join: passing array instead

  method StringObject StringJoinArray(StringObject *pthis, int n, StringObject *jl)
  begin
    StringObject this = *pthis;
    int ne=0;
    int i;
    char *k;
    int wid=1;
    StringObject s;
    int tot=0;
    for (i=0; to i<n; step incr i)
    begin
      s=jl[i];
      if (s)
      begin
        tot+=s->count;
        if (s->size == 2) then wid=2;
        if(s==this) then ne=1; // force new join-buffer
      end
    end
    if ((ne==1)or(this==0)or( this->nbytes < tot*wid)) then this=NewString(tot);
    char *m = strptr(this);
    for (i=0; to i<n; step incr i)
    begin
      s=jl[i];
      k=strptr(s);
      CopyWidth(m, wid, k, s->size, s->count);
      m+=(s->count * wid);
    end
    NullTerminate(m);
    this->count = tot;
    this->size = wid;
    return StringTransfer(pthis,this);
  end
*/

  method StringObject StringJoin(StringObject *pthis, int n, ...)
  begin
    va_list marker;
    StringObject this = *pthis;
    int ne=0;
    int i;
    char *k;
    int wid=1;
    StringObject s;
    int tot=0;
    va_start(marker, n); // Initialize variable arguments
    for (i=0; to i<n; step incr i)
    begin
      s=va_arg(marker, StringObject); // get next StringObject
      if (s)
      begin
        tot+=s->count;
        if (s->size == 2) then wid=2;
        if(s==this) then ne=1; // force new join-buffer
      end
    end
    va_end(marker); // Reset variable arguments
    if ((ne==1)or(this==0)or( this->nbytes < tot*wid)) then this=NewString(tot);
    char *m = strptr(this);
    va_start(marker, n); // Initialize variable arguments
    for (i=0; to i<n; step incr i)
    begin
      s=va_arg(marker, StringObject); // get next StringObject
      k=strptr(s);
      CopyWidth(m, wid, k, s->size, s->count);
      m+=(s->count * wid);
    end
    va_end(marker); // Reset variable arguments
    NullTerminate(m);
    this->count = tot;
    this->size = wid;
    return StringTransfer(pthis,this);
  end


  method StringObject StringMerge(StringObject *pthis,StringArrayObject *plist, StringObject kw)
  begin
    StringArrayObject list= *plist;
    if (list==0) then list=NewStringArray(0);
    int wid=kw->size; // default char width
    StringObject this= *pthis;
    StringObject *jl=(ref) list + list->offset;
    StringObject s;
    int en=list->nbytes;
    int tot=0;
    int ne=0;
    int i;
    for (i=0; to i<en; step incr i)
    begin
      s=jl[i];
      if (s)
      begin
        tot += s->count;
        if (s->size == 2) then wid=2;
        if(s==this) then ne=1; // force new join-buffer
      end
      tot += kw->count;
    end
    if ((ne==1)or(this==0)or( this->nbytes < tot*wid)) then this=NewString(tot);
    char *m = strptr(this);   // accumulator buffer base
    char *km = strptr(kw); // marker string chars
    char *ks;              // array element chars
    int kl = kw->count * wid;
    for (i=0; to i<en; step incr i)
    begin
      s=jl[i];
      if (s)
      begin
        ks=strptr(s);
        CopyWidth(m, wid, ks, s->size, s->count);
        m+=(s->count * wid);
      end
      CopyWidth(m, wid, km, kw->size, kw->count);
      m+=kl;
    end
    //m-kl;   // excluding end marker
    NullTerminate(m-kl);
    this->count = tot - kw->count; // excluding end marker
    this->size = wid;
    StringArrayFree(&list);
    *plist=0;
    return StringTransfer(pthis,this);
  end

  method StringArrayObject StringSplit(StringObject *pthis, StringArrayObject *plist, StringObject kw)
  begin
    StringObject this = *pthis;
    if (this==0) then this=NewString(0);
    StringArrayObject list= *plist;
    if (list) StringArrayFree(&list);
    int b=1;
    int en=0; // count markers
    while(b)
    begin
      en++;
      b=StringInstr(pthis,b,kw);
      if (b)
      begin
        b+=kw->count;
      end
    end
    list->count=en;        // returning number of string segements
    b=1;                   // start of string segment
    int e;                 // boundary of string segment
    int le;                // length of string segment
    int d;                 // stride for next string segment
    char *m=strptr(this);   // string base
    int wid = this->size;  // character width
    list= NewStringArray(en);
    StringObject *li=(ref) list + list->offset;
    int i;
    for (i=0; to i<en; step incr i)
    begin
      e=StringInstr(&this, b, kw);      //locate boundary marker
      if (e==0) then e=1 + this->count; //locate boundary of string
      le=e-b+1;
      StringObject c=NewString(le);
      CopyWidth(strptr(c), wid, m, wid, le);
      d=le + kw->count; // string + marker
      b+=d;             // stride
      m+=(d * wid);     // next offset
      li[i]=c;          // assign string to array
    end
    *plist=list;
    return list;
  end



  method StringObject StringRepeat(StringObject *pthis, StringObject s ,int n)
  begin
    int i;
    char *k=strptr(s);
    int tot=s->count*n;
    int wid=s->size;
    StringObject c = *pthis;
    if ((c==0)or( c->nbytes < tot*wid)) then c=NewString(tot);
    char *m=strptr(c);
    for (i=1; to i<=n; step incr i)
    begin
      CopyWidth(m, wid, k, s->size, s->count);
      m+=(s->count * wid);
    end
    NullTerminate(m);
    c->count = tot;
    c->size = wid;
    return StringTransfer(pthis,c);
  end


  method StringObject StringLcase(StringObject *r, StringObject this)
  begin
    int i;
    int w=this->size;
    int n=this->count;
    StringObject s= *r;
    if ((s==0)or(s != this)) then s = StringCopy(&s,this);
    char *c = strptr(s);
    char a;
    for (i=0; to to i<n; incr i)
    begin
      a= *c;
      if ((a>65)and(a<91)) then *c=a+32;
      c+=w;
    end
    return StringTransfer(r,s);
  end


  method StringObject StringUcase(StringObject *r, StringObject this)
  begin
    int i;
    int w=this->size;
    int n=this->count;
    StringObject s= *r;
    if ((s==0)or(s != this)) then  s = StringCopy(&s,this);
    char *c = strptr(s);
    char a;
    for (i=0; to to i<n; incr i)
    begin
      a= *c;
      if ((a>96)and(a<123)) then *c=a-32;
      c+=w;
    end
    if (*r != this) then return StringTransfer(r,s);
    return this;
  end


  method StringObject StringLtrim(StringObject *r, StringObject this)
  begin
    int i;
    StringObject u= *r;
    int w=this->size;
    int n=this->count;
    char *c = strptr(this);
    if (w<2)
    begin
      i=0;
      while (i++ < n)
      begin
        if (*c>32) then break;
        c+=w;
      end
      return StringTransfer(r,StringGetMid(&u,this,i,-1));
    end
    else
    begin
      i=0;
      while (i++ <n)
      begin
        if ((c[0]>32)or(c[1])) then break;
        c+=w;
      end
      return StringTransfer(r,StringGetMid(&u,this,(i>>1)+1,-1));
    end
  end


  method StringObject StringRtrim(StringObject *r, StringObject this)
  begin
    int i;
    StringObject u= *r;
    int w=this->size;
    int n=this->count;
    char *c = w * n - w + strptr(this);
    if (w<2)
    begin
      i=n;
      while(i-- >0)
      begin
        if (*c>32) then break;
        decr c;
      end
      return StringTransfer(r,StringGetMid(&u,this, 1, i+1));
    end
    else
    begin
      i=n;
      while (i-- >0)
      begin
        if ((c[0]>32)or(c[1])) then break;
        c+=w;
      end
      return StringTransfer(r,StringGetMid(&u,this, 1, (i>>1)+1));
    end
  end


  method StringObject StringTrim(StringObject *r, StringObject this)
  begin
    int i;
    StringObject u= *r;
    int w=this->size;
    int n=this->count;
    char *c = w * n - w + strptr(this);
    if (w<2)
    begin
      i=0;
      while (i++ < n)
      begin
        if (*c>32) then break;
        c+=w;
      end
      int b=i;
      i=n;
      while(i-- >0)
      begin
        if (*c>32) then break;
        decr c;
      end
      return StringTransfer(r,StringGetMid(&u,this, b, i-b+1));
    end
    else
    begin
      i=0;
      while (i++ <n)
      begin
        if ((c[0]>32)or(c[1])) then break;
        c+=w;
      end
      int b=i;
      i=n;
      while (i-- >0)
      begin
        if ((c[0]>32)or(c[1])) then break;
        c+=w;
      end
      return StringTransfer(r,StringGetMid(&u,this, b, ((i-b)>>1)+1));
    end
  end


  method StringObject StringInsert(StringObject *pthis, StringObject s, int i)
  begin
    StringObject this= *pthis;
    int c=this->count;
    int w=this->size;
    StringObject tl=NewString(c);
    StringObject tr=NewString(c);
    StringJoin(pthis,3,StringGetMid(&tl,this,1,i-1), s, StringGetMid(&tr,this,i,-1) );
    StringFree(&tl);
    StringFree(&tr);
    return *pthis;
  end


  method StringObject StringDelete(StringObject *pthis, int i, int le)
  begin
    StringObject this= *pthis;
    int c=this->count;
    int w=this->size;
    StringObject tl=NewString(c);
    StringObject tr=NewString(c);
    StringJoin(pthis,2,StringGetMid(&tl,this,1,i-1), StringGetMid(&tr,this,i+le,-1) );
    StringFree(&tl);
    StringFree(&tr);
    return *pthis;
  end


  method StringObject StringChr(StringObject *r, int a)
  begin
    int le=CharWidth;
    StringObject s= *r;
    if ((s==0)or(s->nbytes < le*CharWidth)) then s = NewString(le);
    s->count=le;
    s->size=CharWidth;
    short *k=(short*)strptr(s);
    *k=a;
    return StringTransfer(r,s);
  end


  method StringObject StringStr(StringObject *r, double d)
  begin
    int wi=1;
    int le=32;
    StringObject s= *r;
    if ((s==0)or(s->nbytes < le*wi)) then s = NewString(le);
    char *k=strptr(s);
    sprintf(k,"%f",d);
    s->count=ByteLen(k);
    s->size=wi;
    return StringTransfer(r,s);
  end


  method int StringShow(StringObject *pthis)
  begin
    CharArray w=strptr(*pthis);
    printf("%s\n", w); // itr wide chars
  end


  method int StringAsc(StringObject *pthis, int i)   // also supports wide chars
  begin
    StringObject this= *pthis;
    if (i<0) then i+=this->count+1;            // offset from right
    if ((i>this->count)or(i<1)) then return 0; // out of range
    decr i;                                    // indexbase 0
    int wi=this->size;
    if (wi==1) then return *(strptr(this)+i);
    if (wi==2)
    begin
      short *a = (short*)strptr(this)+i*2;
      return *a;
    end
  end


  method int StringCmp(StringObject *pthis, StringObject k)
  //COMPARING MIXED WIDTHS
  begin
    StringObject this= *pthis;
    if ((this==0)and(k==0)) then return  0; // null match
    if (this==0)            then return -1; // no this
    if (k==0)               then return  1; // no k
    if ((this->count==0)and(k->count==0)) then return 0;  // both nulls
    if (this->count==0)  then return  1;                  // this is greater
    if (k->count==0)     then return -1;                  // this is less
    int tw=this->size;
    int kw=k->size;
    char *tc = strptr(this);
    char *kc=strptr(k);
    char *te=tc+this->count*tw;
    char *ke=kc+k->count*kw;
    if ((tw==2)and(kw==2)) // comparing 16bit characters
    begin
      short *tew=(ref) te;
      short *tcw=(ref) tc;
      short *kew=(ref) ke;
      short *kcw=(ref) kc;
      while (1)
      begin
        if (*tcw < *kcw) then return  -1; // this is less
        if (*tcw > *kcw) then return   1; // this is greater
        tcw++;
        kcw++;
        if ((tcw==tew)and(kcw==kew)) then return  0; // match
        if (kcw==kew)                then return  1; // end of k
        if (tcw==tew)                then return -1; // end of this
      end
      return 0;
    end
    //otherwise 8bit or mixed 8bit/16bit characters (comparing lower byte)
    while (1)
    begin
      if (*tc < *kc) then return  -1; // this is less
      if (*tc > *kc) then return   1; // this is greater
      tc+=tw;
      kc+=kw;
      if ((tc==te)and(kc==ke)) then return  0; // match
      if (kc==ke)              then return  1; // end of k
      if (tc==te)              then return -1; // end of this
    end
    return 0;
  end


  method int StringInstr(StringObject *pthis, int i, StringObject k)
  //MATCHING MIXED WIDTHS
  begin
    StringObject this= *pthis;
    if (this==0) then return 0; // no string to search
    if (k==0)    then return 0; // no keystring to use
    char *tb = strptr(this);
    char *tc=tb;
    char *kc=strptr(k);
    char *te=tc+this->count*this->size;
    char *ke=kc+k->count*k->size;
    if (i > this->count) then return 0;          // offset past end
    if (this->count==0)  then return 0;          // null search string
    if (i<0)             then i+=this->count+1;  // offset from right
    if (k->count==0)     then return 0;          // empty keyword
    decr i;                                      //indexbase 0
    tc+=i*this->size;                            // offset
    char *td;
    char *kd;
    int tw=this->size;
    int kw=k->size;
    if ((tw==2)and(kw==2)) // comparing 16bit characters
    begin
      short *tbw=(ref) tb;
      short *tew=(ref) te;
      short *tcw=(ref) tc;
      short *kew=(ref) ke;
      short *kcw=(ref) kc;
      short *kdw;
      short *tdw;
      while (tcw<tew)
      begin
        if (*tcw == *kcw)
        begin
          tdw=tcw;
          kdw=kcw;     
          while (*tdw == *kdw)
          begin
            tdw++;
            kdw++;
            if (kdw==kew) then return ((tcw-tbw)>>1)+1;  // match complete
            if (tdw==tew) then return 0;                 // end of main string
            if (*tdw == *tcw) then tcw=tdw-tw;             // possible next match
          end
        end
        tcw++;
      end
      return 0;
    end
    //otherwise 8bit or mixed 8bit/16bit characters (comparing lower byte)
    while (tc<te)
    begin
      if (*tc == *kc)
      begin
        td=tc;
        kd=kc;     
        while (*td == *kd)
        begin
          td+=tw;
          kd+=kw;
          if (kd==ke) then return ((tc-tb)>>(tw-1))+1; // match complete
          if (td==te) then return 0;                   // end of main string
          if (*td == *tc) then tc=td-tw;                 // possible next match
        end
      end
      tc+=tw;
    end
    return 0;
  end


  method double StringVal(StringObject *pthis)
  begin
  double d;
  sscanf(strptr(*pthis),"%lf ",&d);
  return d;
  end


  method StringObject StringReplace(StringObject *pthis, StringObject f , StringObject r)
  begin
    StringObject this= *pthis;
    if ((this==0)or(f==0)or(r==0)) then return this;
    if ((this->count==0)or(f->count==0)) then return this;
    int n=0;
    int i=1;
    while (i)
    begin
      i=StringInstr(&this, i, f);
      if (i)
      begin
        n++;
        i+=f->count;
      end
    end
    n *= (r->count - f->count);
    int tot = n + this->count;
    StringObject c = NewString(tot);
    char *m = strptr(c);
    int b=1,j=1;
    while (j)
    begin
      j=StringInstr(&this,b,f);
      if (j)
      begin
        if (j>b) then CopyWidth(m, c->size,strptr(this)+b-1,this->size,j-b);
        m += c->size * (j-b);
        CopyWidth(m,c->size,strptr(r),r->size,r->count);
        m += c->size * r->count;
        b=j + f->count; // skip by keyword length
      end
    end
    // remainder
    j = this->count + 1;
    if (j>b)
    begin
      CopyWidth(m,c->size,strptr(this)+b-1,this->size,j-b);
      m += c->size * (j-b);
    end
    NullTerminate(m);
    return StringTransfer(pthis,c);
  end


  types StringClassTableStruct
  begin
    method StringObject      (byref Free)      (StringObject *pthis);
    method StringObject      (byref FreeN)     (StringObject *pthis, int n);
    method StringArrayObject (byref ArrayFree) (StringArrayObject *pthis);
    method StringObject      (byref Copy)       (StringObject *pthis, StringObject s);
    method char*             (byref GetChars)  (StringObject *pthis, char **r);
    method StringObject      (byref SetChars)  (StringObject *pthis, char *c);
    method StringObject      (byref GetMid)    (StringObject *pthis, StringObject s, int i, int le);
    method StringObject      (byref SetMid)    (StringObject *pthis, int i, StringObject s);
//  method StringObject      (byref JoinArray) (StringObject *pthis, int n, StringObject *jl);
    method StringObject      (byref Join)      (StringObject *pthis, int n, ...);
    method StringObject      (byref Merge)     (StringObject *pthis, StringArrayObject *plist, StringObject kw);
    method StringArrayObject (byref Split)     (StringObject *pthis, StringArrayObject *plist, StringObject kw);
    method StringObject      (byref Repeat)    (StringObject *pthis, StringObject s ,int n);
    method StringObject      (byref Replace)   (StringObject *pthis, StringObject f , StringObject r);
    method StringObject      (byref Ucase)     (StringObject *r, StringObject this);
    method StringObject      (byref Lcase)     (StringObject *r, StringObject this);
    method StringObject      (byref Ltrim)     (StringObject *r, StringObject this);
    method StringObject      (byref Rtrim)     (StringObject *r, StringObject this);
    method StringObject      (byref Trim)      (StringObject *r, StringObject this);
    method StringObject      (byref Insert)    (StringObject *pthis, StringObject s, int i);
    method StringObject      (byref Delete)    (StringObject *pthis, int i, int le);
    method StringObject      (byref Chr)       (StringObject *r, int a);
    method StringObject      (byref Str)       (StringObject *r, double d);
    method int               (byref Show)      (StringObject *pthis);
    method int               (byref Asc)       (StringObject *pthis, int i);   // also supports wide chars
    method int               (byref Cmp)       (StringObject *pthis, StringObject k);
    method int               (byref Instr)     (StringObject *pthis, int i,  StringObject k);
    method double            (byref Val)       (StringObject *pthis);
  end
  StringClassTable,*StringMethods;

  function StringMethods StringClassInit()
  begin
    dim as static StringClassTable t;
    StringMethods f references t;
    f->Free       references StringFree;
    f->FreeN      references StringFreeN;
    f->ArrayFree  references StringArrayFree;
    f->Copy       references StringCopy;
    f->GetChars   references StringGetChars;
    f->SetChars   references StringSetChars;
    f->GetMid     references StringGetMid;
    f->SetMid     references StringSetMid;
//  f->JoinArray  references StringJoinArray;
    f->Join       references StringJoin;
    f->Merge      references StringMerge;
    f->Split      references StringSplit;
    f->Repeat     references StringRepeat;
    f->Replace    references StringReplace;
    f->Ucase      references StringUcase;
    f->Lcase      references StringLcase;
    f->Ltrim      references StringLtrim;
    f->Rtrim      references StringRtrim;
    f->Trim       references StringTrim;
    f->Insert     references StringInsert;
    f->Delete     references StringDelete;
    f->Chr        references StringChr;
    f->Str        references StringStr;
    f->Show       references StringShow;
    f->Asc        references StringAsc;
    f->Cmp        references StringCmp;
    f->Instr      references StringInstr;
    f->Val        references StringVal;
    pStringMethods=f;
    return f;
  end

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #7 on: November 11, 2013, 03:15:49 PM »
Charles,

I'm working on getting the modified version of your code working on C9 and Red Hat is complaining on the run but not the compile.

allbasic@c_basic:~/668428/usr/john/cbc $ ./t_cbc
./t_cbc: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
allbasic@c_basic:~/668428/usr/john/cbc $

The same code runs fine on Ubuntu 64 bit.

John

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: C Basic Class Library
« Reply #8 on: November 11, 2013, 06:04:02 PM »
On OSX 10.9:

Code: [Select]
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:7:
./GenericClass.c:159:3: warning: control may reach end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:7:
./GenericClass.c:171:3: warning: control may reach end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:7:
./GenericClass.c:183:3: warning: control may reach end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:7:
./GenericClass.c:200:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:9:
./StringClass.c:137:11: warning: equality comparison result unused [-Wunused-comparison]
    for (i==0; to i<n; incr i)
         ~^~~
./StringClass.c:137:11: note: use '=' to turn this equality comparison into an assignment
    for (i==0; to i<n; incr i)
          ^~
          =
./StringClass.c:398:9: warning: implicit declaration of function 'StringInstr' is invalid in C99 [-Wimplicit-function-declaration]
      b=StringInstr(pthis,b,kw);
        ^
./StringClass.c:655:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:9:
./StringClass.c:671:3: warning: control may reach end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:10:
./LexiClass.c:50:31: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat]
    printf("Word Start: %i\n",w->bp);
                        ~~    ^~~~~
                        %s
./LexiClass.c:51:31: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat]
    printf("Word End:   %i\n",w->ep);
                        ~~    ^~~~~
                        %s
./LexiClass.c:52:31: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat]
    printf("Text End:   %i\n",w->et);
                        ~~    ^~~~~
                        %s
./LexiClass.c:53:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:10:
./LexiClass.c:60:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:10:
./LexiClass.c:142:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
In file included from Test.c:3:
In file included from ./BasicClassLibrary.h:10:
./LexiClass.c:159:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
Test.c:5:12: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  function TestStrings()
           ^~~~~~~~~~~
Test.c:75:3: warning: control reaches end of non-void function [-Wreturn-type]
  end
  ^
./BasicDefine.h:12:17: note: expanded from macro 'end'
  #define end   }
                ^
17 warnings generated.

Result of execution:
Code: [Select]
[riveraa@Kitty ~/Downloads/CBasicClassLibrary] $ ./test
Segmentation fault: 11

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #9 on: November 11, 2013, 06:09:42 PM »
I don't know if this is related to my __vdso_time issue on C9 but when trying to run the phpinfo.php script I get the following in the Apache error_log.

Code: [Select]
[Mon Nov 11 21:03:27 2013] [error] [client 127.10.32.129] PHP Warning:  phpinfo(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EST/-5.0/no DST' instead in /var/lib/stickshift/525667ede0b8cd7b5d000021/app-root/data/642383/sbcgi/test.php on line 2, referer: https://c9.io/scriptbasic/c9basic

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #10 on: November 11, 2013, 06:14:25 PM »
Quote
#define end   }

Maybe OSX doesn't like the leading spaces. Try this.

Code: [Select]
#define end }

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: C Basic Class Library
« Reply #11 on: November 11, 2013, 06:20:56 PM »
That's not causing the warning, spaces are legal.

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #12 on: November 11, 2013, 06:53:04 PM »
This is the error I'm getting trying to compile Charles's (unmodified) current installment on CentOS release 6.4 (Final) 64 bit. (Red Hat clone)

Code: [Select]
[root@ip-10-200-134-45 cbasic]# gcc Test.c -o test1
In file included from BasicClassLibrary.h:9,
                 from Test.c:3:
StringClass.c:878: error: redefinition of typedef ‘StringClassTable’
StringClass.c:4: note: previous declaration of ‘StringClassTable’ was here
StringClass.c:878: error: redefinition of typedef ‘StringMethods’
StringClass.c:4: note: previous declaration of ‘StringMethods’ was here
[root@ip-10-200-134-45 cbasic]#

I tried to compile on a 32 bit version of CentOS 6.4 and got the same results.

Code: [Select]
[root@johns2 cbasic]# gcc Test.c -o test1
In file included from BasicClassLibrary.h:9,
                 from Test.c:3:
StringClass.c:878: error: redefinition of typedef ‘StringClassTable’
StringClass.c:4: note: previous declaration of ‘StringClassTable’ was here
StringClass.c:878: error: redefinition of typedef ‘StringMethods’
StringClass.c:4: note: previous declaration of ‘StringMethods’ was here
[root@johns2 cbasic]#
« Last Edit: November 11, 2013, 07:33:51 PM by John »

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: C Basic Class Library
« Reply #13 on: November 11, 2013, 07:33:24 PM »
I think Charles has standardized on C11.  When I turn it off on my Mac, I see this:

Code: [Select]
In file included from ./BasicClassLibrary.h:9:
./StringClass.c:878:3: warning: redefinition of typedef 'StringClassTable' is a C11 feature [-Wtypedef-redefinition]
  StringClassTable,*StringMethods;
  ^
./StringClass.c:4:41: note: previous definition is here
  typedef struct StringClassTableStruct StringClassTable,*StringMethods;
                                        ^
./StringClass.c:878:21: warning: redefinition of typedef 'StringMethods' is a C11 feature [-Wtypedef-redefinition]
  StringClassTable,*StringMethods;
                    ^
./StringClass.c:4:59: note: previous definition is here
  typedef struct StringClassTableStruct StringClassTable,*StringMethods;

So if your compiler supports it,try it like this: gcc Test.c -std=c11 -o test1

Offline John

  • Forum Support / SB Dev
  • Posts: 3558
    • ScriptBasic Open Source Project
Re: C Basic Class Library
« Reply #14 on: November 11, 2013, 07:40:25 PM »
CentOS 32 bit
[root@johns2 cbasic]# gcc Test.c -std=c11 -o test1
cc1: error: unrecognized command line option "-std=c11"
[root@johns2 cbasic]#

CentOS 64 bit - gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
[root@ip-10-200-134-45 cbasic]# gcc Test.c -std=c11 -o test1
cc1: error: unrecognized command line option "-std=c11"
[root@ip-10-200-134-45 cbasic]#

C9 Red Hat 64 bit - gcc version 4.7.2 20121015 (Red Hat 4.7.2-5) (GCC)
allbasic@c_basic:~/668428/usr/john/cbc $ gcc Test.c -std=c11 -o test1
In file included from BasicClassLibrary.h:9:0,
                 from Test.c:3:
StringClass.c: In function ‘StringSplit’:
StringClass.c:398:7: warning: implicit declaration of function ‘StringInstr’ [-Wimplicit-function-declaration]
Test.c: At top level:
Test.c:5:12: warning: return type defaults to ‘int’ [enabled by default]
allbasic@c_basic:~/668428/usr/john/cbc $ ./test1
./test1: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
allbasic@c_basic:~/668428/usr/john/cbc $ gcc Test.c -o test1
allbasic@c_basic:~/668428/usr/john/cbc $ ./test1
./test1: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
allbasic@c_basic:~/668428/usr/john/cbc $

Ubuntu 64 bit - gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~12.04)
jrs@laptop:~/C_BASIC/charles$ gcc Test.c -std=c11 -o test1
In file included from BasicClassLibrary.h:9:0,
                 from Test.c:3:
StringClass.c: In function ‘StringSplit’:
StringClass.c:398:7: warning: implicit declaration of function ‘StringInstr’ [-Wimplicit-function-declaration]
       b=StringInstr(pthis,b,kw);
       ^
Test.c: At top level:
Test.c:5:12: warning: return type defaults to ‘int’ [enabled by default]
   function TestStrings()
            ^
jrs@laptop:~/C_BASIC/charles$ ./test1

LO
HELLO
HELLOHELLOHELLO
9
helloLOhellohello
hellohellohello
42.000000
42.000000
AbcAbcAbcAbcAbcAbcAbc
LOLOLOLOLOLOLO
AbcAbcAbcAbcAbcAbcAbc
<
>
  Hello World!
<HELLO WORLD!>
<<HELLO WORLD!>>
HELLO
HELLOH
abc
       \abc
WORD:       aa
Class Size: 80
Char Width: 1
Word Len:   2
Word Start: 9801938
Word End:   9801940
Text End:   9801944
=
jrs@laptop:~/C_BASIC/charles$
« Last Edit: November 11, 2013, 08:55:06 PM by John »