diff --git a/Android.mk b/Android.mk index 989d491..4eaaf75 100644 --- a/Android.mk +++ b/Android.mk @@ -1,33 +1,92 @@ -# This make file can be usedS to build J as part of an Android project. +# This make file can be used to build J as part of an Android project. # The project it was created for is hosted on github at # https://github.com/mdykman/jconsole_for_android . -# openj should be checked out into a seperate folder under -# /jni . That project is equipped with an Android.mk +# openj should be checked out into a seperate folder under +# /jni . That project is equipped with an Android.mk # file which will invoke this one. # Further detais on building J within the Android # context can be found in that project # +# this has been built under Android 2.1, API level 7. see note below # this has been built under Android 2.2, API level 8. +# TARGET PLATFORMS + +# As long as graphics are not a defining goal, +# Android 2.1 (API 7) has been selected as the +# target platform to admit the largest possible +# potential user base. +# Android 2.2 (API 8) offers a great deal more +# graphical power to applications with the +# inclusion of libGLESv2.so and should be the +# target for future builds hoping to integrate +# native graphics into the Android app. + +# When building under Android API 7 (2.1) +# hostdefs.c fails to build as that platform +# lacks regex.h. Under API 8 (2.2), the +# include below should be uncommented. +# The current release for Android 2.1 includes +# XXX_defs.ijs files generated under API 8. +# I am confident that these are sufficient +# for the present build. + + + +## edited by md - removed -pedantic from the build flags as it was creating much distracting noise in a build cycle. + LOCAL_PATH := $(call my-dir) +# include $(CLEAR_VARS) +# LOCAL_MODULE := libm6 +# LOCAL_SRC_FILES := libm6.a + +# include $(PREBUILT_STATIC_LIBRARY) + include $(CLEAR_VARS) LOCAL_MODULE := j -LOCAL_LDLIBS := -llog -ldl -lm -lc +ifeq ($(TARGET_ARCH),arm) + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -mfloat-abi=softfp -mfpu=vfpv3-d16 -march=armv7-a -D__TARGET_FPU_VFP -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +# LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -mfpu=vfpv3-d16 -march=armv7-a -D__TARGET_FPU_VFP -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + FENV := arm/fenv.c + LOCAL_LDLIBS := -llog -ldl -lc + LOCAL_STATIC_LIBRARIES := libm6 + else + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -mfloat-abi=softfp -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +# LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + FENV := + LOCAL_LDLIBS := -llog -ldl -lm -lc + endif +endif +ifeq ($(TARGET_ARCH),mips) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +# LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + FENV := mips/fenv.c + LOCAL_LDLIBS := -llog -ldl -lm -lc +endif +ifeq ($(TARGET_ARCH),x86) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -msse2 -mfpmath=sse -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +# LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -msse2 -mfpmath=sse -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + FENV := + LOCAL_LDLIBS := -llog -ldl -lm -lc +endif -LOCAL_CFLAGS := -O0 -fno-omit-frame-pointer -fno-strict-aliasing -fno-unwind-tables -fno-tree-vectorize -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -fPIC +LOCAL_CFLAGS += -DSUPPORT_UTF8 +# LOCAL_CFLAGS+= -DSYS_LINUX - -LOCAL_SRC_FILES := a.c ab.c af.c ai.c am.c am1.c amn.c ao.c ap.c ar.c as.c au.c c.c ca.c cc.c cd.c cf.c cg.c ch.c cip.c cl.c cp.c cpdtsp.c cr.c crs.c \ +LOCAL_SRC_FILES := $(FENV) a.c ab.c af.c ai.c am.c am1.c amn.c ao.c ap.c ar.c as.c au.c c.c ca.c cc.c cd.c cf.c cg.c ch.c cip.c cl.c cp.c cpdtsp.c cr.c crs.c \ ct.c cu.c cv.c cx.c d.c dc.c dss.c dstop.c dsusp.c dtoa.c f.c f2.c i.c io.c j.c jdlllic.c k.c m.c mbx.c p.c pv.c px.c r.c rl.c rt.c s.c sc.c sl.c \ sn.c t.c u.c v.c v0.c v1.c v2.c va1.c va2.c va2s.c vamultsp.c vb.c vbang.c vbit.c vcant.c vchar.c vcat.c vcatsp.c vcomp.c vcompsc.c vd.c vdx.c ve.c \ vf.c vfft.c vfrom.c vfromsp.c vg.c vgauss.c vgcomp.c vgranking.c vgsort.c vgsp.c vi.c viix.c visp.c vm.c vo.c vp.c vq.c vrand.c vrep.c vs.c vsb.c \ vt.c vu.c vx.c vz.c w.c wc.c wn.c ws.c x.c x15.c xa.c xb.c xc.c xcrc.c xd.c xf.c xfmt.c xh.c xi.c xl.c xo.c xs.c xt.c xu.c \ - jconsole.c jeload.c jni/j-jni-interface.c + jconsole.c jeload.c jni/j-jni-interface.c jni/jthostne_android.c + include $(BUILD_SHARED_LIBRARY) -include jni/openj-core/defs/Android.mk +# uncomment the next line for Android 2.2+ +#include jni/openj-core/defs/Android.mk diff --git a/Jconsole.mk b/Jconsole.mk new file mode 100644 index 0000000..2f1a04c --- /dev/null +++ b/Jconsole.mk @@ -0,0 +1,60 @@ +# This make file can be used to build J as part of an Android project. +# The project it was created for is hosted on github at +# https://github.com/mdykman/jconsole_for_android . +# openj should be checked out into a seperate folder under +# /jni . That project is equipped with an Android.mk +# file which will invoke this one. +# Further detais on building J within the Android +# context can be found in that project +# +# this has been built under Android 2.1, API level 7. see note below +# this has been built under Android 2.2, API level 8. + +# TARGET PLATFORMS + +# As long as graphics are not a defining goal, +# Android 2.1 (API 7) has been selected as the +# target platform to admit the largest possible +# potential user base. +# Android 2.2 (API 8) offers a great deal more +# graphical power to applications with the +# inclusion of libGLESv2.so and should be the +# target for future builds hoping to integrate +# native graphics into the Android app. + +# When building under Android API 7 (2.1) +# hostdefs.c fails to build as that platform +# lacks regex.h. Under API 8 (2.2), the +# include below should be uncommented. +# The current release for Android 2.1 includes +# XXX_defs.ijs files generated under API 8. +# I am confident that these are sufficient +# for the present build. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jconsole + +LOCAL_LDLIBS := -llog -ldl -lm -lc + +ifeq ($(TARGET_ARCH),arm) + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -mfpu=vfpv3-d16 -march=armv7-a -D__TARGET_FPU_VFP -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + else + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -DREADLINE -fPIC + endif +endif +ifeq ($(TARGET_ARCH),mips) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +endif +ifeq ($(TARGET_ARCH),x86) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -msse2 -mfpmath=sse -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -DREADLINE -fPIC +endif + + +LOCAL_SRC_FILES := jconsole.c jeload.c linenoise.c + +include $(BUILD_EXECUTABLE) + diff --git a/Tsdll.mk b/Tsdll.mk new file mode 100644 index 0000000..61d6420 --- /dev/null +++ b/Tsdll.mk @@ -0,0 +1,58 @@ +# This make file can be used to build J as part of an Android project. +# The project it was created for is hosted on github at +# https://github.com/mdykman/jconsole_for_android . +# openj should be checked out into a seperate folder under +# /jni . That project is equipped with an Android.mk +# file which will invoke this one. +# Further detais on building J within the Android +# context can be found in that project +# +# this has been built under Android 2.1, API level 7. see note below +# this has been built under Android 2.2, API level 8. + +# TARGET PLATFORMS + +# As long as graphics are not a defining goal, +# Android 2.1 (API 7) has been selected as the +# target platform to admit the largest possible +# potential user base. +# Android 2.2 (API 8) offers a great deal more +# graphical power to applications with the +# inclusion of libGLESv2.so and should be the +# target for future builds hoping to integrate +# native graphics into the Android app. + +# When building under Android API 7 (2.1) +# hostdefs.c fails to build as that platform +# lacks regex.h. Under API 8 (2.2), the +# include below should be uncommented. +# The current release for Android 2.1 includes +# XXX_defs.ijs files generated under API 8. +# I am confident that these are sufficient +# for the present build. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := tsdll + +LOCAL_LDLIBS := -lc + +ifeq ($(TARGET_ARCH),arm) + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -mfpu=vfpv3-d16 -march=armv7-a -D__TARGET_FPU_VFP -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + else + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -mfloat-abi=softfp -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC + endif +endif +ifeq ($(TARGET_ARCH),mips) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +endif +ifeq ($(TARGET_ARCH),x86) + LOCAL_CFLAGS := -Os -fno-strict-aliasing -fomit-frame-pointer -std=c99 -pedantic -msse2 -mfpmath=sse -D_MISALIGN_BYTEVECTOR -DNOASM -DOPENJ -D_FILE_OFFSET_BITS=64 -fPIC +endif + +LOCAL_SRC_FILES := tsdll.c + +include $(BUILD_SHARED_LIBRARY) diff --git a/ap.c b/ap.c index 154642c..1ba6129 100644 --- a/ap.c +++ b/ap.c @@ -80,7 +80,7 @@ DO(n-1, fvv(d,z,y,x); RER; x=xx+=d; y=zz; z=zz+=d;); \ }} - + #if SY_ALIGN #define PREFIXBFXLOOP(T,pfx) \ {T*xx=(T*)x,*yy,*zz=(T*)z; \ @@ -126,13 +126,13 @@ PREFIXBFX( eqpfxB, EQ, IEQ, SEQ, BEQ, {B b=1; DO(n, *z++=b=b==*x++;);}) static B jtpscanlt(J jt,I m,I c,I n,B*z,B*x,B p){A t;B*v;I d,i; - d=c/n; memset(z,!p,m*c); + d=c/n; memset(z,!p,m*c); if(1==d)DO(m, if(v=memchr(x,p,n))*(z+(v-x))=p; z+=c; x+=c;) else{ GA(t,B01,d,1,0); v=BAV(t); for(i=0;i >: +: *: */ @@ -173,7 +173,7 @@ AHDRP(minuspfxI,I,I){C er=0;I d=c/n,i,j,n1=n-1,*xx=x,*y,*zz=z; if(1==d){ if(1==n)DO(m, *z++=*x++;) else DO(m, MINUSP(n,z,x); RER; z=zz+=c; x=xx+=c;); - }else for(i=0;irank&&jt->rank[1]rank[1]; jt->rank=0; R rank1ex(w,self,r,jtgprefix);} jt->rank=0; - n=IC(w); + n=IC(w); h=VAV(self)->h; hv=AAV(h); m=AN(h); GA(z,BOX,n,1,0); zv=AAV(z); DO(n, RZ(zv[i]=df1(take(sc(1+i),w),hv[i%m]));); @@ -246,11 +246,11 @@ static DF1(jtgprefix){A h,*hv,z,*zv;I m,n,r; static DF1(jtpscan){A y,z;C id;I c,cv,f,m,n,r,rr[2],t,wn,wr,*ws,wt,zt;VF ado; RZ(w); - wt=AT(w); + wt=AT(w); if(SPARSE&wt)R scansp(w,self,jtpscan); wn=AN(w); wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; ws=AS(w); m=prod(f,ws); c=m?AN(w)/m:prod(r,f+ws); n=r?ws[f]:1; - y=VAV(self)->f; id=vaid(VAV(y)->f); + y=VAV(self)->f; id=vaid(VAV(y)->f); if(2>n||!wn){if(id){jt->rank=0; R r?ca(w):reshape(over(shape(w),one),w);}else R prefix(w,self);} vapfx(id,wt,&ado,&cv); if(!ado)R prefix(w,self); @@ -280,26 +280,26 @@ static A jtifxi(J jt,I m,A w){A z;I d,j,k,n,p,*x; R z; } -static DF2(jtinfix){PROLOG;DECLF;A x,z;I m; +static DF2(jtinfix){PROLOG;DECLF;A x,z;I m; PREF2(jtinfix); if(a==ainf)R repeat(zero,w); - RE(m=i0(vib(a))); + RE(m=i0(vib(a))); RZ(x=ifxi(m,w)); if(*AS(x))z=eachl(x,w,atop(fs,ac2(jtseg))); else{A s;I r; r=AR(w); r=MAX(0,r); GA(s,INT,r,1,0); if(r)ICPY(AV(s),AS(w),r); *AV(s)=0>m?0:m; RZ(x=df1(reshape(s,filler(w)),fs)); z=reshape(over(zero,shape(x)),x); - } + } EPILOG(z); } -static DF2(jtinfix2){PROLOG;A f,x,y;B d;I c,m,n,n1,r,*s,t; - PREF2(jtinfix); - RE(m=i0(vib(a))); t=AT(w); n=IC(w); +static DF2(jtinfix2){PROLOG;A f,x,y;B d;I c,m,n,n1,r,*s,t; + PREF2(jtinfix); + RE(m=i0(vib(a))); t=AT(w); n=IC(w); if(!(2==m&&2<=n&&t&DENSE))R infix(a,w,self); c=AN(w)/n; d=1&&t&DIRECT; r=AR(w); s=AS(w); n1=n-1; - if(d ){RZ(x=gah(r,w)); ICPY(AS(x),s,r); *AS(x)=n1; AN(x)=c*n1;} + if(d ){RZ(x=gah(r,w)); ICPY(AS(x),s,r); *AS(x)=n1; AN(x)=c*n1;} else RZ(x=curtail(w)); if(d&!(t&IS1BYTE)){RZ(y=gah(r,w)); ICPY(AS(y),s,r); *AS(y)=n1; AN(y)=c*n1; AK(y)=AK(w)+(I)w+c*bp(t)-(I)y;} else RZ(y= behead(w)); @@ -308,7 +308,7 @@ static DF2(jtinfix2){PROLOG;A f,x,y;B d;I c,m,n,n1,r,*s,t; } /* 2 f/\w */ static DF2(jtginfix){A h,*hv,x,z,*zv;I d,m,n; - RE(m=i0(vib(a))); + RE(m=i0(vib(a))); RZ(x=ifxi(m,w)); h=VAV(self)->h; hv=AAV(h); d=AN(h); if(n=IC(x)){ @@ -323,7 +323,7 @@ static DF2(jtginfix){A h,*hv,x,z,*zv;I d,m,n; #define MCREL(uu,vv,n) {A*u=(A*)(uu),*v=(A*)(vv); DO((n), *u++=(A)AABS(wd,*v++););} -static DF2(jtinfixd){A fs,z;C*x,*y;I c=0,d,k,m,n,p,q,r,*s,wd,wr,*ws,wt,zc; +static DF2(jtinfixd){A fs,z;C*x,*y;I c=0,d,k,m,n,p,q,r,*s,wd,wr,*ws,wt,zc; F2RANK(0,RMAX,jtinfixd,self); wr=AR(w); ws=AS(w); wt=AT(w); n=IC(w); RE(m=i0(a)); p=m==IMIN?IMAX:ABS(m); @@ -335,7 +335,7 @@ static DF2(jtinfixd){A fs,z;C*x,*y;I c=0,d,k,m,n,p,q,r,*s,wd,wr,*ws,wt,zc; k=c*bp(wt); wd=(I)w*ARELATIVE(w); if(AN(z))switch((0>m?2:0)+(wd?1:0)){ case 0: q=p*k; DO(d, MC(x,y,q); x+=q; y+=k;); break; - case 1: q=p*k; DO(d, MCREL(x,y,p); x+=q; y+=k;); break; + case 1: q=p*k; DO(d, MCREL(x,y,p); x+=q; y+=k;); break; case 2: MC(x,y,n*k); if(q=d*p-n)fillv(wt,q*c,x+n*k); break; case 3: MCREL(x,y,n); if(q=d*p-n)fillv(wt,q*c,x+n*k); break; } @@ -364,8 +364,8 @@ static A jtmovsumavg1(J jt,I m,A w,A fs,B avg){A y,z;D d=(D)m;I c,p,s,t,wt; switch((wt&B01?0:wt&INT?2:4)+avg){ case 0: MOVSUMAVG(B,I,INT,I,INT,x, SETZ ); break; case 1: MOVSUMAVG(B,I,INT,D,FL, x/d,SETZD); break; - case 2: - irange(AN(w),AV(w),&s,&t); t=0=d*((D)s+(D)t); + case 2: + irange(AN(w),AV(w),&s,&t); t=0=d*((D)s+(D)t))&&(IMIN<=d*(D)s); if(t) MOVSUMAVG(I,I,INT,I,INT,x, SETZ ) else MOVSUMAVG(I,D,FL, D,FL, x, SETZ ); break; case 3: MOVSUMAVG(I,D,FL, D,FL, x/d,SETZD); break; @@ -384,7 +384,7 @@ static A jtmovsumavg(J jt,I m,A w,A fs,B avg){A z; static DF2(jtmovavg){I m; PREF2(jtmovavg); RE(m=i0(vib(a))); - if(0f; x=VAV(x)->f; id=ID(x); - if(wt&B01)id=id==CMIN?CSTARDOT:id==CMAX?CPLUSDOT:id; + x=VAV(self)->f; x=VAV(x)->f; id=ID(x); + if(wt&B01)id=id==CMIN?CSTARDOT:id==CMAX?CPLUSDOT:id; if(id==CBDOT&&(x=VAV(x)->f,INT&AT(x)&&!AR(x)))id=(C)*AV(x); switch(0p)R infix(a,w,self); d=0<=m0?1+p-m:(p+m-1)/m; c=aii(w); cm=c*m; b=0>m0&&0rank=0; + zt=rtype(cv); jt->rank=0; GA(z,zt,c*d,AR(w),AS(w)); *AS(z)=d; if((t=atype(cv))&&t!=wt){RZ(w=cvt(t,w)); wt=AT(w);} - zv=CAV(z); zk=bp(zt)*c; + zv=CAV(z); zk=bp(zt)*c; wv=CAV(w); wk=bp(wt)*(0<=m0?c:c*m); DO(d-b, ado(jt,1L,cm,m,zv,wv); zv+=zk; wv+=wk;); if(b)ado(jt,1L,c*(p%m),p%m,zv,wv); @@ -527,11 +527,11 @@ F1(jtbslash){A f;AF f1=jtprefix,f2=jtinfix;V*v; switch(v->id){ case CPOUND: f1=jtiota1; break; - case CLEFT: case CRIGHT: case CCOMMA: + case CLEFT: case CRIGHT: case CCOMMA: f2=jtinfixd; break; - case CFORK: + case CFORK: if(v->f1==(AF)jtmean)f2=jtmovavg; break; - case CSLASH: + case CSLASH: f2=jtmovfslash; if(vaid(f))f1=jtpscan; } R ADERIV(CBSLASH,f1,f2,RMAX,0L,RMAX); diff --git a/ar.c b/ar.c index a02bf47..d2e48c7 100644 --- a/ar.c +++ b/ar.c @@ -13,23 +13,28 @@ static DF1(jtreduce); #define PARITY2 u=(UC*)&s; b=0; b^=*u++; b^=*u++; -#define PARITY4 u=(UC*)&s; b=0; b^=*u++; b^=*u++; b^=*u++; b^=*u++; +#define PARITY4 u=(UC*)&s; b=0; b^=*u++; b^=*u++; b^=*u++; b^=*u++; #define PARITY8 u=(UC*)&s; b=0; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; #if SY_64 #define PARITYW PARITY8 #else #define PARITYW PARITY4 -#endif +#endif -#if SY_ALIGN +#if SY_ALIGN || _MISALIGN_BYTEVECTOR #define VDONE(T,PAR) \ {I q=n/sizeof(T);T s,*y=(T*)x; DO(m, s=0; DO(q, s^=*y++;); PAR; *z++=b==pc;);} +#if _MISALIGN_BYTEVECTOR +static void vdone(I m,I n,B*x,B*z,B pc){B b,*u; + DO(m, b=0; DO(n, b^=*x++;); *z++=b==pc;); +} +#else static void vdone(I m,I n,B*x,B*z,B pc){B b,*u; if(1==m){UI s,*xi; s=0; b=0; - xi=(I*)x; DO(n/SZI, s^=*xi++;); + xi=(I*)x; DO(n/SZI, s^=*xi++;); u=(B*)xi; DO(n%SZI, b^=*u++;); u=(B*)&s; DO(SZI, b^=*u++;); *z=b==pc; @@ -38,6 +43,7 @@ static void vdone(I m,I n,B*x,B*z,B pc){B b,*u; else if(0==n%sizeof(US ))VDONE(US, PARITY2) else DO(m, b=0; DO(n, b^=*x++;); *z++=b==pc;); } +#endif #else static void vdone(I m,I n,B*x,B*z,B pc){B b;I q,r;UC*u;UI s,*y; q=n/SZI; r=n%SZI; y=(UI*)x; @@ -114,7 +120,7 @@ static void vdone(I m,I n,B*x,B*z,B pc){B b;I q,r;UC*u;UI s,*y; REDUCECFX( eqinsB, EQ, IEQ, SEQ, BEQ, vdone(m,n,x,z,(B)(n%2))) REDUCECFX( neinsB, NE, INE, SNE, BNE, vdone(m,n,x,z,1 )) -REDUCECFX( orinsB, OR, IOR, SOR, BOR, DO(m, *z++=1&&memchr(x,C1,n); x+=c;)) +REDUCECFX( orinsB, OR, IOR, SOR, BOR, DO(m, *z++=1&&memchr(x,C1,n); x+=c;)) REDUCECFX( andinsB, AND, IAND, SAND, BAND, DO(m, *z++=! memchr(x,C0,n); x+=c;)) REDUCEBFX( ltinsB, LT, ILT, SLT, BLT, DO(m, *z++= *(x+n-1)&&!memchr(x,C1,n-1)?1:0; x+=c;)) REDUCEBFX( leinsB, LE, ILE, SLE, BLE, DO(m, *z++=!*(x+n-1)&&!memchr(x,C0,n-1)?0:1; x+=c;)) @@ -129,13 +135,13 @@ REDUCEPFX(plusinsB,I,B,PLUS) #else AHDRR(plusinsB,I,B){I d,dw,i,p,q,r,r1,s;UC*tu;UI*v; if(c==n&&ntbase+jt->ttop; + old=jt->tbase+jt->ttop; for(i=1;iIMAX?scf(d-n):sc((I)d-n)); R n?tymes(z,t):t; case CEQ: p=1; /* fall thru */ case CNE: - ASSERT(B01&AT(e),EVNONCE); - if(!n)*BAV(z)=p; - b=1; DO(r, if(!(s[i]%2)){b=0; break;}); + ASSERT(B01&AT(e),EVNONCE); + if(!n)*BAV(z)=p; + b=1; DO(r, if(!(s[i]%2)){b=0; break;}); R !p==*BAV(e)&&b!=n%2?not(z):z; }} /* f/w on sparse vector w, post processing */ @@ -256,10 +262,10 @@ static A jtredspd(J jt,A w,A self,C id,VF ado,I cv,I f,I r,I zt){A a,e,x,z,zx;I wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); x=SPA(wp,x); s=AS(x); xr=r; v=AV(a); DO(AN(a), if(f 1, sparse axis */ @@ -362,8 +368,8 @@ static DF1(jtreducesp){A a,g,x,y,z;B b;C id;I cv,f,n,r,rr[2],*v,wn,wr,*ws,wt,zt; vains(id,wt,&ado,&cv); if(2==n&&!(ado&&strchr(fca,id))){ rr[0]=0; rr[1]=r; - jt->rank=rr; x=from(zero,w); - jt->rank=rr; y=from(one, w); + jt->rank=rr; x=from(zero,w); + jt->rank=rr; y=from(one, w); R df2(x,y,g); } if(!ado)R redg(w,self); @@ -463,11 +469,11 @@ static DF1(jtreduce){A z;C id;I c,cv,f,m,n,r,rr[2],t,wn,wr,*ws,wt,zt;VF ado; static A jtredcatsp(J jt,A w,A z,I r){A a,q,x,y;B*b;I c,d,e,f,j,k,m,n,n1,p,*u,*v,wr,*ws,xr;P*wp,*zp; ws=AS(w); wr=AR(w); f=wr-r; p=ws[1+f]; - wp=PAV(w); x=SPA(wp,x); y=SPA(wp,i); a=SPA(wp,a); v=AV(a); + wp=PAV(w); x=SPA(wp,x); y=SPA(wp,i); a=SPA(wp,a); v=AV(a); m=*AS(y); n=AN(a); n1=n-1; xr=AR(x); RZ(b=bfi(wr,a,1)); c=b[f]; d=b[1+f]; if(c&&d)b[f]=0; e=f+!c; - j=0; DO(n, if(e==v[i]){j=i; break;}); + j=0; DO(n, if(e==v[i]){j=i; break;}); k=1; DO(f, if(!b[i])++k;); zp=PAV(z); SPB(zp,e,ca(SPA(wp,e))); GA(q,INT,n-(c&&d),1,0); v=AV(q); DO(wr, if(b[i])*v++=i-(i>f);); SPB(zp,a,q); @@ -481,12 +487,12 @@ static A jtredcatsp(J jt,A w,A z,I r){A a,q,x,y;B*b;I c,d,e,f,j,k,m,n,n1,p,*u,*v MC(AV(q),AV(x),AN(x)*bp(AT(x))); SPB(zp,x,q); SPB(zp,i,ca(y)); }else{ /* other */ - GA(q,INT,xr,1,0); v=AV(q); + GA(q,INT,xr,1,0); v=AV(q); if(1!=k){*v++=0; *v++=k; e=0; DO(xr-1, ++e; if(e!=k)*v++=e;); RZ(x=cant2(q,x));} v=AV(q); u=AS(x); *v=u[0]*u[1]; ICPY(1+v,2+u,xr-1); RZ(x=reshape(vec(INT,xr-1,v),x)); e=ws[f+c]; RZ(y=repeat(sc(e),y)); v=j+AV(y); if(c)DO(m, k=p**v; DO(e, *v=k+ i; v+=n;);) - else DO(m, k= *v; DO(e, *v=k+p*i; v+=n;);); + else DO(m, k= *v; DO(e, *v=k+p*i; v+=n;);); RZ(q=grade1(y)); RZ(y=from(q,y)); RZ(x=from(q,x)); SPB(zp,x,x); SPB(zp,i,y); } @@ -498,7 +504,7 @@ static DF1(jtredcat){A z;B b;I f,r,*s,*v,wr; wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; s=AS(w); jt->rank=0; b=1==r&&1==s[f]; if(2>r&&!b)R ca(w); - GA(z,AT(w),AN(w),wr-1,s); + GA(z,AT(w),AN(w),wr-1,s); if(!b){v=f+AS(z); RE(*v=mult(s[f],s[1+f])); ICPY(1+v,2+f+s,r-2);} if(SPARSE&AT(w))R redcatsp(w,z,r); MC(AV(z),AV(w),AN(w)*bp(AT(w))); @@ -528,9 +534,9 @@ static DF1(jtredstitch){A c,y;I f,n,r,*s,*v,wr; RE(v[f+1]=mult(s[f],s[f+2])); ICPY(v+f+2,s+3+f,r-3); R reshape(x,y); }else{ - v=AS(y); + v=AS(y); RE(v[f+1]=mult(s[f],s[f+2])); ICPY(v+f+2,s+3+f,r-3); - --AR(y); + --AR(y); R y; }} /* ,./"r w */ @@ -563,7 +569,7 @@ static DF2(jtoprod){R df2(a,w,VAV(self)->h);} F1(jtslash){A h;AF f1=jtreduce;C c;V*v; RZ(w); if(NOUN&AT(w))R evger(w,sc(GINSERT)); - v=VAV(w); + v=VAV(w); switch(v->id){ case CCOMMA: f1=jtredcat; break; case CCOMDOT: f1=jtredstitch; break; @@ -607,7 +613,7 @@ DF1(jtmean){A z;I c,f,m,n,r,wn,wr,*ws,wt; if(!(wn&&2 +#include "required_arithmetic.h" + +#define FE_ALL_RND ( FE_TONEAREST | FE_TOWARDZERO | FE_UPWARD | FE_DOWNWARD ) + +#if defined( __GNUC__ ) + #define ALWAYS_INLINE __attribute__ ((__always_inline__)) +#else + #define ALWAYS_INLINE +#endif + +#ifndef __arm__ + #error This file is for use on ARM + VFP and later +#endif + + +#define GET_FPSCR() ({ uint32_t _fpscr; __asm__ __volatile__( "fmrx %0, fpscr" : "=r" (_fpscr) ); /* return */ _fpscr; }) +#define SET_FPSCR(_fpscr) __asm__ __volatile__( "fmxr fpscr, %0" : : "r" (_fpscr) ) + + +const fenv_t _FE_DFL_ENV = {{{ 0, 0, 0, 0 }}}; +// Worker functions for making sure that much of the work is done in a uniform way + +// For each bit set in excepts, change the floating point state to match the correspinding bit in *flagp +static inline int _fesetexceptflag_private(const fexcept_t *flagp, int excepts ) ALWAYS_INLINE; +static inline int _fesetexceptflag_private(const fexcept_t *flagp, int excepts ) +{ + uint32_t fpscr = GET_FPSCR(); + + excepts &= FE_ALL_EXCEPT | 0x8000; + + fpscr &= ~excepts; + fpscr |= *flagp & excepts; + + SET_FPSCR( fpscr ); + + return 0; +} + +// For each bit set in excepts, copy the corresponding bit from the floating point state into *flagp +// All other bits shall be set to zero +static inline int _fegetexceptflag_private(fexcept_t *flagp, int excepts); +static inline int _fegetexceptflag_private(fexcept_t *flagp, int excepts) +{ + uint32_t fpscr = GET_FPSCR(); + + *flagp = fpscr & excepts; + + return 0; +} + + + +/******************************************************************************* +* The function "feclearexcept" clears the supported floating point * +* exceptions represented by its argument. * +*******************************************************************************/ + +int feclearexcept(int excepts) +{ + fexcept_t zero = 0; + return _fesetexceptflag_private( &zero, excepts ); +} + + + +/******************************************************************************* +* The function "feraiseexcept" raises the supported floating-point * +* exceptions represented by its argument. The order in which these * +* floating-point exceptions are raised is unspecified. * +*******************************************************************************/ + +int feraiseexcept(int excepts) +{ + int inexact_set = 0; + + if( excepts & FE_OVERFLOW ) + { + required_add_float( 0x1.0p127f, 0x1.0p127f ); + inexact_set = 1; + } + if( excepts & FE_UNDERFLOW ) + { + required_multiply_float( 0x1.0p-126f, 0x1.0p-126f ); + inexact_set = 1; + } + if( excepts & FE_INVALID ) + required_add_float( __builtin_inff(), -__builtin_inff() ); + if( excepts & FE_DIVBYZERO ) + required_divide_float( 1.0f, 0.0f ); + if( 0 != (excepts & FE_INEXACT) && 0 == inexact_set ) + required_add_float( 0x1.0p127f, 1.0f ); + + return 0; +} + + + + + + +/******************************************************************************* +* The function "fetestexcept" determines which of the specified subset of * +* the floating-point exception flags are currently set. The excepts * +* argument specifies the floating-point status flags to be queried. This * +* function returns the value of the bitwise OR of the floating-point * +* exception macros corresponding to the currently set floating-point * +* exceptions included in excepts. * +* * +*******************************************************************************/ + +int fetestexcept(int excepts ) +{ + fexcept_t t = 0; + + _fegetexceptflag_private( &t, excepts); + + return t; +} + + +/******************************************************************************* +* The following functions provide control of rounding direction modes. * +*******************************************************************************/ + +/******************************************************************************* +* The function "fegetround" returns the value of the rounding direction * +* macro which represents the current rounding direction, or a negative * +* if there is no such rounding direction macro or the current rounding * +* direction is not determinable. * +*******************************************************************************/ + +int fegetround(void) +{ + int32_t fpscr = GET_FPSCR(); + + return fpscr & FE_ALL_RND; +} + + +/******************************************************************************* +* The function "fesetround" establishes the rounding direction represented * +* by its argument "round". If the argument is not equal to the value of a * +* rounding direction macro, the rounding direction is not changed. It * +* returns zero if and only if the argument is equal to a rounding * +* direction macro. * +*******************************************************************************/ + +int fesetround(int round ) +{ + if( (round & FE_ALL_RND) != round ) + return round; + + int32_t fpscr = GET_FPSCR(); + + fpscr &= ~FE_ALL_RND; + fpscr |= round & FE_ALL_RND; + + SET_FPSCR( fpscr ); + + return 0; +} + + +/******************************************************************************* +* The following functions manage the floating-point environment, exception * +* flags and dynamic modes, as one entity. * +*******************************************************************************/ + +/******************************************************************************* +* The fegetenv function stores the current floating-point enviornment in * +* the object pointed to by envp. * +*******************************************************************************/ +int fegetenv(fenv_t *envp) +{ + envp->__fpscr = GET_FPSCR(); + envp->__reserved0 = 0; + envp->__reserved1 = 0; + envp->__reserved2 = 0; + + return 0; +} + +/******************************************************************************* +* The feholdexcept function saves the current floating-point environment in * +* the object pointed to by envp, clears the floating-point status flags, * +* and then installs a non-stop (continue on floating-point exceptions) * +* mode, if available, for all floating-point exceptions. The feholdexcept * +* function returns zero if and only if non-stop floating-point exceptions * +* handling was successfully installed. * +*******************************************************************************/ +int feholdexcept(fenv_t *envp) +{ + uint32_t fpscr = GET_FPSCR(); + + envp->__fpscr = fpscr; + envp->__reserved0 = 0; + envp->__reserved1 = 0; + envp->__reserved2 = 0; + + fpscr &= ~( FE_ALL_EXCEPT | (FE_ALL_EXCEPT << 8) ); + + SET_FPSCR( fpscr ); + + return 0; +} + + +/******************************************************************************* +* The fesetnv function establishes the floating-point environment * +* represented by the object pointed to by envp. The argument envp shall * +* point to an object set by a call to fegetenv or feholdexcept, or equal to * +* a floating-point environment macro -- we define only *FE_DFL_ENV and * +* FE_DISABLE_SSE_DENORMS_ENV -- to be C99 standard compliant and portable * +* to other architectures. Note that fesetnv merely installs the state of * +* the floating-point status flags represented through its argument, and * +* does not raise these floating-point exceptions. * +* * +*******************************************************************************/ +int fesetenv(const fenv_t *envp) +{ + SET_FPSCR( envp->__fpscr ); + + return 0; +} + + + +/******************************************************************************* +* The feupdateenv function saves the currently raised floating-point * +* exceptions in its automatic storage, installs the floating-point * +* environment represented by the object pointed to by envp, and then raises * +* the saved floating-point exceptions. The argument envp shall point to an * +* object set by a call to feholdexcept or fegetenv or equal a * +* floating-point environment macro. * +* * +*******************************************************************************/ +int feupdateenv(const fenv_t *envp) +{ + uint32_t oldenv = GET_FPSCR(); + + SET_FPSCR( envp->__fpscr ); + + int inexact_set = 0; + + if( oldenv & FE_OVERFLOW ) + { + required_add_float( 0x1.0p127f, 0x1.0p127f ); + inexact_set = 1; + } + if( oldenv & FE_UNDERFLOW ) + { + required_multiply_float( 0x1.0p-126f, 0x1.0p-126f ); + inexact_set = 1; + } + if( oldenv & FE_INVALID ) + required_add_float( __builtin_inff(), -__builtin_inff() ); + if( oldenv & FE_DIVBYZERO ) + required_divide_float( 1.0f, 0.0f ); + if( 0 != (oldenv & FE_INEXACT) && 0 == inexact_set ) + required_add_float( 0x1.0p127f, 1.0f ); + + return 0; +} + + +/******************************************************************************* +* The function "fegetexceptflag" stores a implementation-defined * +* representation of the states of the floating-point status flags indicated * +* by its integer argument excepts in the object pointed to by the argument, * +* flagp. * +*******************************************************************************/ + +int fegetexceptflag(fexcept_t *flagp, int excepts) +{ + return _fegetexceptflag_private( flagp, excepts ); +} + +/******************************************************************************* +* The function "fesetexceptflag" sets or clears the floating point status * +* flags indicated by the argument excepts to the states stored in the * +* object pointed to by flagp. The value of the *flagp shall have been set * +* by a previous call to fegetexceptflag whose second argument represented * +* at least those floating-point exceptions represented by the argument * +* excepts. This function does not raise floating-point exceptions; it just * +* sets the state of the flags. * +*******************************************************************************/ + +int fesetexceptflag(const fexcept_t *flagp, int excepts ) +{ + return _fesetexceptflag_private( flagp, excepts ); +} + +#endif diff --git a/arm/fenv.h b/arm/fenv.h new file mode 100644 index 0000000..564bd7b --- /dev/null +++ b/arm/fenv.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/******************************************************************************* +* * +* File: fenv.h * +* * +* Contains: typedefs and prototypes for C99 floating point environment. * +* * +*******************************************************************************/ + +#ifndef __FENV__ +#define __FENV__ + +/* We require VFP for this set of interfaces to work */ +#if !defined(__VFP_FP__) || defined(__SOFTFP__) + #warning The functions are not supported on platforms that do not have hardware floating-point. +#else + +#if defined(__GNUC__) && (__GNUC__ >= 4) + #pragma GCC fenv +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + A collection of functions designed to provide access to the floating + point environment for numerical programming. It is compliant with + the floating-point requirements in C99. + + The file declares many functions in support of numerical + programming. Programs that test flags or run under + non-default modes must do so under the effect of an enabling + "fenv_access" pragma: + + Note that prior to iPhone OS 2.0, these interfaces did nothing. + + #pragma STDC FENV_ACCESS on +*/ + +/******************************************************************************** +* * +* fenv_t is a type for representing the entire floating-point * +* environment in a single object. * +* * +* fexcept_t is a type for representing the floating-point * +* exception flag state collectively. * +* * +********************************************************************************/ + + + +typedef struct { +#if 0 + union + { + struct + { +#endif + unsigned int __fpscr; + unsigned int __reserved0; + unsigned int __reserved1; + unsigned int __reserved2; +#if 0 + } ; +#if defined( __GNUC__ ) + struct + { + unsigned int __fpscr_cmp_n : 1; + unsigned int __fpscr_cmp_z : 1; + unsigned int __fpscr_cmp_c : 1; + unsigned int __fpscr_cmp_v : 1; + unsigned int __fpscr_do_not_modify_1 : 2; /* Should be zero */ + unsigned int __fpscr_default_nan_mode : 1; + unsigned int __fpscr_flush_to_zero : 1; + unsigned int __fpscr_rounding_mode : 2; + unsigned int __fpscr_stride : 2; + unsigned int __fpscr_do_not_modify_2 : 1; /* Should be zero */ + unsigned int __fpscr_len : 3 ; + unsigned int __fpscr_trap_enable_subnormal : 1 ; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_do_not_modfify_3 : 2; /* Should be zero */ + unsigned int __fpscr_trap_enable_inexact : 1; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_trap_enable_underflow : 1; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_trap_enable_overflow : 1; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_trap_enable_div_by_zero : 1; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_trap_enable_invalid : 1; /* Note: we run under "Run Fast Mode". Setting this bit has undefined results. */ + unsigned int __fpscr_fp_state_flag_subnormal : 1; + unsigned int __fpscr_do_not_modify_4 : 2; /* Should be zero */ + unsigned int __fpscr_fp_state_flag_inexact : 1; + unsigned int __fpscr_fp_state_flag_underflow : 1; + unsigned int __fpscr_fp_state_flag_overflow : 1; + unsigned int __fpscr_fp_state_flag_div_by_zero : 1; + unsigned int __fpscr_fp_state_flag_invalid : 1; + } __attribute((packed)); +#endif + }; +#endif +} fenv_t; + +typedef unsigned short fexcept_t; + +/* Definitions of floating-point exception macros */ +#define FE_INEXACT 0x0010 +#define FE_UNDERFLOW 0x0008 +#define FE_OVERFLOW 0x0004 +#define FE_DIVBYZERO 0x0002 +#define FE_INVALID 0x0001 +#define FE_ALL_EXCEPT 0x001F + +/* Definitions of rounding direction macros */ +#define FE_TONEAREST 0x00000000 +#define FE_UPWARD 0x00400000 +#define FE_DOWNWARD 0x00800000 +#define FE_TOWARDZERO 0x00C00000 + +/* default environment object */ +extern const fenv_t _FE_DFL_ENV; +#define FE_DFL_ENV &_FE_DFL_ENV /* pointer to default environment */ + + +/******************************************************************************* +* The following functions provide high level access to the exception flags.* +* The "int" input argument can be constructed by bitwise ORs of the * +* exception macros: for example: FE_OVERFLOW | FE_INEXACT. * +*******************************************************************************/ + +/******************************************************************************* +* The function "feclearexcept" clears the supported floating point * +* exceptions represented by its argument. * +*******************************************************************************/ + +extern int feclearexcept(int /*excepts*/); + + +/******************************************************************************* +* The function "fegetexceptflag" stores a implementation-defined * +* representation of the states of the floating-point status flags indicated * +* by its integer argument excepts in the object pointed to by the argument, * +* flagp. * +*******************************************************************************/ + +extern int fegetexceptflag(fexcept_t * /*flagp*/, int /*excepts*/); + + +/******************************************************************************* +* The function "feraiseexcept" raises the supported floating-point * +* exceptions represented by its argument. The order in which these * +* floating-point exceptions are raised is unspecified. * +*******************************************************************************/ + +extern int feraiseexcept(int /*excepts*/); + + +/******************************************************************************* +* The function "fesetexceptflag" sets or clears the floating point status * +* flags indicated by the argument excepts to the states stored in the * +* object pointed to by flagp. The value of the *flagp shall have been set * +* by a previous call to fegetexceptflag whose second argument represented * +* at least those floating-point exceptions represented by the argument * +* excepts. This function does not raise floating-point exceptions; it just * +* sets the state of the flags. * +*******************************************************************************/ + +extern int fesetexceptflag(const fexcept_t * /*flagp*/, int /*excepts*/); + + +/******************************************************************************* +* The function "fetestexcept" determines which of the specified subset of * +* the floating-point exception flags are currently set. The excepts * +* argument specifies the floating-point status flags to be queried. This * +* function returns the value of the bitwise OR of the floating-point * +* exception macros corresponding to the currently set floating-point * +* exceptions included in excepts. * +* * +*******************************************************************************/ + +extern int fetestexcept(int /*excepts*/); + + +/******************************************************************************* +* The following functions provide control of rounding direction modes. * +*******************************************************************************/ + +/******************************************************************************* +* The function "fegetround" returns the value of the rounding direction * +* macro which represents the current rounding direction, or a negative * +* if there is no such rounding direction macro or the current rounding * +* direction is not determinable. * +*******************************************************************************/ + +extern int fegetround(void); + + +/******************************************************************************* +* The function "fesetround" establishes the rounding direction represented * +* by its argument "round". If the argument is not equal to the value of a * +* rounding direction macro, the rounding direction is not changed. It * +* returns zero if and only if the argument is equal to a rounding * +* direction macro. * +*******************************************************************************/ + +extern int fesetround(int /*round*/); + + +/******************************************************************************* +* The following functions manage the floating-point environment, exception * +* flags and dynamic modes, as one entity. * +*******************************************************************************/ + +/******************************************************************************* +* The fegetenv function stores the current floating-point enviornment in * +* the object pointed to by envp. * +*******************************************************************************/ +extern int fegetenv(fenv_t * /*envp*/); + +/******************************************************************************* +* The feholdexcept function saves the current floating-point environment in * +* the object pointed to by envp, clears the floating-point status flags, * +* and then installs a non-stop (continue on floating-point exceptions) * +* mode, if available, for all floating-point exceptions. The feholdexcept * +* function returns zero if and only if non-stop floating-point exceptions * +* handling was successfully installed. * +*******************************************************************************/ +extern int feholdexcept(fenv_t * /*envp*/); + +/******************************************************************************* +* The fesetnv function establishes the floating-point environment * +* represented by the object pointed to by envp. The argument envp shall * +* point to an object set by a call to fegetenv or feholdexcept, or equal to * +* a floating-point environment macro -- we define only *FE_DFL_ENV and * +* FE_DISABLE_SSE_DENORMS_ENV -- to be C99 standard compliant and portable * +* to other architectures. Note that fesetnv merely installs the state of * +* the floating-point status flags represented through its argument, and * +* does not raise these floating-point exceptions. * +*******************************************************************************/ +extern int fesetenv(const fenv_t * /*envp*/); + +/******************************************************************************* +* The feupdateenv function saves the currently raised floating-point * +* exceptions in its automatic storage, installs the floating-point * +* environment represented by the object pointed to by envp, and then raises * +* the saved floating-point exceptions. The argument envp shall point to an * +* object set by a call to feholdexcept or fegetenv or equal a * +* floating-point environment macro. * +*******************************************************************************/ +extern int feupdateenv(const fenv_t * /*envp*/); + +#ifdef __cplusplus +} +#endif + +#endif // HARDWARE FP + +#endif /* __FENV__ */ diff --git a/bin/build_defs b/bin/build_defs index 9a67564..c44d5e7 100755 --- a/bin/build_defs +++ b/bin/build_defs @@ -11,12 +11,12 @@ suffix=".ijs" else suffix="_64.ijs" fi - + rm -f defs/netdefs.ijs defs/hostdefs.ijs defs/temp -cc $M32 -D$un defs/netdefs.c -o defs/temp -defs/temp >defs/netdefs.ijs -cc $M32 -D$un defs/hostdefs.c -o defs/temp -defs/temp >defs/hostdefs.ijs +${CC} $M32 -D$un defs/netdefs.c -o defs/temp +${WINE} ./defs/temp >defs/netdefs.ijs +${CC} $M32 -D$un defs/hostdefs.c -o defs/temp +${WINE} ./defs/temp >defs/hostdefs.ijs rm -f defs/temp if [ -e defs/hostdefs.ijs ] && [ -e defs/netdefs.ijs ] diff --git a/bin/build_jconsole b/bin/build_jconsole index e8d88b3..3df5b62 100755 --- a/bin/build_jconsole +++ b/bin/build_jconsole @@ -4,7 +4,15 @@ make jconsole if [ -x jconsole ] then +strip jconsole +if [ $un != Win ] +then cp jconsole j/bin/. +cp jconsole release/$un$bits/. +else +cp jconsole j/bin/jconsole.exe +cp jconsole release/$un$bits/jconsole.exe +fi echo success: jconsole created and copied to j/bin else echo failed: jconsole NOT created diff --git a/bin/build_libj b/bin/build_libj index 63adc86..3a9cbe8 100755 --- a/bin/build_libj +++ b/bin/build_libj @@ -124,9 +124,19 @@ xs.o \ xt.o \ xu.o " -echo COMP $COMP -echo LINK $SOLINK -export LIBJ_OBJS +if [ $un = Win ]; then +LIBJ_WIN_OBJS="win/jdll.o " +if [ $olecom = 1 ]; then +LIBJ_WINOLE_OBJS="win/jdllcomx.o " +fi +LIBJDEF="win/jdll.def" +fi + +if [ $jjni = 1 ]; then +LIBJ_JJNI_OBJS="javaconsole/jinterface.o " +fi + +export LIBJ_OBJS LIBJ_WIN_OBJS LIBJ_WINOLE_OBJS LIBJDEF LIBJ_JJNI_OBJS echo takes minutes for a clean build echo "running: make libj >& make.txt" @@ -138,10 +148,17 @@ cat make.txt | grep -Ev "assignment from incompatible pointer type|initializatio cat esum.txt -if [ -x libj.$SOSUFFIX ] +if [ -x $TARGET.$SOSUFFIX ] then -cp libj.$SOSUFFIX j/bin/. -echo success: libj.$SOSUFFIX created and copied to j/bin +strip $TARGET.$SOSUFFIX +if [ $un = Win ]; then +cp $TARGET.$SOSUFFIX j/bin/j.$SOSUFFIX +cp $TARGET.$SOSUFFIX release/$un$bits/j.$SOSUFFIX +else +cp $TARGET.$SOSUFFIX j/bin/$TARGET.$SOSUFFIX +cp $TARGET.$SOSUFFIX release/$un$bits/$TARGET.$SOSUFFIX +fi +echo success: $TARGET.$SOSUFFIX created and copied to j/bin else -echo failed: libj.$SOSUFFIX NOT created +echo failed: $TARGET.$SOSUFFIX NOT created fi diff --git a/bin/build_tsdll b/bin/build_tsdll index f3f8354..a419a15 100755 --- a/bin/build_tsdll +++ b/bin/build_tsdll @@ -1,11 +1,24 @@ #!/bin/bash +source bin/jconfig + +if [ $un == Win ] +then +TARGET=tsdll +else TARGET=libtsdll +fi source bin/jconfig + +if [ $un = Win ]; then +export LIBTSDEF="tsdll.def" +fi + make tsdll -if [ -x libj.$SOSUFFIX ] +if [ -x $TARGET.$SOSUFFIX ] then -echo success: libtsdll.$SOSUFFIX created +cp $TARGET.$SOSUFFIX release/$un$bits/$TARGET.$SOSUFFIX +echo success: $TARGET.$SOSUFFIX created else -echo failed: libtsdll.$SOSUFFIX NOT created +echo failed: $TARGET.$SOSUFFIX NOT created fi diff --git a/bin/jconfig b/bin/jconfig index a398ca8..bfc6f93 100755 --- a/bin/jconfig +++ b/bin/jconfig @@ -1,11 +1,15 @@ # configuration for build shell scripts - edit to configure +if [ "no" = "$JAVA_HOME"no ]; then +JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.26 +fi + # bits 32 or 64 -bits=64 +bits="${bits:=64}" # readline 0 or 1 to enable jconsole line recall -readline=0 -LIBREADLINE="" +# readline=0 +# LIBREADLINE="" # readline should be enabled if possible @@ -15,17 +19,25 @@ LIBREADLINE=" -lreadline " # if link fails install readline or try one of next lines # LIBREADLINE=" -ledit -lncurses " -# LIBREADLINE=" -ledit64 -lnccurses " +# LIBREADLINE=" -ledit64 -lnccurses " # be careful with changes after this line +if [ "no" = "$un"no ]; then un=`uname` +fi lcun=$( echo "$un" | tr -s '[:upper:]' '[:lower:]' ) +if [ "no" = "$HOSTCPU"no ]; then +HOSTCPU=`uname -m` +fi + if [ $un != Linux ] && [ $un != Darwin ] && [ $un != FreeBSD ] then -echo jconfig: not Linux or Darwin - changes to jconfig and other files required +echo jconfig: not Linux or Darwin Or Win - changes to jconfig and other files required exit 1 +else +echo jconfig: build for $un fi if [ $bits != 32 ] && [ $bits != 64 ] @@ -40,11 +52,58 @@ echo jconfig: readline must be 0 or 1 exit 1 fi -COMP=" -fPIC -O3 -fno-strict-aliasing -DNOASM " +if [ "no" = "$olecom"no ]; then +olecom=0 +fi + +if [ $un != Win ] +then +olecom=0 +fi + +if [ $olecom != 0 ] && [ $olecom != 1 ] +then +echo jconfig: olecom must be 0 or 1 +exit 1 +fi + +if [ $un == Win ] +then +if [ $olecom == 1 ]; then +OLECOMX=" -DOLECOM " +fi +# readline 0 or 1 to enable jconsole line recall +readline=0 +LIBREADLINE="" +fi + +if [ "no" = "$jjni"no ]; then +jjni=0 +fi + +if [ $jjni != 0 ] && [ $jjni != 1 ] +then +echo jconfig: jjni must be 0 or 1 +exit 1 +fi + +if [ $jjni == 1 ]; then +JJNIX=" -DJJNI -I$JAVA_HOME/include -I$JAVA_HOME/include/linux " +fi + +if [ $un == Win ] +then +JCONLINK=' -Wl,--stack=8000000 ' +SOLINK=" -shared -Wl,--enable-stdcall-fixup -lm -lole32 -loleaut32 -luuid -o " +TSLINK=" -shared -Wl,--enable-stdcall-fixup -o " +SOSUFFIX=dll +fi if [ $un == Linux ] then -SOLINK=" -shared -W1,soname,libj.so -lm -ldl -o " +JCONLINK=" -ldl " +SOLINK=" -shared -Wl,-soname,libj.so -lm -ldl -o " +TSLINK=" -shared -Wl,-soname,libtsdll.so -ldl -o " SOSUFFIX=so fi @@ -56,18 +115,57 @@ fi if [ $un == Darwin ] then +JCONLINK="" SOLINK=" -dynamiclib -lm -ldl -o " +TSLINK=" -dynamiclib -ldl -o " SOSUFFIX=dylib fi if [ $bits == 32 ] then -COMP=" -m32 $COMP " -SOLINK=" -m32 $SOLINK " +if [ $un != Win ] +then +# faster, but sse2 not available for 32-bit amd cpu +# sse does not support mfpmath=sse in 32-bit gcc +DPREC=" -msse2 -mfpmath=sse " +else +# slower, use 387 fpu and truncate extra precision +# this still fail linux g410 g421p (repeat several times) +DPREC=" -ffloat-store " +fi M32=" -m32 " +NOASM=" -DNOASM " else -COMP=" -D_UNIX64 $COMP " +if [ $un != Win ] +then +UNIX64=" -D_UNIX64 " +fi +DPREC="" +M32=" -m64 " +NOASM=" -DNOASM " +fi + +OPTCF=" -O3 -fno-strict-aliasing -fsignaling-nans " + +if [ ${HOSTCPU:0:3} == arm ] +then +bits=32 +NOASM=" -DNOASM " +DPREC=" -mfloat-abi=softfp -mfpu=vfpv3 -march=armv7-a " M32="" +UNIX64="" +OPTCF=" -Os -fno-strict-aliasing -fsignaling-nans " +fi + +# -O2 need -fno-strict-aliasing for dtoa.c, +# -O3 linux gcc 4.6 crashed because of -ftree-vectorize misalignment +# either add -fno-tree-vectorize (disable all loop vectorize) +# or define _MISALIGN_BYTEVECTOR (disable some codes inside ar.c, 32-bit fails g331ins space requirement of test 0 1, need to relax) +if [ $un == Win ] +then +COMP=" $OPTCF -std=c99 -pedantic -D_MISALIGN_BYTEVECTOR -D_JDLL -D_FILE_OFFSET_BITS=64 $OLECOMX $M32 $NOASM $DPREC $JJNIX $COMP " +else +COMP=" $OPTCF -std=c99 -pedantic -D_MISALIGN_BYTEVECTOR -fpic -D__USE_MISC -D_XOPEN_SOURCE -D_FILE_OFFSET_BITS=64 $UNIX64 $M32 $NOASM $DPREC $JJNIX $COMP " fi if [ $readline == 1 ] @@ -75,5 +173,7 @@ then COMP="-DREADLINE $COMP " fi -SOLINK=" $SOLINK $TARGET.$SOSUFFIX " -export COMP SOLINK M32 LIBREADLINE +SOLINK=" $M32 $SOLINK $TARGET.$SOSUFFIX " +TSLINK=" $M32 $TSLINK $TARGET.$SOSUFFIX " +JCONLINK=" $M32 $JCONLINK " +export COMP JCONLINK TSLINK SOLINK LIBREADLINE olecom diff --git a/defs/Android.mk b/defs/Android.mk index 15c58d5..34c8934 100644 --- a/defs/Android.mk +++ b/defs/Android.mk @@ -3,9 +3,9 @@ # In this case, it causes netdefs and hostdefs to be created. The Android build system copys the final # binary to the directory /libs/ -# In order to build an Android package, -# those binaries must be uploaded onto an android device or emulator and executed. -# The output of these programs become netdefs_android.ijs and hostdefs_android.ijs respectively. +# In order to build an Android package, +# those binaries must be uploaded onto an android device or emulator and executed. +# The output of these programs become netdefs_android.ijs and hostdefs_android.ijs respectively. # They must be placed in /assets/system/defs in the final package in order to # be installed at first boot along with the rest of the system files. diff --git a/defs/Android.mk.1 b/defs/Android.mk.1 new file mode 100644 index 0000000..63f06d7 --- /dev/null +++ b/defs/Android.mk.1 @@ -0,0 +1,37 @@ + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := j-netdefs + +LOCAL_LDLIBS := -llog -ldl -lm -lc + +LOCAL_CFLAGS := -O0 -fno-omit-frame-pointer -fno-strict-aliasing -fno-unwind-tables -fno-tree-vectorize -D_MISALIGN_BYTEVECTOR -DNOASM -fPIC + + +LOCAL_SRC_FILES := netdefs.c + + +include $(BUILD_EXECUTABLE) + + + + + +include $(CLEAR_VARS) + +LOCAL_MODULE := j-hostdefs + +LOCAL_LDLIBS := -llog -ldl -lm -lc + +LOCAL_CFLAGS := -O0 -fno-omit-frame-pointer -fno-strict-aliasing -fno-unwind-tables -fno-tree-vectorize -D_MISALIGN_BYTEVECTOR -DNOASM -fPIC + + +LOCAL_SRC_FILES := hostdefs.c + + +include $(BUILD_EXECUTABLE) + + + diff --git a/defs/hostdefs.c b/defs/hostdefs.c index 24b8e64..33fd2a0 100644 --- a/defs/hostdefs.c +++ b/defs/hostdefs.c @@ -9,7 +9,8 @@ #else #include -#include "winregex\rxposix.h" +//#include "winregex\rxposix.h" +#include "pcreposix.h" #endif #include #include diff --git a/defs/hostdefs.sym b/defs/hostdefs.sym index 2aaccb8..2ff37cb 100644 --- a/defs/hostdefs.sym +++ b/defs/hostdefs.sym @@ -9,7 +9,8 @@ #else -#include "winregex\rxposix.h" +//#include "winregex\rxposix.h" +#include "pcreposix.h" #endif @@ -34,7 +35,7 @@ i SEEK_CUR SEEK_END SEEK_SET i O_APPEND O_CREAT O_EXCL O_RDONLY O_RDWR O_TRUNC O_WRONLY #ifndef _WIN32 -i O_ACCMODE O_NOCTTY O_NONBLOCK +i O_ACCMODE O_NOCTTY O_NONBLOCK i FD_CLOEXEC i F_DUPFD F_GETFD F_SETFD F_GETFL F_SETFL i F_SETLK F_SETLKW F_GETLK F_UNLCK F_WRLCK @@ -90,4 +91,4 @@ i EEXIST ENAMETOOLONG #ifndef _WIN32 i EINPROGRESS ECANCELED ETIMEDOUT EMSGSIZE ENOTSUP -#endif \ No newline at end of file +#endif diff --git a/f2.c b/f2.c index 4c8dc28..9973652 100644 --- a/f2.c +++ b/f2.c @@ -4,17 +4,15 @@ /* Format: ": Dyad */ #include "j.h" - - static F2(jtth2box){A z;I n,p,q,*v,x,y; p=jt->pos[0]; q=jt->pos[1]; RZ(a=vi(a)); n=AN(a); v=AV(a); ASSERT(1>=AR(a),EVRANK); ASSERT(1==n||2==n,EVLENGTH); - x=v[0]; y=2>n?0:v[1]; + x=v[0]; y=2>n?0:v[1]; ASSERT(0<=x&&x<=2&&0<=y&&y<=2,EVDOMAIN); jt->pos[0]=x; jt->pos[1]=y; - z=thorn1(w); + z=thorn1(w); jt->pos[0]=p; jt->pos[1]=q; R z; } @@ -30,7 +28,7 @@ static I jtc2j(J jt,B e,I m,C*zv){C c,*s,*t;I k,p; }} t=jt->th2buf; k=strlen(t); if(!e&&(s=memchr(t,'-',k))){ /* turn -0 to 0 */ - *s=' '; + *s=' '; DO(k-(1+s-t), c=s[1+i]; if(c!='0'&&c!='.'){*s=CSIGN; break;}); if(!m&&' '==*s){++t; --k;} } @@ -59,7 +57,7 @@ static B jtfmtex(J jt,I m,I d,I n,I*xv,B b,I c,I q,I ex){B bm=b||m;C*u,*v=jt->th } /* format one extended integer in exponential form */ static B jtfmtx(J jt,B e,I m,I d,C*s,I t,X*wv){B b;C*v=jt->th2buf;I c,n,p,q,*xv;X x; - x=*wv; n=AN(x); xv=AV(x)+n-1; + x=*wv; n=AN(x); xv=AV(x)+n-1; c=*xv; b=0>c; if(b)c=-c; if(c==XPINF){if(b)*v++='_'; *v++='_'; *v=0; R 1;} q=c>999?4:c>99?3:c>9?2:1; p=q+XBASEN*(n-1); @@ -67,9 +65,9 @@ static B jtfmtx(J jt,B e,I m,I d,C*s,I t,X*wv){B b;C*v=jt->th2buf;I c,n,p,q,*xv; else if(m&&mth2bufn<4+p+d){A s; jt->th2bufn=4+p+d; GA(s,LIT,jt->th2bufn,1,0); v=jt->th2buf=CAV(s);} - if(' '==*s)*v++=' '; if(b)*v++='_'; + if(' '==*s)*v++=' '; if(b)*v++='_'; sprintf(v,FMTI,c); v+=q; - DO(n-1, c=*--xv; sprintf(v,FMTI04,b?-c:c); v+=XBASEN;); + DO(n-1, c=*--xv; sprintf(v,FMTI04,b?-c:c); v+=XBASEN;); if(d){*v++='.'; memset(v,'0',d); v[d]=0;} } R 1; @@ -114,7 +112,11 @@ static void jtfmt1(J jt,B e,I m,I d,C*s,I t,C*wv){D y; else if(!memcmp(wv,&infm,SZD))strcpy(jt->th2buf,e?" __" :' '==*s?" __":"__"); else if(_isnan(*wv) )strcpy(jt->th2buf,e?" _.":' '==*s?" _.":"_."); else sprintf(jt->th2buf,s,y); -}} /* format one number */ +} +#ifdef __MINGW32__ +if ('+'==jt->th2buf[0])jt->th2buf[0]=' '; +#endif +} /* format one number */ static void jtth2c(J jt,B e,I m,I d,C*s,I n,I t,I wk,C*wv,I zk,C*zv){ DO(n, fmt1(e,m,d,s,t,wv); c2j(e,m,zv); zv+=zk; wv+=wk;); @@ -131,7 +133,7 @@ static A jtth2a(J jt,B e,I m,I d,C*s,I n,I t,I wk,C*wv,B first){PROLOG;A y,z;B b } m+=!first; GA(y,LIT,n*m,2,0); *AS(y)=n; *(1+AS(y))=m; - yv=CAV(y); memset(yv,' ',AN(y)); u=zv; + yv=CAV(y); memset(yv,' ',AN(y)); u=zv; if(e){yv+=!first; DO(n, q=strlen(u); MC(yv+(b&&CSIGN!=*u),u,q); yv+=m; u+=1+q;);} else {yv+=m; DO(n, q=strlen(u); MC(yv-q, u,q); yv+=m; u+=1+q;);} EPILOG(y); @@ -154,8 +156,13 @@ static B jtth2ctrl(J jt,A a,A*ep,A*mp,A*dp,A*sp,I*zkp){A da,ea,ma,s;B b=1,*ev,r; } if(0>m)m=-m; if(0>d)d=-d; ASSERT(0<=m&&0<=d,EVLIMIT); if(0<=x)sprintf(sv, "%%"FMTI"."FMTI"f", m,d); +// mingw bug for spec "%- 7.0e+000" , missing the leading space for positive number +#ifdef __MINGW32__ + else sprintf(sv, m?"%%-+"FMTI"."FMTI"e" :"%%-"FMTI"."FMTI"e", m?m-1:0,d+!!(SYS&SYS_PC)); +#else else sprintf(sv, m?"%%- "FMTI"."FMTI"e" :"%%-"FMTI"."FMTI"e", m?m-1:0,d+!!(SYS&SYS_PC)); - sv+=sk; ev[i]=0>x; mv[i]=m; dv[i]=d; zk+=m; b=b&&m; +#endif + sv+=sk; ev[i]=0>x; mv[i]=m; dv[i]=d; zk+=m; b=b&&m; if(jt->th2bufnth2bufn=m; if(jt->th2bufn<500+d)jt->th2bufn=500+d; } GA(s,LIT,jt->th2bufn,1,0); jt->th2buf=CAV(s); @@ -181,8 +188,8 @@ F2(jtthorn2){PROLOG;A da,ea,h,ma,s,y,*yv,z;B e,*ev;C*sv,*wv,*zv;I an,c,d,*dv,k,m DO(c, if(is,s,m); *(m+zv->s)=0; - zv->m =(UC)m; - zv->sn =0; + zv->m =(UC)m; + zv->sn =0; zv->e =0; zv->flag=NMDOT; - zv->hash=nmhash(m,s); + zv->hash=NMHASH(m,s); ACX(z); R z; } @@ -32,11 +32,11 @@ B jtglobinit(J jt){A x,y;C*s;D*d;I j;UC c,k; jt->adbreak=&breakdata; /* required for ma to work */ meminit(); /* required for ma to work */ jt->parsercalls=0; - s=bitdisp; + s=bitdisp; DO(256, c=(UC)i; DO(BB, *s++=c&(UC)128?'1':'0'; *s++=' '; c<<=1;); ); DO(16, c=(UC)i; k=0; DO(BB, if(c&(UC)1)++k; c>>=1;); bitc[i]=k;); DO(15, j=1+i; DO(16, bitc[16*j+i]=bitc[j]+bitc[i];);); - MC(&inf, XINF,SZD); + MC(&inf, XINF,SZD); MC(&jnan,XNAN,SZD); infm=-inf; memset(testb,C0,256); @@ -58,7 +58,7 @@ B jtglobinit(J jt){A x,y;C*s;D*d;I j;UC c,k; GA(x,INT, 1,1,0 ); ACX(x); * AV(x)=1; iv1=xone =x; GA(x,FL, 1,0,0 ); ACX(x); *DAV(x)=inf; ainf =x; GA(x,FL, 1,0,0 ); ACX(x); *DAV(x)=PI; pie =x; - GA(x,MARK,1,0,0 ); ACX(x); * AV(x)=0; mark =x; + GA(x,MARK,1,0,0 ); ACX(x); * AV(x)=0; mark =x; GA(x,B01, 0,2,&zeroZ); ACX(x); mtm =x; GA(x,CMPX,1,0,0 ); ACX(x); d=DAV(x); *d=0; *(1+d)=1; a0j1 =x; RZ(y=str(1L,"z")); ACX(y); diff --git a/io.c b/io.c index f338e07..59bba51 100644 --- a/io.c +++ b/io.c @@ -8,6 +8,7 @@ #include #else #include +#include #include #include #include @@ -16,6 +17,8 @@ #define _stdcall #endif +#include + #include "j.h" #include "d.h" @@ -27,21 +30,24 @@ void jtwri(J jt,I type,C*p,I m,C*s){C buf[1024],*t=jt->outseq,*v=buf;I c,d,e,n; d=m>n?n-3:m; memcpy(v,p,c); v+=c; memcpy(v,s,d); v+=d; if(m>n){memcpy(v,"...",3L); v+=3;} - memcpy(v,t,e); v+=e; + memcpy(v,t,e); v+=e; *v=0; jsto(jt,type,buf); }} static void jtwrf(J jt,I n,C*v,F f){C*u,*x;I j=0,m; while(n>j){ - u=j+v; - m=(x=memchr(u,CLF,n-j))?1+x-u:n-j; + u=j+v; + m=(x=memchr(u,CLF,n-j))?1+x-u:n-j; fwrite(u,sizeof(C),m,f); j+=m; }} A jtinpl(J jt,B b,I n,C*s){C c;I k=0; if(n&&(c=*(s+n-1),CLF==c||CCR==c))--n; +#if _WIN32 + if(n&&(c=*(s+n-1),CCR==c))--n; +#endif ASSERT(!*jt->adbreak,EVINPRUPT); if(!b){ /* 1==b means literal input */ if(n&&COFF==*(s+n-1))joff(zero); @@ -51,7 +57,7 @@ A jtinpl(J jt,B b,I n,C*s){C c;I k=0; } static I advl(I j,I n,C*s){B b;C c,*v; - v=j+s; + v=j+s; DO(n-j, c=*v++; b=c==CCR; if(b||c==CLF)R j+1+i+(b&&CLF==*v);); R n; } /* advance one line on CR, CRLF, or LF */ @@ -71,7 +77,7 @@ A jtjgets(J jt,C*p){A y;B b;C*v;I j,k,m,n;UC*s; *jt->adbreak=0; if(b=1==*p)p=""; /* 1 means literal input */ if(jt->dcs){ - ++jt->dcs->dcn; j=jt->dcs->dci; + ++jt->dcs->dcn; j=jt->dcs->dci; y=jt->dcs->dcy; n=AN(y); s=UAV(y); RZ(jdcs->dcj=k=j; @@ -88,7 +94,7 @@ A jtjgets(J jt,C*p){A y;B b;C*v;I j,k,m,n;UC*s; if(jt->nfe) v=nfeinput(jt,*p?"input_jfe_' '":"input_jfe_''"); else{ - ASSERT(jt->sminput,EVBREAK); + ASSERT(jt->sminput,EVBREAK); v=((inputtype)(jt->sminput))(jt,p); } R inpl(b,(I)strlen(v),v); @@ -131,7 +137,13 @@ F1(jtjoff){I x; x=i0(w); breakclose(jt); if(jt->sesm)jsto(jt, MTYOEXIT,(C*)x); - exit((int)x); + +#ifndef ANDROID + exit((int)x); +#else + #include "jni/j-jni-interface.h" + android_quit(); +#endif R 0; } @@ -176,7 +188,7 @@ DF1(jtwd){A z=0;C*p=0;D*pd;I e,*pi,t;V*sv; pd=DAV(w); GA(w,INT,AN(w),AR(w),0); pi=AV(w); - DO(AN(w),*pi++=(I)(jfloor(0.5+*pd++));); + DO(AN(w),*pi++=(I)(jfloor(0.5+*pd++));); break; default: ASSERT(0,EVDOMAIN); @@ -198,12 +210,12 @@ static char breaknone=0; B jtsesminit(J jt){jt->adbreak=&breakdata; R 1;} #endif -int _stdcall JDo(J jt, char* lp){int r; +int _stdcall JDo(J jt, C* lp){int r; r=(int)jdo(jt,lp); while(jt->nfe) r=(int)jdo(jt,nfeinput(jt,"input_jfe_' '")); R r; -} +} /* socket protocol CMDGET name */ A _stdcall JGetA(J jt, I n, C* name){A x; @@ -250,10 +262,10 @@ void jsto(J jt,I type,C*s){C e;I ex; e=jt->jerr; ex=jt->etxn; jt->jerr=0; jt->etxn=0; jt->breakignore=1;exec1(cstr(q));jt->breakignore=0; - jt->jerr=e; jt->etxn=ex; + jt->jerr=e; jt->etxn=ex; }else{ if(jt->smoutput) ((outputtype)(jt->smoutput))(jt,(int)type,s); -#if SY_WIN32 && !SY_WINCE +#if defined(OLECOM) && SY_WIN32 && !SY_WINCE if(type & MTYOFM) oleoutput(jt,strlen(s),s); /* save output for ole */ #endif }} @@ -265,7 +277,7 @@ J JInit(void){ /* jtglobinit must be done once when dll is first loaded Windows does it in dll load routine - thread safe Unix does it here once, but this is not thread safe */ - + static J g_jt=0; if(!g_jt) { @@ -371,7 +383,7 @@ static int setterm(J jt, C* name, I* jtype, I* jrank, I* jshape, I* jdata) // validate name if(strlen(name) >= sizeof(gn)) return EVILNAME; - if(valid(name, gn)) return EVILNAME; + if(valid(name, gn)) return EVILNAME; for(i=0; i<*jrank; ++i) k *= ((I*)(*jshape))[i]; a = ga(*jtype, k, *jrank, (I*)*jshape); if(!a) return EVWSFULL; diff --git a/j.h b/j.h index 57a0709..123622e 100644 --- a/j.h +++ b/j.h @@ -42,8 +42,7 @@ #endif #include -#include - +#include #if SY_64 #define IMAX 9223372036854775807L @@ -194,7 +193,7 @@ #define jfloor jfloor1 #else #define jfloor floor -#endif +#endif #define BB 8 /* # bits in a byte */ #if SY_64 @@ -224,7 +223,7 @@ #define FCONS(x) fdef(CFCONS,VERB,jtnum1,jtnum2,0L,0L,(x),0L,RMAX,RMAX,RMAX) #define FEQ(u,v) (ABS((u)-(v))<=jt->fuzz*MAX(ABS(u),ABS(v))) #define F1(f) A f(J jt, A w) -#define F2(f) A f(J jt,A a,A w) +#define F2(f) A f(J jt,A a,A w) #define F1RANK(m,f,self) {RZ( w); if(m +#define _isnan isnan +#define _SW_INVALID FE_INVALID +static inline unsigned int _clearfp(void){int r=fetestexcept(FE_ALL_EXCEPT); feclearexcept(FE_ALL_EXCEPT); return r; } +// #define _clearfp() (unsigned int)0 +#endif + +#elif defined(__mips__) && defined(ANDROID) +#include "mips/fenv.h" +#define _isnan isnan +#define _SW_INVALID FE_INVALID +static inline unsigned int _clearfp(void){int r=fetestexcept(FE_ALL_EXCEPT); feclearexcept(FE_ALL_EXCEPT); return r; } + +#else #include #define _isnan isnan #define _SW_INVALID FE_INVALID +static inline unsigned int _clearfp(void){int r=fetestexcept(FE_ALL_EXCEPT); feclearexcept(FE_ALL_EXCEPT); return r; } + +#endif +#endif + +#ifdef _MISALIGN_BYTEVECTOR +#define MISALIGN_BYTEVECTOR 1 +#else +#define MISALIGN_BYTEVECTOR 0 +#endif -static inline UINT _clearfp(void){int r=fetestexcept(FE_ALL_EXCEPT); - feclearexcept(FE_ALL_EXCEPT); return r; -} +#ifdef __MINGW32__ +#ifndef _SW_INVALID +#define _SW_INVALID 0x00000010 /* invalid */ #endif +#ifndef _EM_ZERODIVIDE +#define _EM_ZERODIVIDE 0x00000008 +#endif +#define EM_INVALID _SW_INVALID +#define EM_ZERODIVIDE _EM_ZERODIVIDE +#if defined(__STRICT_ANSI__) +extern int __cdecl _isnan (double); +extern unsigned int __cdecl _clearfp (void); +#endif +#if defined(__STRICT_ANSI__) && !defined(__MINGW64__) +#ifndef _fileno +#define _fileno(__F) ((__F)->_file) +#endif +#ifndef _MAX_PATH +#define _MAX_PATH (260) +#endif +#endif +#endif + diff --git a/j/addons/data/jmf/jmf.ijs b/j/addons/data/jmf/jmf.ijs index 03fcdb6..85ff94a 100644 --- a/j/addons/data/jmf/jmf.ijs +++ b/j/addons/data/jmf/jmf.ijs @@ -55,7 +55,7 @@ NULLPTR=: <0 3 : 0'' if. IFUNIX do. - lib=. > (IFDEF'android') { 'libc.so.6 ';'libc.so ' + lib=. > (UNAME-:'Android') { 'libc.so.6 ';'libc.so ' lib=. >(UNAME-:'Darwin'){lib;'libc.dylib ' api=. 1 : ('(''',lib,''',x) & cd') c_isatty=: ' isatty i i' api @@ -89,10 +89,10 @@ else. PAGE_READONLY=: 2 PAGE_READWRITE=: 4 TRUNCATE_EXISTING=: 5 - + j=. (GENERIC_READ+GENERIC_WRITE),PAGE_READWRITE,FILE_MAP_WRITE RW=: j,:GENERIC_READ,PAGE_READONLY,FILE_MAP_READ - + CloseHandleR=: 'kernel32 CloseHandle > i x'&(15!:0) CreateFileMappingR=: 'kernel32 CreateFileMappingW > x x * i i i *w'&(15!:0) CreateFileR=: 'kernel32 CreateFileW > x *w i i * i i x'&(15!:0) diff --git a/j/system/config/base.cfg b/j/system/config/base.cfg index aa9e89a..75c9ae9 100644 --- a/j/system/config/base.cfg +++ b/j/system/config/base.cfg @@ -62,25 +62,23 @@ case. 'Darwin' do. Editor=: '' Editor_nox=: '' case. 'Linux' do. - if. IFDEF'android' do. - BoxForm=: 0 - Browser=: '' - Browser_nox=: '' - EPSReader=: '' - PDFReader=: '' - XDiff=: '' - Editor=: '' - Editor_nox=: '' - else. - BoxForm=: 0 - Browser=: '' - Browser_nox=: '/usr/bin/w3m' - EPSReader=: '/usr/bin/evince' - PDFReader=: '/usr/bin/evince' - XDiff=: '/usr/bin/meld' - Editor=: 'geany +%l %f' - Editor_nox=: 'vi -c%l %f' - end. + BoxForm=: 0 + Browser=: '' + Browser_nox=: '/usr/bin/w3m' + EPSReader=: '/usr/bin/evince' + PDFReader=: '/usr/bin/evince' + XDiff=: '/usr/bin/meld' + Editor=: 'geany +%l %f' + Editor_nox=: 'vi -c%l %f' +case. 'Android' do. + BoxForm=: 0 + Browser=: '' + Browser_nox=: '' + EPSReader=: '' + PDFReader=: '' + XDiff=: '' + Editor=: '' + Editor_nox=: '' case. 'Win' do. BoxForm=: 1 Browser=: '' diff --git a/j/system/main/socket.ijs b/j/system/main/socket.ijs index 81400ce..83cf180 100644 --- a/j/system/main/socket.ijs +++ b/j/system/main/socket.ijs @@ -23,7 +23,16 @@ case. 'Win' do. closesocketJ=: 'closesocket i i' scdm ioctlsocketJ=: 'ioctlsocket i i i *i' scdm case. 'Linux' do. - c=. > (IFDEF'android') {'libc.so.6';'libc.so' + c=. 'libc.so.6' + ccdm=: 1 : ('(''"',c,'" '',x)&(15!:0)') + ncdm=: ccdm + scdm=: ccdm + wcdm=: 1 : ']' + LIB=: c + closesocketJ=: 'close i i' scdm + ioctlsocketJ=: 'ioctl i i i *i' scdm +case. 'Android' do. + c=. 'libc.so' ccdm=: 1 : ('(''"',c,'" '',x)&(15!:0)') ncdm=: ccdm scdm=: ccdm diff --git a/j/system/main/stdlib.ijs b/j/system/main/stdlib.ijs index 08d748b..df12595 100644 --- a/j/system/main/stdlib.ijs +++ b/j/system/main/stdlib.ijs @@ -9,12 +9,37 @@ hostpathsep=: ('/\'{~6=9!:12'')&(I. @ (e.&'/\')@] }) jpathsep=: '/'&(('\' I.@:= ])}) winpathsep=: '\'&(('/' I.@:= ])}) PATHJSEP_j_=: '/' +IFDEF=: 3 : '0=4!:0<''DEF'',y,''_z_''' + IF64=: 16={:$3!:3[2 'IFUNIX IFWIN IFWINCE'=: 5 6 7 = 9!:12'' IFGTK=: IFJHS=: IFBROADWAY=: 0 IFJ6=: 0 IFWINE=: IFWIN > 0-:2!:5'_' -if. IF64 +. IFDEF'android' do. + +if. notdef 'IFIOS' do. + IFIOS=: 0 +end. + +if. notdef 'UNAME' do. + if. IFUNIX do. + UNAME=: (2!:0 'uname')-.10{a. + elseif. do. + UNAME=: 'Win' + end. +end. + +if. notdef 'IFARM' do. + if. IFIOS do. + IFARM=: 1 + elseif. IFUNIX do. + IFARM=: 'arm' -: 3{.(2!:0 'uname -m')-.10{a. + elseif. do. + IFARM=: 0 + end. +end. + +if. IF64 +. IFIOS +. ( (IFDEF'android') { UNAME;'Android' -0!:0 (IFDEF'android'){'libc.so.6';'libc.so' + llib=. 'libc.so.6' + isatty=: (llib , ' isatty > i i') & (15!:0) +elseif. 'Android'-:UNAME do. + llib=. 'libc.so' isatty=: (llib , ' isatty > i i') & (15!:0) elseif. 'Darwin'-:UNAME do. isatty=: 'libc.dylib isatty > i i' & (15!:0) @@ -180,8 +200,8 @@ type=: {&t@(2&+)@(4!:0)&boxopen ucp=: 7&u: ucpcount=: # @ (7&u:) 3 : 0'' -llib=.>(IFDEF'android'){'libc.so.6';'libc.so' -if. 'Linux'-:UNAME do. usleep=: 3 : '(llib,'' usleep > i i'')&(15!:0) >.y' +if. 'Linux'-:UNAME do. usleep=: 3 : '''libc.so.6 usleep > i i''&(15!:0) >.y' +elseif. 'Android'-:UNAME do. usleep=: 3 : '''libc.so usleep > i i''&(15!:0) >.y' elseif. 'Darwin'-:UNAME do. usleep=: 3 : '''libc.dylib usleep > i i''&(15!:0) >.y' elseif. do. usleep=: 3 : '0: ''kernel32 Sleep > n i''&(15!:0) >.y % 1000' end. @@ -346,7 +366,7 @@ cocurrent 'z' if. -. (UNAME-:'Darwin')+.(UNAME-:'SunOS') do. DLL_PATH=: '' return. end. llp=. 2!:5 'LD_LIBRARY_PATH',~'DY'#~UNAME-:'Darwin' if. 0 -: llp do. llp=. '' end. -def_path=. >(IFDEF'android') { ':/usr/local/lib:/usr/lib:/usr/lib/ccs/lib:/etc/lib:/lib':'/system/lib' +def_path=. >(UNAME-:'Android') { ':/usr/local/lib:/usr/lib:/usr/lib/ccs/lib:/etc/lib:/lib':'/system/lib' DLL_PATH=: a: -.~ <;._1 ':',llp,def_path ) find_dll=: 3 : 0 @@ -734,7 +754,7 @@ if. +/ # &> c do. if. {.opt do. r=. r,LF,;(,&(LF2)) &.> cd end. - + end. if. 0=#;res do. r=. r,'no difference',LF end. @@ -782,14 +802,14 @@ dy=. (fy e. fx)#dy if. #j=. dx -. dy do. j=. {."1 j cmp=. <@fcompare"1 (sx&,&.>j),.sy&,&.>j - + if. 0=2{opt do. f=. 'no difference'&-: @ (_13&{.) msk=. -. f &> cmp j=. msk#j cmp=. msk#cmp end. - + r=. r,< j; old newlen=. # &> new if. *./ 1 = oldlen do. - + hit=. (;old) i. txt ndx=. I. hit < #old - + if. 0 e. $ndx do. txt return. end. - + cnt=. 1 exp=. hit { newlen,1 hnx=. ndx { hit bgn=. ndx + +/\ 0, (}: hnx) { newlen - 1 - + else. - + hit=. old I. @ E. each hit - + if. 0 = +/ cnt do. txt return. end. - + bgn=. set=. '' - + pick=. > @ { diff=. }. - }: - + for_i. I. 0 < cnt do. ln=. i pick oldlen cx=. (i pick hit) -. set, ,bgn -/ i.ln @@ -1289,26 +1309,26 @@ else. bgn=. bgn, cx set=. set, ,cx +/ i.ln end. - + cnt=. # &> hit msk=. 0 < cnt exp=. (#txt) $ 1 del=. newlen - oldlen - + if. #add=. I. msk *. del > 0 do. exp=. (>: (add{cnt) # add{del) (;add{hit) } exp end. - + if. #sub=. I. msk *. del < 0 do. sbx=. ; (;sub{hit) + each (sub{cnt) # i. each sub{del exp=. 0 sbx } exp end. - + hit=. ; hit ind=. /: (#hit) $ 1 2 3 hnx=. (/: ind { hit) { ind bgn=. (hnx { hit) + +/\ 0, }: hnx { cnt # del - + end. ind=. ; bgn + each hnx { cnt # i.each newlen diff --git a/jconsole.c b/jconsole.c index 854457b..771b0d0 100644 --- a/jconsole.c +++ b/jconsole.c @@ -4,8 +4,9 @@ /* #define READLINE for Unix readline support */ #ifdef _WIN32 #include -#include +#include #else +#include #define _isatty isatty #define _fileno fileno #endif @@ -20,11 +21,20 @@ static char input[30000]; /* J calls for keyboard input (debug suspension and 1!:1[1) */ /* we call to get next input */ #ifdef READLINE +#ifndef ANDROID /* readlin.h */ int add_history(const char *); int read_history(const char *); int write_history(const char *); char* readline(const char *); +#else +#include "linenoise.h" +#define add_history linenoiseHistoryAdd +#define read_history linenoiseHistoryLoad +#define write_history linenoiseHistorySave +#define readline linenoise +#define using_history() +#endif int hist=1; char histfile[256]; @@ -51,7 +61,7 @@ if(hist) if(line) free(line); /* free last input */ line = readline(prompt); if(!line) return "2!:55''"; /* ^d eof */ - if(*line) add_history(line); + if(*line) add_history(line); return line; } #endif @@ -76,17 +86,17 @@ char* Jinput_stdio(char* prompt) return input; } -char* _stdcall Jinput(J jt,char* prompt){ +C* _stdcall Jinput(J jt,C* prompt){ #ifdef READLINE if(isatty(0)){ return Jinput_rl(prompt); - } else + } else #endif return Jinput_stdio(prompt); } /* J calls for output */ -void _stdcall Joutput(J jt,int type, char* s) +void _stdcall Joutput(J jt,int type, C* s) { if(MTYOEXIT==type) { @@ -117,7 +127,7 @@ void addargv(int argc, char* argv[], C* d) if('\''==*(p-1))*p++='\''; } *p++='\''; - } + } *p=0; } @@ -126,13 +136,19 @@ J jt; int main(int argc, char* argv[]) { void* callbacks[] = {Joutput,0,Jinput,0,(void*)SMCON}; int type; - +#if !defined(WIN32) && !(defined(__arm__)||defined(__mips__)) +// set stack size to get limit error instead of crash + struct rlimit lim; + getrlimit(RLIMIT_STACK,&lim); + lim.rlim_cur=0x1000000; // 0xc000000 12mb works, but let's be safe with 16mb + setrlimit(RLIMIT_STACK,&lim); +#endif jepath(argv[0]); // get path to JFE folder jt=jeload(callbacks); if(!jt){char m[1000]; jefail(m), fputs(m,stdout); exit(1);} adadbreak=(char**)jt; // first address in jt is address of breakdata signal(SIGINT,sigint); - + #ifdef READLINE char* rl_readline_name="jconsole"; /* argv[0] varies too much*/ #endif diff --git a/jdlllic.c b/jdlllic.c index 5e3549b..d857e8a 100644 --- a/jdlllic.c +++ b/jdlllic.c @@ -1,11 +1,7 @@ /* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ /* encode/decode routines - license keys and ijl */ -#if defined _WIN32 && !OPENJ -#include "..\jsrc\j.h" -#else #include "j.h" -#endif F1(jtlock1){ASSERT(0,EVDOMAIN);} /* no encode */ diff --git a/jeload.c b/jeload.c index f11c227..5551732 100644 --- a/jeload.c +++ b/jeload.c @@ -24,12 +24,18 @@ #define filesep '/' #define filesepx "/" #define ijx "11!:0'pc ijx closeok;xywh 0 0 300 200;cc e editijx rightmove bottommove ws_vscroll ws_hscroll;setfont e monospaced 12;pas 0 0;pgroup jijx;pshow;'[18!:4<'base'" - #ifdef __MACH__ + #ifdef __MACH__ #define JDLLNAME "libj.dylib" #else #define JDLLNAME "libj.so" #endif #endif + +#ifdef ANDROID +#include +#include +#endif + #include "j.h" static void* hjdll; @@ -39,6 +45,7 @@ static JFreeType jfree; static JgaType jga; static JGetLocaleType jgetlocale; static char path[PLEN]; +static char pathroot[PLEN]; static char pathdll[PLEN]; int jedo(char* sentence) @@ -91,7 +98,7 @@ void jepath(char* arg) // fprintf(stderr,"arg0 %s\n",arg); // try host dependent way to get path to executable // use arg if they fail (arg command in PATH won't work) -#ifdef __MACH__ +#ifdef __MACH__ n=_NSGetExecutablePath(arg2,&len); if(0!=n) strcat(arg2,arg); #else @@ -136,6 +143,8 @@ void jepath(char* arg) strcat(pathdll,filesepx); strcat(pathdll,JDLLNAME); // fprintf(stderr,"arg4 %s\n",path); + strcpy(pathroot,path); + *(strrchr(pathroot,filesep)) = 0; } // called by jwdp (java jnative.c) to set path @@ -183,7 +192,35 @@ int jefirst(int type,char* arg) *q++=*p++; } *q=0; - strcat(input,"'"); +#if ANDROID +struct stat st; + strcat(input,"'[UNAME_z_=:'Android"); + if(!getenv("HOME")) { + if(!stat("/sdcard",&st)) { + setenv("HOME","/sdcard",1); + } else { + setenv("HOME",pathroot,1); + } + } + if(!getenv("TMP")) { + char tmp[PLEN]; + strcpy(tmp, pathroot); + strcat(tmp, filesepx); + strcat(tmp, "tmp"); + if(stat(tmp,&st)) mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO); + setenv("TMP",tmp,1); + } +#endif +#if defined(__arm__) + strcat(input,"'[IFARM_z_=:1"); +#else + strcat(input,"'[IFARM_z_=:0"); +#endif +#if defined(__mips__) + strcat(input,"[IFMIPS_z_=:1"); +#else + strcat(input,"[IFMIPS_z_=:0"); +#endif r=jedo(input); free(input); return r; diff --git a/jld/Android.mk b/jld/Android.mk new file mode 100644 index 0000000..7c2f87d --- /dev/null +++ b/jld/Android.mk @@ -0,0 +1,27 @@ + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jld + +LOCAL_LDLIBS := -llog -ldl -lc + +LOCAL_CFLAGS := -O0 -fno-omit-frame-pointer -fno-strict-aliasing -fno-unwind-tables -fno-tree-vectorize -D_MISALIGN_BYTEVECTOR -DNOASM -fPIC + + +LOCAL_SRC_FILES := jld.c + + +ifneq ($(TARGET_ARCH_ABI),x86) +LOCAL_STATIC_LIBRARIES := cpufeatures +endif + +include $(BUILD_SHARED_LIBRARY) + +ifneq ($(TARGET_ARCH_ABI),x86) +$(call import-module,android/cpufeatures) +endif + + + diff --git a/jld/jld.c b/jld/jld.c new file mode 100644 index 0000000..02af8b9 --- /dev/null +++ b/jld/jld.c @@ -0,0 +1,51 @@ +/** + * This is a loader for libj on android + * It attempts to determine whether or not + * the device is equipped with a hardware + * FPU, and then loader the version which + * has been compiled explicitly for the current + * platform + * - mdykman + */ + +#include +#include +#include + +#ifdef __ARM_ARCH_5__ + #include +#endif + + +int fpuEmu(); + +jint JNI_On_Load(JavaVM*env, void* reserved) { + // TODO: can I capture stderr here?? + + // I don't need my full path, I don't think + char*lib = fpuEmu() ? "./libj-emu.so" : "./libj-fpu.so"; + void*r=dlopen(lib,RTLD_LAZY); + if(r==NULL) { + fprintf(stderr,"error in library loader %s: %s\n",lib,dlerror()); + return 1; + + } else { + fprintf(stderr,"successfully loaded: %s\n",lib); + /* + // this probably is neither neccessary nor advisable + int(*onload)(JavaVM*jvm,void*res) = dlsym(r,"JNI_On_Load"); + return onload(env,reserved); + */ + } + return 0; +} + +#ifdef __ARM_ARCH_5__ +int __fpuEmu() { + uint64_t flags = android_getCpuFeatures(); +} +#endif +// return 1 if using fpu-emu, otherwise 0 +int fpuEmu() { + return system("grep \'\\\' /proc/cpuinfo"); +} diff --git a/jlib.h b/jlib.h index 3e20259..efe4905 100644 --- a/jlib.h +++ b/jlib.h @@ -1,8 +1,18 @@ /* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ +#ifdef _WIN32 +#ifdef __MINGW32__ +#ifndef _stdcall +#define _stdcall __stdcall +#endif +#endif +#else +#define _stdcall +#endif + J _stdcall JInit(); /* init instance */ -void _stdcall JSM(J jt, void*callbacks[]); /* set callbacks */ +void _stdcall JSM(J jt, void*callbacks[]); /* set callbacks */ int _stdcall JDo(J jt,C*); /* run sentence */ C* _stdcall JGetLocale(J jt); /* get locale */ int _stdcall JFree(J jt); /* free instance */ @@ -11,7 +21,7 @@ I _stdcall JSetA(J jt,I n,C* name,I x,C* d);/* name=:3!:2 data */ typedef void* (_stdcall *JInitType) (); typedef int (_stdcall *JDoType) (void*, C*); -typedef C* (_stdcall *JGetLocaleType)(void*); +typedef C* (_stdcall *JGetLocaleType)(void*); typedef void (_stdcall *JSMType) (void*, void*); typedef void (_stdcall *JFreeType) (void*); typedef A (_stdcall *JgaType) (J jt, I t, I n, I r, I*s); diff --git a/jni/j-jni-interface.c b/jni/j-jni-interface.c index 62704fa..5df27c7 100644 --- a/jni/j-jni-interface.c +++ b/jni/j-jni-interface.c @@ -1,157 +1,572 @@ -#include "j.h" -#include "org_dykman_j_android_JInterface.h" -#include "j-jni-interface.h" -#include - - -/** -This is designed to explicitly to be used with the class file org.dykman.dykman.j.JInterface whic is part of a larger Android project hosted at - https://github.com/mdykman/jconsole_for_android -It consists of the implementations of the native function declared in the class as well as a method for sending output ansynchronously to the Java layer. -While wrriten a part of an Android project, JInterface is generic enough to be used in any Java context that whishes to interact with J and capture it's output. -A subclass of JInterface, org.dykman.j.android.AndroidJInterface include additional android-specific methods which can be invoke from J, via 15!:0 - */ - -#define LOCALOGTAG "j-interface" -#ifdef ANDROID -#include -#define LOGD(msg) __android_log_write(ANDROID_LOG_DEBUG,LOCALOGTAG,msg) -#define LOGFD(...) __android_log_print(ANDROID_LOG_DEBUG,LOCALOGTAG,__VA_ARGS__) -#else -#include -#define LOGD(msg) printf("%s: %s\n",LOCALOGTAG,msg) - -// TODO.. this is not right... -#define LOGFD(...) printf("%s: %s\n",LOCALOGTAG,__VA_ARGS__) -#endif - -JNIEnv *local_jnienv; -jclass local_class; -jobject local_baseobj; - -jmethodID outputId = 0; - -void consoleAppend(JNIEnv *env, jobject obj,int type, const char*chars) { - if(outputId == 0) { -// jclass cls = (*env)->GetObjectClass(env,obj); - outputId = (*env)->GetMethodID(env,local_class,"output","(ILjava/lang/String;)V" ); - } - if(outputId == 0) { - LOGD("failed to get the method id for " "output:" "(ILjava/lang/String;)V"); - } else { - jstring str = (*env)->NewStringUTF(env,chars); - (*env)->CallVoidMethod(env,obj,outputId,(jint)type,str); - } -} - -JNIEXPORT jint JNICALL Java_org_dykman_j_JInterface_callJNative - (JNIEnv * env, jobject obj, jlong inst, jstring js) { - J jengine = (J)inst; - local_jnienv = env; - local_baseobj = obj; - local_class = (*env)->GetObjectClass(env,obj); - const char *nativeString = (*env)->GetStringUTFChars(env, js, 0); - int jc = JDo(jengine,(C*)nativeString); - return (jint) jc; -} - -JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_destroyJNative - (JNIEnv *env, jobject obj, jlong inst) { - LOGD("free called"); - JFree((J)inst); - outputId = 0; -} - -JNIEXPORT jobject JNICALL Java_org_dykman_j_JInterface_getVariableNative - (JNIEnv *env, jobject obj, jlong inst, jstring jname) { - J jengine = (J)inst; - const char *name = (*env)->GetStringUTFChars(env, jname, 0); - long type, rank; - long *shape; - char *data; - - JGetM(jengine,(I*)&type,(I*)&rank,(I*)&shape,(I*)&data); -LOGFD("name=%s,type=%l,rank=%l,shapehead=%l,data=%p",name,type,rank,*shape,data); - return NULL; - } - - -void _stdcall outputHandler(J jt,int type, const char* s) { - consoleAppend(local_jnienv,local_baseobj,type,s); -} - -JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_setEnv - (JNIEnv *env, jobject obj, jstring jkey, jstring jval) { - char*key = (*env)->GetStringUTFChars(env, jkey, 0); - char*val = (*env)->GetStringUTFChars(env, jval, 0); - setenv(key,val,0); - free(key); - free(val); -} - - - -#ifdef ANDROID -const char* android_next_ptr = NULL; -const char* __nextLineFromAndroid( - JNIEnv *env, - jobject obj) { - local_class = (*env)->GetObjectClass(env,obj); - jmethodID nextLineId = (*env)->GetMethodID(env,local_class,"nextLine","()Ljava/lang/String;" ); - jstring res = (jstring) (*env)->CallObjectMethod(env,obj,nextLineId); - if(android_next_ptr != NULL) { - free((char*)android_next_ptr); - } - android_next_ptr = (*env)->GetStringUTFChars(env, res, 0); - return android_next_ptr; -} - -const char * _stdcall android_next_line() { - return __nextLineFromAndroid(local_jnienv,local_baseobj); -} - -int __downloadViaAndroid( - JNIEnv *env, - jobject obj, - const char* furl, - const char* ff) { -// jclass cls = (*env)->GetObjectClass(env,obj); - local_class = (*env)->GetObjectClass(env,obj); - jmethodID downloadId = (*env)->GetMethodID(env,local_class,"downloadFile","(Ljava/lang/String;Ljava/lang/String;)I" ); - jstring jurl = (*env)->NewStringUTF(env,furl); - jstring jfile = (*env)->NewStringUTF(env,ff); - jint res = (*env)->CallIntMethod(env,obj,downloadId,jurl,jfile); - return (int)res; -} - - -int _stdcall android_download_file(const char* furl, const char* ff) { - return __downloadViaAndroid(local_jnienv, local_baseobj,furl,ff); -} - -#endif - -/* - * Class: org_dykman_j_android_JActivity - * Method: initializeJNative - * Signature: ()V - */ - -JNIEXPORT jlong JNICALL Java_org_dykman_j_JInterface_initializeJNative - (JNIEnv * env, jobject obj) { - LOGD("init called"); - local_jnienv = env; - local_baseobj = obj; - local_class = (*env)->GetObjectClass(env,obj); - - outputId = 0; - J j = JInit(); -#ifdef ANDROID - void* callbacks[] = {outputHandler,0,android_next_line,0,(void*)SMJAVA}; -#else - void* callbacks[] = {outputHandler,0,0,0,(void*)SMJAVA}; -#endif - JSM(j,callbacks); - return (jlong) j; -} - +#include "j.h" +#include "org_dykman_j_android_JInterface.h" +#include "j-jni-interface.h" +#include + +/** +This is designed to explicitly to be used with the class file org.dykman.dykman.j.JInterface whic is part of a larger Android project hosted at + https://github.com/mdykman/jconsole_for_android +It consists of the implementations of the native function declared in the class as well as a method for sending output ansynchronously to the Java layer. +While written a part of an Android project, JInterface is generic enough to be used in any Java context that whishes to interact with J and capture it's output. +A subclass of JInterface, org.dykman.j.android.AndroidJInterface include additional android-specific methods which can be invoke from J, via 15!:0 + +Under this implementation, we rely on the jobject which calls these methods from java being a singleton. + */ + +// #define JNIGNULL (*env)->NewGlobalRef(env, NULL) +#define JNIGNULL (void*)0 + +/* +char android_temp_dir[240]; + */ +static JavaVM *jvm; +static JNIEnv *local_jnienv; +static jobject local_baseobj; + +jmethodID outputId = 0; + +int _stdcall GetJavaVM(JavaVM ** pvm, JNIEnv ** penv){ + *pvm = jvm; + *penv = local_jnienv; + return 0; +} + +void consoleAppend(JNIEnv *env, jobject obj,int type, const char*chars) { + if(outputId == 0) { + jclass the_class = (*env)->GetObjectClass(env,obj); + outputId = (*env)->GetMethodID(env,the_class,"output","(ILjava/lang/String;)V" ); + } + if(outputId == 0) { + LOGD("failed to get the method id for " "output:" "(ILjava/lang/String;)V"); + } else { + jstring str = (*env)->NewStringUTF(env,chars); + (*env)->CallVoidMethod(env,obj,outputId,(jint)type,str); + } +} + +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + LOGD("jni-onload called"); + jvm = vm; + if ((*vm)->GetEnv(vm, (void **)&local_jnienv, JNI_VERSION_1_6) != JNI_OK) { + LOGD("failed jni check"); + return -1; + } + + // Get jclass with env->FindClass. + // Register methods with env->RegisterNatives. + + LOGD("returning from jni-onload"); + return JNI_VERSION_1_6; +} + +JNIEXPORT jint JNICALL Java_org_dykman_j_JInterface_callJNative + (JNIEnv * env, jobject obj, jlong inst, jstring js) { + LOGD("called callJNative "); + J jengine = (J)inst; + + LOGD(":::: callJNative format string"); + const char *nativeString = (*env)->GetStringUTFChars(env, js, 0); + LOGD(":::: callJNative jdo"); + int jc = JDo(jengine,(C*)nativeString); + LOGD(":::: callJNative returning"); + return (jint) jc; +} + +JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_destroyJNative + (JNIEnv *env, jobject obj, jlong inst) { + LOGD("free called"); + JFree((J)inst); + outputId = 0; +} + +JNIEXPORT jobject JNICALL Java_org_dykman_j_JInterface_getVariableNative + (JNIEnv *env, jobject obj, jlong inst, jstring jname) { + J jengine = (J)inst; + const char *name = (*env)->GetStringUTFChars(env, jname, 0); + long type, rank; + long *shape; + char *data; + + JGetM(jengine,(I*)&type,(I*)&rank,(I*)&shape,(I*)&data); +LOGFD("name=%s,type=%l,rank=%l,shapehead=%l,data=%p",name,type,rank,*shape,data); + return NULL; + } + + +void _stdcall outputHandler(J jt,int type, const char* s) { + consoleAppend(local_jnienv,local_baseobj,type,s); +} + +JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_setEnv + (JNIEnv *env, jobject obj, jstring jkey, jstring jval) { + char*key = (*env)->GetStringUTFChars(env, jkey, 0); + char*val = (*env)->GetStringUTFChars(env, jval, 0); + /* + if(strcmp(key,"TMP")==0) { + strcpy(android_temp_dir,val); + } + */ + setenv(key,val,0); + free(key); + free(val); +} + + + +int __unzipViaJava( + JNIEnv *env, + jobject obj, + const char* file, + const char* dir) { + jclass the_class = (*env)->GetObjectClass(env,obj); + jmethodID unzipId = (*env)->GetMethodID(env,the_class,"unzipS","(Ljava/lang/String;Ljava/lang/String;)I" ); + jstring jfile = (*env)->NewStringUTF(env,file); + jstring jdir = dir == NULL ? NULL : (*env)->NewStringUTF(env,dir); + jint res = (*env)->CallIntMethod(env,obj,unzipId,jfile,jdir); + return (int)res; +} + + +int _stdcall java_unzip_file(const char* file, const char* todir) { +/* make the empty string equate to null to accomodate J (he guessed) */ + const char* _todir = todir == NULL || strlen(todir) == 0 ? NULL : todir; + return __unzipViaJava(local_jnienv, local_baseobj,file,_todir); +} + + +#ifdef ANDROID +const char* android_next_ptr = NULL; +const char* __nextLineFromAndroid( + JNIEnv *env, + jobject obj) { + jclass the_class = (*env)->GetObjectClass(env,obj); + jmethodID nextLineId = (*env)->GetMethodID(env,the_class,"nextLine","()Ljava/lang/String;" ); + /* this method blocks via sleep until a line is available */ + jstring res = (jstring) (*env)->CallObjectMethod(env,obj,nextLineId); + if(android_next_ptr != NULL) { + free((char*)android_next_ptr); + } + android_next_ptr = (*env)->GetStringUTFChars(env, res, 0); + return android_next_ptr; +} + +const char * _stdcall android_next_line() { + return __nextLineFromAndroid(local_jnienv,local_baseobj); +} +int __downloadViaAndroid( + JNIEnv *env, + jobject obj, + const char* furl, + const char* ff) { + jclass the_class = (*env)->GetObjectClass(env,obj); + jmethodID downloadId = (*env)->GetMethodID(env,the_class,"downloadFile","(Ljava/lang/String;Ljava/lang/String;)I" ); + jstring jurl = (*env)->NewStringUTF(env,furl); + jstring jfile = (*env)->NewStringUTF(env,ff); + jint res = (*env)->CallIntMethod(env,obj,downloadId,jurl,jfile); + return (int)res; +} + +int _stdcall android_download_file(const char* furl, const char* ff) { + return __downloadViaAndroid(local_jnienv, local_baseobj,furl,ff); +} + +void __quitViaAndroid( + JNIEnv *env, + jobject obj) { + jclass the_class = (*env)->GetObjectClass(env,obj); + jmethodID quitId = (*env)->GetMethodID(env,the_class,"quit","()V" ); + (*env)->CallVoidMethod(env,obj,quitId); +} + + +int _stdcall android_get_abi() { + return android_abi; +} + +void _stdcall android_quit() { + __quitViaAndroid(local_jnienv,local_baseobj); +} + +/* +const char * __hostExecAndroid( + JNIEnv* env, + jobject obj, + const char* cmd) { + jclass the_class = (*env)->GetObjectClass(env,obj); + + + jmethodID execId = (*env)->GetMethodID(env,the_class,"execHostCommand","(Ljava/lang/String;)Ljava/lang/String;"); + jstring jcmd = (*env)->NewStringUTF(env,cmd); + jstring jres = (jstring) (*env)->CallObjectMethod(env,obj,execId,jcmd); + const char *res = (*env)->GetStringUTFChars(env, jres, 0); + return res; +} + +char* _stdcall android_exec_host(const char *cmd) { + return __hostExecAndroid(local_jnienv,local_baseobj,cmd); +} + */ + +void _stdcall android_free(void *ptr) { + free(ptr); +} + +int __launchActivityAndroid( + JNIEnv* env, + jobject obj, + const char* action, + const char* data, + const char* type, + int flags + ) { + jclass the_class = (*env)->GetObjectClass(env,obj); + jmethodID methodId = (*env)->GetMethodID(env,the_class,"launchActivity","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I"); + jstring jaction = (*env)->NewStringUTF(env,action); + jstring jdata = (*env)->NewStringUTF(env,data); + jstring jtype = (*env)->NewStringUTF(env,type); + jint jres = (*env)->CallIntMethod(env,obj,methodId,jaction,jdata,jtype,(jint)flags); + return (int) jres; +} +int _stdcall android_launch_app(const char* action, const char* data, const char* type,int flags) { + return __launchActivityAndroid(local_jnienv,local_baseobj,action,data,type,flags); +} +#endif + +/* + * Class: org_dykman_j_android_JActivity + * Method: initializeJNative + * Signature: ()V + */ + +JNIEXPORT jlong JNICALL Java_org_dykman_j_JInterface_initializeJNative + (JNIEnv * env, jobject obj) { + LOGD("init called"); +// local_jnienv = env; + local_baseobj = (*env)->NewGlobalRef(env,obj); + + (*env)->ExceptionClear(env); + outputId = 0; + J j = JInit(); +#ifdef ANDROID + void* callbacks[] = {outputHandler,0,android_next_line,0,(void*)SMJAVA}; +#else + void* callbacks[] = {outputHandler,0,0,0,(void*)SMJAVA}; +#endif + JSM(j,callbacks); + return (jlong) j; +} + +/* + * jnido.... callback to j + */ + +static A jnidocall (JNIEnv * env, jobject obj, J jt, jobject appobj, jstring verb, jobjectArray objarr) { + const char *nativeverb = (*env)->GetStringUTFChars(env, verb, 0); + char str[200]; /* do not reduce to 100, crash will occur if verb is long. This had happened */ +#if SY_64 + sprintf(str, "\'%s\' (jnhandler ::0:) (%li),(%li),(%li),(%li)", nativeverb, (jlong)env, (jlong)obj, (jlong)appobj, (jlong)objarr); +#else + sprintf(str, "\'%s\' (jnhandler ::0:) (%i),(%i),(%i),(%i)", nativeverb, (jint)env, (jint)obj, (jint)appobj, (jint)objarr); +#endif + (*env)->ReleaseStringUTFChars(env, verb, nativeverb); + A ret = exec1(cstr(str)); + (*env)->ExceptionClear(env); + return ret; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnido + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_dykman_j_JInterface_jnido + (JNIEnv * env, jobject obj, jlong jt0, jobject appobj, jstring verb, jobjectArray objarr) { + J jt = (J)jt0; + PROLOG; + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jclass clz; + jmethodID mid; + jobject retobj; + I rc = 0;int rettype = 0; + if(!r||(1!=(AN(r))&&((BOX==AT(r))||(INT==AT(r))||(FL==AT(r))||(B01==AT(r))))) {tpop(_ttop); /* LOGD("jnido return null object"); */ return JNIGNULL;} + if(B01==AT(r)) {rettype = B01; + clz = (*env)->FindClass( env, "java/lang/Boolean" ); + mid = (*env)->GetMethodID( env, clz, "", "(Z)V" ); + retobj = (*env)->NewObject( env, clz, mid, (jboolean)*(unsigned char*)AV(r) ); + (*env)->DeleteLocalRef(env, clz); + // LOGD("jnido return boolean object"); + tpop(_ttop); return retobj; + } + if(INT==AT(r)) { rettype = INT; +#if SY_64 + clz = (*env)->FindClass( env, "java/lang/Long" ); + mid = (*env)->GetMethodID( env, clz, "", "(J)V" ); + retobj = (*env)->NewObject( env, clz, mid, (jlong)*(I*)AV(r) ); +#else + clz = (*env)->FindClass( env, "java/lang/Integer" ); + mid = (*env)->GetMethodID( env, clz, "", "(I)V" ); + retobj = (*env)->NewObject( env, clz, mid, (jint)*(I*)AV(r) ); +#endif + (*env)->DeleteLocalRef(env, clz); + // LOGD("jnido return integer object"); + tpop(_ttop); return retobj; + } + if(FL==AT(r)) {rettype = FL; + clz = (*env)->FindClass( env, "java/lang/Double" ); + mid = (*env)->GetMethodID( env, clz, "", "(D)V" ); + retobj = (*env)->NewObject( env, clz, mid, *(D*)AV(r) ); + (*env)->DeleteLocalRef(env, clz); + // LOGD("jnido return double object"); + tpop(_ttop); return retobj; + } + if(LIT==AT(r)) {rettype = LIT; + jstring str = (*env)->NewStringUTF(env,(C*)AV(r)); + // LOGD("jnido return string object"); + tpop(_ttop); return str; + } + if(C2T==AT(r)) {rettype = C2T; + retobj = (*env)->NewString( env, (jchar*)AV(r), AN(r) ); + // LOGD("jnido return string (from wchar) object"); + tpop(_ttop); return retobj; + } + if(BOX==AT(r)) { + A ra = (A)*AV(r); + if (B01==AT(ra)&&(1==AN(ra))) {rettype = BOX; + if(!(*(unsigned char*)AV(ra))) {tpop(_ttop); /* LOGD("jnido return null object"); */ return JNIGNULL;} + else {tpop(_ttop); return (jobject)*(unsigned char*)AV(ra);} + } else if(INT==AT(ra)&&(1==AN(ra))) {rettype = BOX; + if(!(*(I*)AV(ra))) {tpop(_ttop); /* LOGD("jnido return null object"); */ return JNIGNULL;} + else {tpop(_ttop); + // LOGD("jnido return jobject object"); + return (jobject)*(I*)AV(ra);} + } + } + tpop(_ttop); /* LOGD("jnido return null object"); */ return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoz + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[Z + */ +JNIEXPORT jbooleanArray JNICALL Java_org_dykman_j_JInterface_jnidoz + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jbooleanArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (B01==AT(r)) { + retobjarr = (*env)->NewBooleanArray( env, n ); + (*env)->SetBooleanArrayRegion( env, retobjarr, 0, n, (jboolean*)AV(r) ); + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidos + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[S + */ +JNIEXPORT jshortArray JNICALL Java_org_dykman_j_JInterface_jnidos + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jshortArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (INT==AT(r)) { + retobjarr = (*env)->NewShortArray( env, n ); + I* pr = (I*)AV(r); jshort tmp; + for (int i=0; iSetShortArrayRegion( env, retobjarr, i, 1, &tmp ); } + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoi + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[I + */ +JNIEXPORT jintArray JNICALL Java_org_dykman_j_JInterface_jnidoi + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jintArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (INT==AT(r)) { + retobjarr = (*env)->NewIntArray( env, n ); +#if SY_64 + jlong* pr = (I*)AV(r); jint tmp; + for (int i=0; iSetIntArrayRegion( env, retobjarr, i, 1, &tmp ); } +#else + (*env)->SetIntArrayRegion( env, retobjarr, 0, n, (jint*)AV(r) ); +#endif + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidol + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[J + */ +JNIEXPORT jlongArray JNICALL Java_org_dykman_j_JInterface_jnidol + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jlongArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (INT==AT(r)) { + retobjarr = (*env)->NewLongArray( env, n ); +#if SY_64 + (*env)->SetLongArrayRegion( env, retobjarr, 0, n, (jlong*)AV(r) ); +#else + jint* pr = (I*)AV(r); jlong tmp; + int i; + for (i=0; iSetLongArrayRegion( env, retobjarr, i, 1, &tmp ); } +#endif + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidof + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[F + */ +JNIEXPORT jfloatArray JNICALL Java_org_dykman_j_JInterface_jnidof + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jfloatArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (FL==AT(r)) { + retobjarr = (*env)->NewFloatArray( env, n ); + D* pr = (D*)AV(r); jfloat tmp; + for (int i=0; iSetFloatArrayRegion( env, retobjarr, i, 1, &tmp ); } + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidod + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[D + */ +JNIEXPORT jdoubleArray JNICALL Java_org_dykman_j_JInterface_jnidod + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jdoubleArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (FL==AT(r)) { + retobjarr = (*env)->NewDoubleArray( env, n ); + (*env)->SetDoubleArrayRegion( env, retobjarr, 0, n, (jdouble*)AV(r) ); + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoc + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_dykman_j_JInterface_jnidoc + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jbyteArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (LIT==AT(r)) { + retobjarr = (*env)->NewByteArray( env, n ); + (*env)->SetByteArrayRegion( env, retobjarr, 0, n, (jbyte*)AV(r) ); + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidow + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[C + */ +JNIEXPORT jcharArray JNICALL Java_org_dykman_j_JInterface_jnidow + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jcharArray retobjarr; + I n = AN(r); + if(!r) {return JNIGNULL;} + else if (C2T==AT(r)) { + retobjarr = (*env)->NewCharArray( env, n ); + (*env)->SetCharArrayRegion( env, retobjarr, 0, n, (jchar*)AV(r) ); + return retobjarr; + } else return JNIGNULL; +} + +/* + * Class: org_dykman_j_JInterface + * Method: jnidox + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[Ljava/lang/Object; + */ +JNIEXPORT jobjectArray JNICALL Java_org_dykman_j_JInterface_jnidox + (JNIEnv * env, jobject obj, jlong jt, jobject appobj, jstring verb, jobjectArray objarr) { + A r = jnidocall (env, obj, (J)jt, appobj, verb, objarr); + + jobjectArray retobjarr; + I n = AN(r); + if (B01==AT(r)) { + C* rab = (C*)AV(r); + jclass clzobject = (*env)->FindClass( env, "java/lang/Object" ); + retobjarr = (*env)->NewObjectArray( env, n, clzobject, 0 ); + int i; + for (i=0;iSetObjectArrayElement( env, retobjarr, i, JNIGNULL ); + else (*env)->SetObjectArrayElement( env, retobjarr, i, (jobject)*(unsigned char*)(i+rab) ); + } + return retobjarr; + } else if (INT==AT(r)) { + I* rai = (I*)AV(r); + jclass clzobject = (*env)->FindClass( env, "java/lang/Object" ); + retobjarr = (*env)->NewObjectArray( env, n, clzobject, 0 ); + int i; + for (i=0;iSetObjectArrayElement( env, retobjarr, i, JNIGNULL ); + else (*env)->SetObjectArrayElement( env, retobjarr, i, (jobject)*(I*)(i+rai) ); + } + return retobjarr; + } else if (BOX==AT(r)) { + A ra; + A* rap = (A*)AV(r); + int err=0; + jclass clzobject = (*env)->FindClass( env, "java/lang/Object" ); + retobjarr = (*env)->NewObjectArray( env, n, clzobject, 0 ); + int i,j; + for (i=0;iSetObjectArrayElement( env, retobjarr, i, JNIGNULL ); + else (*env)->SetObjectArrayElement( env, retobjarr, i, (jobject)*(unsigned char*)AV(ra) ); + } else if((INT==AT(ra))&&(1==AN(ra))) { + if(!(*(I*)AV(ra))) (*env)->SetObjectArrayElement( env, retobjarr, i, JNIGNULL ); + else (*env)->SetObjectArrayElement( env, retobjarr, i, (jobject)*(I*)AV(ra) ); + } else {err=1; break;} + } + if (!err) { + return retobjarr; + } else { +// for (j=0;jDeleteLocalRef(env, (*env)->GetObjectArrayElement( env, retobjarr, j ) ); + + (*env)->DeleteLocalRef(env, retobjarr); + return JNIGNULL; + } + } else return JNIGNULL; +} + diff --git a/jni/j-jni-interface.h b/jni/j-jni-interface.h index 381879d..c01fda3 100644 --- a/jni/j-jni-interface.h +++ b/jni/j-jni-interface.h @@ -1,7 +1,46 @@ #ifndef J_JNI_INTERFACE +#define J_JNI_INTERFACE #ifdef ANDROID + + +#define ANDROID_ABI_ARM5 1 +#define ANDROID_ABI_ARM7 2 +#define ANDROID_ABI_x86 3 + +int _stdcall android_get_abi(); int _stdcall android_download_file(const char* url, const char* file); +int _stdcall android_unzip_file(const char* file, const char* todir); +int _stdcall android_launch_app(const char* action, const char* data, const char* type,int flags); +//char* _stdcall android_exec_host(const char *cmd); +void _stdcall android_quit(); +void _stdcall android_free(void* ptr); +//extern char android_temp_dir[]; +#endif + +#ifdef ANDROID +#define LOCALOGTAG "j-interface" +#include +#define LOGD(msg) __android_log_write(ANDROID_LOG_DEBUG,LOCALOGTAG,msg) +#define LOGFD(...) __android_log_print(ANDROID_LOG_DEBUG,LOCALOGTAG,__VA_ARGS__) + +#ifdef __ARM_ARCH_7__ +/* ARM-7 */ +static int android_abi = ANDROID_ABI_ARM7; +#elseif defined(__ARM_ARCH_5__) +/* ARM-5 */ +static int android_abi = ANDROID_ABI_ARM5; +#else +/* x86 */ +static int android_abi = ANDROID_ABI_x86; +#endif + +#else +#include +#define LOGD(msg) printf("%s: %s\n",LOCALOGTAG,msg) + +#define LOGFD(str,...) printf(LOCALOGTAG " " str,__VA_ARGS__) + #endif #endif // J_JNI_INTERFACE diff --git a/jni/jthostne_android.c b/jni/jthostne_android.c new file mode 100644 index 0000000..c3c1003 --- /dev/null +++ b/jni/jthostne_android.c @@ -0,0 +1,71 @@ +#ifdef ANDROID + +#include "j.h" +#include "x.h" +#include "jni/j-jni-interface.h" + +#include + + + +#if defined(link) +//#error link is as *link* +#undef link +#endif +#include + +F1(jthostne){A z;C*s; + F1RANK(1,jthostne,0); + if (isatty(0)) { + ASSERT(AT(w)==LIT,EVFACE); + RZ(w=vs(w)); + s=CAV(w); +#if SYS & SYS_PCWIN + ASSERT(0,EVNONCE); +#else + { + I b; + b=system(s); +#if !SY_64 && (SYS&SYS_LINUX) && !ANDROID + //Java-jnative-j.so system always returns -1 + if(jt->sm==SMJAVA&&-1==b) b=-1==system("")?0:-1; +#endif + b=!b; + ASSERT(b,EVFACE); + } +#endif + R mtv; + } else { + ASSERT(AT(w)==BOX,EVFACE); + int an=AN(w); + ASSERT(an>=2,EVFACE); + A* l=AAV(w); + char* ac; char* d; char* t; I lr; + int flags=0; + +#define BXD(ptr,arr,nn) \ + if(nn3) { + ASSERT(AT(*(l+3))==INT,EVFACE); + flags=*IAV(*(l+3)); + } + + int res = android_launch_app(ac,d,t,flags); + if(t!=NULL) free(t); if(d!=NULL) free(d); if(ac!=NULL) free(ac); + R sc(res); + } +} + +#endif diff --git a/jni/org_dykman_j_android_JInterface.h b/jni/org_dykman_j_android_JInterface.h index e6131b3..492264b 100644 --- a/jni/org_dykman_j_android_JInterface.h +++ b/jni/org_dykman_j_android_JInterface.h @@ -1,6 +1,6 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class org_dykman_j_JInterface */ + #include + /* Header for class org_dykman_j_JInterface */ #ifndef _Included_org_dykman_j_JInterface #define _Included_org_dykman_j_JInterface @@ -27,6 +27,14 @@ extern "C" { JNIEXPORT jobject JNICALL Java_org_dykman_j_JInterface_getVariableNative (JNIEnv *, jobject, jlong, jstring); +/* + * Class: org_dykman_j_JInterface + * Method: setVariableNative + * Signature: (JLjava/lang/String;Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_setVariableNative + (JNIEnv *, jobject, jlong, jstring, jobject); + /* * Class: org_dykman_j_JInterface * Method: callJNative @@ -51,7 +59,6 @@ JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_destroyJNative JNIEXPORT jlong JNICALL Java_org_dykman_j_JInterface_initializeJNative (JNIEnv *, jobject); - /* * Class: org_dykman_j_JInterface * Method: setEnv @@ -60,6 +67,86 @@ JNIEXPORT jlong JNICALL Java_org_dykman_j_JInterface_initializeJNative JNIEXPORT void JNICALL Java_org_dykman_j_JInterface_setEnv (JNIEnv *, jobject, jstring, jstring); +/* + * Class: org_dykman_j_JInterface + * Method: jnido + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_dykman_j_JInterface_jnido + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoz + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[Z + */ +JNIEXPORT jbooleanArray JNICALL Java_org_dykman_j_JInterface_jnidoz + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidos + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[S + */ +JNIEXPORT jshortArray JNICALL Java_org_dykman_j_JInterface_jnidoi + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoi + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[I + */ +JNIEXPORT jintArray JNICALL Java_org_dykman_j_JInterface_jnidoi + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidol + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[J + */ +JNIEXPORT jlongArray JNICALL Java_org_dykman_j_JInterface_jnidol + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidof + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[F + */ +JNIEXPORT jfloatArray JNICALL Java_org_dykman_j_JInterface_jnidof + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidod + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[D + */ +JNIEXPORT jdoubleArray JNICALL Java_org_dykman_j_JInterface_jnidod + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidoc + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_dykman_j_JInterface_jnidoc + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidow + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[C + */ +JNIEXPORT jcharArray JNICALL Java_org_dykman_j_JInterface_jnidow + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + +/* + * Class: org_dykman_j_JInterface + * Method: jnidox + * Signature: (JLjava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)[Ljava/lang/Object; + */ +JNIEXPORT jobjectArray JNICALL Java_org_dykman_j_JInterface_jnidox + (JNIEnv *, jobject, jlong, jobject, jstring, jobjectArray); + #ifdef __cplusplus } #endif diff --git a/js.h b/js.h index d8e70b7..d327e5d 100644 --- a/js.h +++ b/js.h @@ -158,7 +158,7 @@ #endif #endif -/* _WIN64 defined by VC++ and _UNIX64 defined in makefile */ +/* _WIN64 defined by VC++ or MINGW64, and _UNIX64 defined in makefile */ #if defined(_WIN64) || defined(_UNIX64) #undef SY_64 #define SY_64 1 @@ -170,7 +170,7 @@ #if 1!=SY_WIN32+SY_LINUX+SY_MAC error: "one and only one of SY_WIN32, SY_LINUX, SY_MAC must be 1" -#endif +#endif #endif /* only include once */ diff --git a/linenoise.c b/linenoise.c new file mode 100644 index 0000000..b824dff --- /dev/null +++ b/linenoise.c @@ -0,0 +1,612 @@ +/* linenoise.c -- guerrilla line editing library against the idea that a + * line editing lib needs to be 20,000 lines of C code. + * + * You can find the latest source code at: + * + * http://github.com/antirez/linenoise + * + * Does a number of crazy assumptions that happen to be true in 99.9999% of + * the 2010 UNIX computers around. + * + * ------------------------------------------------------------------------ + * + * Copyright (c) 2010, Salvatore Sanfilippo + * Copyright (c) 2010, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ------------------------------------------------------------------------ + * + * References: + * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html + * + * Todo list: + * - Switch to gets() if $TERM is something we can't support. + * - Filter bogus Ctrl+ combinations. + * - Win32 support + * + * Bloat: + * - Completion? + * - History search like Ctrl+r in readline? + * + * List of escape sequences used by this program, we do everything just + * with three sequences. In order to be so cheap we may have some + * flickering effect with some slow terminal, but the lesser sequences + * the more compatible. + * + * CHA (Cursor Horizontal Absolute) + * Sequence: ESC [ n G + * Effect: moves cursor to column n + * + * EL (Erase Line) + * Sequence: ESC [ n K + * Effect: if n is 0 or missing, clear from cursor to end of line + * Effect: if n is 1, clear from beginning of line to cursor + * Effect: if n is 2, clear entire line + * + * CUF (CUrsor Forward) + * Sequence: ESC [ n C + * Effect: moves cursor forward of n chars + * + * The following are used to clear the screen: ESC [ H ESC [ 2 J + * This is actually composed of two sequences: + * + * cursorhome + * Sequence: ESC [ H + * Effect: moves the cursor to upper left corner + * + * ED2 (Clear entire screen) + * Sequence: ESC [ 2 J + * Effect: clear the whole screen + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "linenoise.h" + +#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 +#define LINENOISE_MAX_LINE 4096 +static char *unsupported_term[] = {"dumb","cons25",NULL}; +static linenoiseCompletionCallback *completionCallback = NULL; + +static struct termios orig_termios; /* in order to restore at exit */ +static int rawmode = 0; /* for atexit() function to check if restore is needed*/ +static int atexit_registered = 0; /* register atexit just 1 time */ +static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; +static int history_len = 0; +char **history = NULL; + +static void linenoiseAtExit(void); +int linenoiseHistoryAdd(const char *line); + +static int isUnsupportedTerm(void) { + char *term = getenv("TERM"); + int j; + + if (term == NULL) return 0; + for (j = 0; unsupported_term[j]; j++) + if (!strcasecmp(term,unsupported_term[j])) return 1; + return 0; +} + +static void freeHistory(void) { + if (history) { + int j; + + for (j = 0; j < history_len; j++) + free(history[j]); + free(history); + } +} + +static int enableRawMode(int fd) { + struct termios raw; + + if (!isatty(STDIN_FILENO)) goto fatal; + if (!atexit_registered) { + atexit(linenoiseAtExit); + atexit_registered = 1; + } + if (tcgetattr(fd,&orig_termios) == -1) goto fatal; + + raw = orig_termios; /* modify the original mode */ + /* input modes: no break, no CR to NL, no parity check, no strip char, + * no start/stop output control. */ + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + /* output modes - disable post processing */ + raw.c_oflag &= ~(OPOST); + /* control modes - set 8 bit chars */ + raw.c_cflag |= (CS8); + /* local modes - choing off, canonical off, no extended functions, + * no signal chars (^Z,^C) */ + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + /* control chars - set return condition: min number of bytes and timer. + * We want read to return every single byte, without timeout. */ + raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ + + /* put terminal in raw mode after flushing */ + if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal; + rawmode = 1; + return 0; + +fatal: + errno = ENOTTY; + return -1; +} + +static void disableRawMode(int fd) { + /* Don't even check the return value as it's too late. */ + if (rawmode && tcsetattr(fd,TCSAFLUSH,&orig_termios) != -1) + rawmode = 0; +} + +/* At exit we'll try to fix the terminal to the initial conditions. */ +static void linenoiseAtExit(void) { + disableRawMode(STDIN_FILENO); + freeHistory(); +} + +static int getColumns(void) { + struct winsize ws; + + if (ioctl(1, TIOCGWINSZ, &ws) == -1) return 80; + return ws.ws_col; +} + +static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_t pos, size_t cols) { + char seq[64]; + size_t plen = strlen(prompt); + + while((plen+pos) >= cols) { + buf++; + len--; + pos--; + } + while (plen+len > cols) { + len--; + } + + /* Cursor to left edge */ + snprintf(seq,64,"\x1b[0G"); + if (write(fd,seq,strlen(seq)) == -1) return; + /* Write the prompt and the current buffer content */ + if (write(fd,prompt,strlen(prompt)) == -1) return; + if (write(fd,buf,len) == -1) return; + /* Erase to right */ + snprintf(seq,64,"\x1b[0K"); + if (write(fd,seq,strlen(seq)) == -1) return; + /* Move cursor to original position. */ + snprintf(seq,64,"\x1b[0G\x1b[%dC", (int)(pos+plen)); + if (write(fd,seq,strlen(seq)) == -1) return; +} + +static void beep() { + fprintf(stderr, "\x7"); + fflush(stderr); +} + +static void freeCompletions(linenoiseCompletions *lc) { + size_t i; + for (i = 0; i < lc->len; i++) + free(lc->cvec[i]); + if (lc->cvec != NULL) + free(lc->cvec); +} + +static int completeLine(int fd, const char *prompt, char *buf, size_t buflen, size_t *len, size_t *pos, size_t cols) { + linenoiseCompletions lc = { 0, NULL }; + int nread, nwritten; + char c = 0; + + completionCallback(buf,&lc); + if (lc.len == 0) { + beep(); + } else { + size_t stop = 0, i = 0; + size_t clen; + + while(!stop) { + /* Show completion or original buffer */ + if (i < lc.len) { + clen = strlen(lc.cvec[i]); + refreshLine(fd,prompt,lc.cvec[i],clen,clen,cols); + } else { + refreshLine(fd,prompt,buf,*len,*pos,cols); + } + + nread = read(fd,&c,1); + if (nread <= 0) { + freeCompletions(&lc); + return -1; + } + + switch(c) { + case 9: /* tab */ + i = (i+1) % (lc.len+1); + if (i == lc.len) beep(); + break; + case 27: /* escape */ + /* Re-show original buffer */ + if (i < lc.len) { + refreshLine(fd,prompt,buf,*len,*pos,cols); + } + stop = 1; + break; + default: + /* Update buffer and return */ + if (i < lc.len) { + nwritten = snprintf(buf,buflen,"%s",lc.cvec[i]); + *len = *pos = nwritten; + } + stop = 1; + break; + } + } + } + + freeCompletions(&lc); + return c; /* Return last read character */ +} + +void linenoiseClearScreen(void) { + if (write(STDIN_FILENO,"\x1b[H\x1b[2J",7) <= 0) { + /* nothing to do, just to avoid warning. */ + } +} + +static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) { + size_t plen = strlen(prompt); + size_t pos = 0; + size_t len = 0; + size_t cols = getColumns(); + int history_index = 0; + + buf[0] = '\0'; + buflen--; /* Make sure there is always space for the nulterm */ + + /* The latest history entry is always our current buffer, that + * initially is just an empty string. */ + linenoiseHistoryAdd(""); + + if (write(fd,prompt,plen) == -1) return -1; + while(1) { + char c; + int nread; + char seq[2], seq2[2]; + + nread = read(fd,&c,1); + if (nread <= 0) return len; + + /* Only autocomplete when the callback is set. It returns < 0 when + * there was an error reading from fd. Otherwise it will return the + * character that should be handled next. */ + if (c == 9 && completionCallback != NULL) { + c = completeLine(fd,prompt,buf,buflen,&len,&pos,cols); + /* Return on errors */ + if (c < 0) return len; + /* Read next character when 0 */ + if (c == 0) continue; + } + + switch(c) { + case 13: /* enter */ + history_len--; + free(history[history_len]); + return (int)len; + case 3: /* ctrl-c */ + errno = EAGAIN; + return -1; + case 127: /* backspace */ + case 8: /* ctrl-h */ + if (pos > 0 && len > 0) { + memmove(buf+pos-1,buf+pos,len-pos); + pos--; + len--; + buf[len] = '\0'; + refreshLine(fd,prompt,buf,len,pos,cols); + } + break; + case 4: /* ctrl-d, remove char at right of cursor */ + if (len > 1 && pos < (len-1)) { + memmove(buf+pos,buf+pos+1,len-pos); + len--; + buf[len] = '\0'; + refreshLine(fd,prompt,buf,len,pos,cols); + } else if (len == 0) { + history_len--; + free(history[history_len]); + return -1; + } + break; + case 20: /* ctrl-t */ + if (pos > 0 && pos < len) { + int aux = buf[pos-1]; + buf[pos-1] = buf[pos]; + buf[pos] = aux; + if (pos != len-1) pos++; + refreshLine(fd,prompt,buf,len,pos,cols); + } + break; + case 2: /* ctrl-b */ + goto left_arrow; + case 6: /* ctrl-f */ + goto right_arrow; + case 16: /* ctrl-p */ + seq[1] = 65; + goto up_down_arrow; + case 14: /* ctrl-n */ + seq[1] = 66; + goto up_down_arrow; + break; + case 27: /* escape sequence */ + if (read(fd,seq,2) == -1) break; + if (seq[0] == 91 && seq[1] == 68) { +left_arrow: + /* left arrow */ + if (pos > 0) { + pos--; + refreshLine(fd,prompt,buf,len,pos,cols); + } + } else if (seq[0] == 91 && seq[1] == 67) { +right_arrow: + /* right arrow */ + if (pos != len) { + pos++; + refreshLine(fd,prompt,buf,len,pos,cols); + } + } else if (seq[0] == 91 && (seq[1] == 65 || seq[1] == 66)) { +up_down_arrow: + /* up and down arrow: history */ + if (history_len > 1) { + /* Update the current history entry before to + * overwrite it with tne next one. */ + free(history[history_len-1-history_index]); + history[history_len-1-history_index] = strdup(buf); + /* Show the new entry */ + history_index += (seq[1] == 65) ? 1 : -1; + if (history_index < 0) { + history_index = 0; + break; + } else if (history_index >= history_len) { + history_index = history_len-1; + break; + } + strncpy(buf,history[history_len-1-history_index],buflen); + buf[buflen] = '\0'; + len = pos = strlen(buf); + refreshLine(fd,prompt,buf,len,pos,cols); + } + } else if (seq[0] == 91 && seq[1] > 48 && seq[1] < 55) { + /* extended escape */ + if (read(fd,seq2,2) == -1) break; + if (seq[1] == 51 && seq2[0] == 126) { + /* delete */ + if (len > 0 && pos < len) { + memmove(buf+pos,buf+pos+1,len-pos-1); + len--; + buf[len] = '\0'; + refreshLine(fd,prompt,buf,len,pos,cols); + } + } + } + break; + default: + if (len < buflen) { + if (len == pos) { + buf[pos] = c; + pos++; + len++; + buf[len] = '\0'; + if (plen+len < cols) { + /* Avoid a full update of the line in the + * trivial case. */ + if (write(fd,&c,1) == -1) return -1; + } else { + refreshLine(fd,prompt,buf,len,pos,cols); + } + } else { + memmove(buf+pos+1,buf+pos,len-pos); + buf[pos] = c; + len++; + pos++; + buf[len] = '\0'; + refreshLine(fd,prompt,buf,len,pos,cols); + } + } + break; + case 21: /* Ctrl+u, delete the whole line. */ + buf[0] = '\0'; + pos = len = 0; + refreshLine(fd,prompt,buf,len,pos,cols); + break; + case 11: /* Ctrl+k, delete from current to end of line. */ + buf[pos] = '\0'; + len = pos; + refreshLine(fd,prompt,buf,len,pos,cols); + break; + case 1: /* Ctrl+a, go to the start of the line */ + pos = 0; + refreshLine(fd,prompt,buf,len,pos,cols); + break; + case 5: /* ctrl+e, go to the end of the line */ + pos = len; + refreshLine(fd,prompt,buf,len,pos,cols); + break; + case 12: /* ctrl+l, clear screen */ + linenoiseClearScreen(); + refreshLine(fd,prompt,buf,len,pos,cols); + } + } + return len; +} + +static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) { + int fd = STDIN_FILENO; + int count; + + if (buflen == 0) { + errno = EINVAL; + return -1; + } + if (!isatty(STDIN_FILENO)) { + if (fgets(buf, buflen, stdin) == NULL) return -1; + count = strlen(buf); + if (count && buf[count-1] == '\n') { + count--; + buf[count] = '\0'; + } + } else { + if (enableRawMode(fd) == -1) return -1; + count = linenoisePrompt(fd, buf, buflen, prompt); + disableRawMode(fd); + printf("\n"); + } + return count; +} + +char *linenoise(const char *prompt) { + char buf[LINENOISE_MAX_LINE]; + int count; + + if (isUnsupportedTerm()) { + size_t len; + + printf("%s",prompt); + fflush(stdout); + if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL; + len = strlen(buf); + while(len && (buf[len-1] == '\n' || buf[len-1] == '\r')) { + len--; + buf[len] = '\0'; + } + return strdup(buf); + } else { + count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt); + if (count == -1) return NULL; + return strdup(buf); + } +} + +/* Register a callback function to be called for tab-completion. */ +void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) { + completionCallback = fn; +} + +void linenoiseAddCompletion(linenoiseCompletions *lc, char *str) { + size_t len = strlen(str); + char *copy = malloc(len+1); + memcpy(copy,str,len+1); + lc->cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1)); + lc->cvec[lc->len++] = copy; +} + +/* Using a circular buffer is smarter, but a bit more complex to handle. */ +int linenoiseHistoryAdd(const char *line) { + char *linecopy; + + if (history_max_len == 0) return 0; + if (history == NULL) { + history = malloc(sizeof(char*)*history_max_len); + if (history == NULL) return 0; + memset(history,0,(sizeof(char*)*history_max_len)); + } + linecopy = strdup(line); + if (!linecopy) return 0; + if (history_len == history_max_len) { + free(history[0]); + memmove(history,history+1,sizeof(char*)*(history_max_len-1)); + history_len--; + } + history[history_len] = linecopy; + history_len++; + return 1; +} + +int linenoiseHistorySetMaxLen(int len) { + char **new; + + if (len < 1) return 0; + if (history) { + int tocopy = history_len; + + new = malloc(sizeof(char*)*len); + if (new == NULL) return 0; + if (len < tocopy) tocopy = len; + memcpy(new,history+(history_max_len-tocopy), sizeof(char*)*tocopy); + free(history); + history = new; + } + history_max_len = len; + if (history_len > history_max_len) + history_len = history_max_len; + return 1; +} + +/* Save the history in the specified file. On success 0 is returned + * otherwise -1 is returned. */ +int linenoiseHistorySave(char *filename) { + FILE *fp = fopen(filename,"w"); + int j; + + if (fp == NULL) return -1; + for (j = 0; j < history_len; j++) + fprintf(fp,"%s\n",history[j]); + fclose(fp); + return 0; +} + +/* Load the history from the specified file. If the file does not exist + * zero is returned and no operation is performed. + * + * If the file exists and the operation succeeded 0 is returned, otherwise + * on error -1 is returned. */ +int linenoiseHistoryLoad(char *filename) { + FILE *fp = fopen(filename,"r"); + char buf[LINENOISE_MAX_LINE]; + + if (fp == NULL) return -1; + + while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) { + char *p; + + p = strchr(buf,'\r'); + if (!p) p = strchr(buf,'\n'); + if (p) *p = '\0'; + linenoiseHistoryAdd(buf); + } + fclose(fp); + return 0; +} diff --git a/linenoise.h b/linenoise.h new file mode 100644 index 0000000..15f2a31 --- /dev/null +++ b/linenoise.h @@ -0,0 +1,56 @@ +/* linenoise.h -- guerrilla line editing library against the idea that a + * line editing lib needs to be 20,000 lines of C code. + * + * See linenoise.c for more information. + * + * ------------------------------------------------------------------------ + * + * Copyright (c) 2010, Salvatore Sanfilippo + * Copyright (c) 2010, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINENOISE_H +#define __LINENOISE_H + +typedef struct linenoiseCompletions { + size_t len; + char **cvec; +} linenoiseCompletions; + +typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); +void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); +void linenoiseAddCompletion(linenoiseCompletions *, char *); + +char *linenoise(const char *prompt); +int linenoiseHistoryAdd(const char *line); +int linenoiseHistorySetMaxLen(int len); +int linenoiseHistorySave(char *filename); +int linenoiseHistoryLoad(char *filename); +void linenoiseClearScreen(void); + +#endif /* __LINENOISE_H */ diff --git a/makefile b/makefile new file mode 100644 index 0000000..436dee2 --- /dev/null +++ b/makefile @@ -0,0 +1,16 @@ +CFLAGS=$(COMP) +CXXFLAGS=$(COMP) + +libj : $(LIBJ_OBJS) $(LIBJ_WIN_OBJS) $(LIBJ_WINOLE_OBJS) $(LIBJ_JJNI_OBJS) + ${CXX} $(LIBJ_OBJS) $(LIBJ_WIN_OBJS) $(LIBJ_WINOLE_OBJS) $(LIBJ_JJNI_OBJS) $(LIBJDEF) $(SOLINK) + +jconsole : jconsole.o jeload.o + ${CC} jconsole.o jeload.o $(LIBREADLINE) $(JCONLINK) -o jconsole + +tsdll : tsdll.o + ${CC} tsdll.o $(LIBTSDEF) $(TSLINK) + +clean : + rm -f *.o win/*.o *.dll *.so jconsole *.x *.jmf + +.PHONY : clean diff --git a/mips/fenv.c b/mips/fenv.c new file mode 100644 index 0000000..1e5b7f1 --- /dev/null +++ b/mips/fenv.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/mips/fenv.c,v 1.1 2008/04/26 12:20:29 imp Exp $ + */ + +#include "fenv.h" + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; diff --git a/mips/fenv.h b/mips/fenv.h new file mode 100644 index 0000000..583d002 --- /dev/null +++ b/mips/fenv.h @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/mips/fenv.h,v 1.1 2008/04/26 12:20:29 imp Exp $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include + +__BEGIN_DECLS + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0001 +#define FE_DIVBYZERO 0x0002 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0010 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 16 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +#ifdef ARM_HARD_FLOAT +#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) +#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) +#else +#define __rfs(__fpsr) +#define __wfs(__fpsr) +#endif + +static __inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __wfs(__fpsr); + return (0); +} + +static __inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +static __inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + __wfs(__fpsr); + return (0); +} + +static __inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + +static __inline int +fetestexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + return (__fpsr & __excepts); +} + +static __inline int +fegetround(void) +{ + + /* + * Apparently, the rounding mode is specified as part of the + * instruction format on ARM, so the dynamic rounding mode is + * indeterminate. Some FPUs may differ. + */ + return (-1); +} + +static __inline int +fesetround(int __round) +{ + + return (-1); +} + +static __inline int +fegetenv(fenv_t *__envp) +{ + + __rfs(__envp); + return (0); +} + +static __inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + __rfs(&__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __wfs(__env); + return (0); +} + +static __inline int +fesetenv(const fenv_t *__envp) +{ + + __wfs(*__envp); + return (0); +} + +static __inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __wfs(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +static __inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static __inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static __inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + __rfs(&__fpsr); + return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ + diff --git a/required_arithmetic.h b/required_arithmetic.h new file mode 100644 index 0000000..28b5429 --- /dev/null +++ b/required_arithmetic.h @@ -0,0 +1,120 @@ +/* + * required_arithmetic.h + * + * by Ian Ollmann + * + * Copyright (c) Apple Inc, 2007. All Rights Reserved. + * + * The function of this header is to provide various cLibm routines with + * interfaces that cause arithmetic to *always* happen. This header is needed + * in various places in Libm, because we use arithmetic to set floating point + * state flags. Frequently the product of that arithmetic is not used for the + * numerical result of the function, so the compiler erroneously optimizes + * it away. The intent of this header is to provide basic operators that + * utilize compiler and/or platform specific devices (such as volatile asms) + * to prevent the compiler from optimizing away the arithmetic. If no such + * device is available, you can encapsulate these operations as non-inlined + * functions with the implementation in a separate compilation unit or static + * library as required to prevent the compiler from removing them. + * + * Sample implementations are provided for __i386__, both as sample code and + * so we can test the library. Other architectures are required to provide + * their own implementation. + * + */ +#if defined( __GNUC__ ) + #define ALWAYS_INLINE_NO_DEBUG __attribute__ (( __always_inline__, __nodebug__ )) +#else + #define ALWAYS_INLINE_NO_DEBUG +#endif + +#ifndef __arm__ + #error This file is for ARM with VFP only +#endif + + +#pragma mark - +#pragma mark Declarations + +static inline float required_add_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; +static inline float required_multiply_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; +static inline float required_divide_float( float a, float b ) ALWAYS_INLINE_NO_DEBUG; +static inline int required_convert_float_to_int( float a ) ALWAYS_INLINE_NO_DEBUG; + +static inline double required_add_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; +static inline double required_multiply_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; +static inline double required_divide_double( double a, double b ) ALWAYS_INLINE_NO_DEBUG; +static inline int required_convert_double_to_int( double a ) ALWAYS_INLINE_NO_DEBUG; + +#pragma mark - +#pragma mark Implementation + +// --------------------- single precision ------------------------- + +static inline float required_add_float( float a, float b ) +{ + register float r; + __asm__ __volatile__ ( "fadds %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +static inline float required_multiply_float( float a, float b ) +{ + register float r; + __asm__ __volatile__ ( "fmuls %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +static inline float required_divide_float( float a, float b ) +{ + register float r; + __asm__ __volatile__ ( "fdivs %0, %1, %2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +//rounds toward zero +static inline int required_convert_float_to_int( float a ) +{ + register float temp; + register int result; + + __asm__ __volatile__ ( "ftosizs %0, %1" : "=w" (temp) : "w" (a) ); + __asm__ __volatile__ ( "fmrs %0, %1" : "=r" (result) : "w" (temp) ); + + return result; +} + +// ---------------- double precision -------------------------- + +static inline double required_add_double( double a, double b ) +{ + register double r; + __asm__ __volatile__ ( "faddd %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +static inline double required_multiply_double( double a, double b ) +{ + register double r; + __asm__ __volatile__ ( "fmuld %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +static inline double required_divide_double( double a, double b ) +{ + register double r; + __asm__ __volatile__ ( "fdivd %P0, %P1, %P2" : "=w" (r) : "w" (a), "w" (b) ); + return r; +} + +//rounds toward zero +static inline int required_convert_double_to_int( double a ) +{ + register float temp; + register int result; + + __asm__ __volatile__ ( "ftosizd %0, %P1" : "=w" (temp) : "w" (a) ); + __asm__ __volatile__ ( "fmrs %0, %1" : "=r" (result) : "w" (temp) ); + + return result; +} diff --git a/s.c b/s.c index 11d8947..d58cec6 100644 --- a/s.c +++ b/s.c @@ -38,8 +38,6 @@ /* named locales: */ /* jt->stloc: locales symbol table */ -UI nmhash (I k,UC*v){UI z=*v>>7; DO(k,z=(k-i)^(1000003*z)^*v++;); R z;} - static I symcol=(sizeof(L)+SZI-1)/SZI; B jtsymext(J jt,B b){A x,y;I j,m,n,s[2],*v,xn,yn;L*u; @@ -74,7 +72,7 @@ L* jtsymnew(J jt,I*hv){I j;L*u,*v; B jtsymfree(J jt,L*u){I q; q=u->next; - if(q)(q+jt->sympv)->prev=u->prev; + if(q)(q+jt->sympv)->prev=u->prev; if(LHEAD&u->flag){*(I*)u->prev=q; if(q)(q+jt->sympv)->flag|=LHEAD;} else (u->prev+jt->sympv)->next=q; fa(u->name); u->name=0; /* zero out data fields */ @@ -89,7 +87,7 @@ static SYMWALK(jtsymfreeha, B,B01,100,1, 1, RZ(symfree(d))) /* free pool table B jtsymfreeh(J jt,A w,L*v){I*wv;L*u; wv=AV(w); ASSERTSYS(*wv,"symfreeh"); - u=*wv+jt->sympv; + u=*wv+jt->sympv; RZ(symfree(u)); RZ(symfreeha(w)); memset(wv,C0,AN(w)*SZI); @@ -102,8 +100,8 @@ B jtsymfreeh(J jt,A w,L*v){I*wv;L*u; static SYMWALK(jtsympoola, I,INT,100,1, 1, *zv++=j;) F1(jtsympool){A aa,*pu,q,x,y,*yv,z,*zv;I i,j,n,*u,*v,*xv;L*pv; - RZ(w); - ASSERT(1==AR(w),EVRANK); + RZ(w); + ASSERT(1==AR(w),EVRANK); ASSERT(!AN(w),EVLENGTH); GA(z,BOX,3,1,0); zv=AAV(z); n=*AS(jt->symp); pv=jt->sympv; @@ -120,9 +118,9 @@ F1(jtsympool){A aa,*pu,q,x,y,*yv,z,*zv;I i,j,n,*u,*v,*xv;L*pv; } GA(y,BOX,n,1,0); yv=AAV(y); zv[2]=y; DO(n, yv[i]=mtv;); - n=AN(jt->stloc); v=AV(jt->stloc); + n=AN(jt->stloc); v=AV(jt->stloc); for(i=0;isympv)->val; + x=(j+jt->sympv)->val; RZ(yv[j]=yv[*AV(x)]=aa=sfn(1,LOCNAME(x))); RZ(q=sympoola(x)); u=AV(q); DO(AN(q), yv[u[i]]=aa;); } @@ -155,13 +153,13 @@ static L*jtprobeis(J jt,A a,A g){C*s;I*hv,k,m;L*v;NM*u; u=NAV(a); m=u->m; s=u->s; k=u->hash%AN(g); hv=AV(g)+(k?k:1); if(*hv){ /* !*hv means (0) empty slot */ v=*hv+jt->sympv; - while(1){ + while(1){ u=NAV(v->name); if(m==u->m&&!memcmp(s,u->s,m))R jt->cursymb=v; /* (1) exact match */ if(!v->next)break; /* (2) link list end */ v=v->next+jt->sympv; }} - RZ(v=symnew(hv)); + RZ(v=symnew(hv)); v->name=ra(a); R jt->cursymb=v; } /* probe for assignment */ @@ -170,25 +168,25 @@ static L*jtsyrd1(J jt,A a,A g,B b){A*v,x,y;L*e;NM*av; if(b&&jt->local&&(e=probe(a,jt->local))){av=NAV(a); R av->e=e;} RZ(g&&(y=LOCPATH(g))); if(e=probe(a,g))R e; - v=AAV(y); + v=AAV(y); DO(AN(y), x=v[i]; if(e=probe(a,stfind(1,AN(x),CAV(x))))break;); R e; -} /* find name a where the current locale is g */ +} /* find name a where the current locale is g */ static A jtlocindirect(J jt,I n,C*u){A a,g=jt->global,x,y;B lcl=1;C*s,*v,*xv;I k,xn;L*e; s=n+u; while(uval; - ASSERTN(!AR(y),EVRANK,a); + y=e->val; + ASSERTN(!AR(y),EVRANK,a); ASSERTN(BOX&AT(y),EVDOMAIN,a); - x=AAV0(y); xn=AN(x); xv=CAV(x); - ASSERTN(1>=AR(x),EVRANK,a); + x=AAV0(y); xn=AN(x); xv=CAV(x); + ASSERTN(1>=AR(x),EVRANK,a); ASSERTN(xn,EVLENGTH,a); - ASSERTN(LIT&AT(x),EVDOMAIN,a); + ASSERTN(LIT&AT(x),EVDOMAIN,a); ASSERTN(vlocnm(xn,xv),EVILNAME,a); RZ(g=stfind(1,xn,xv)); } @@ -208,9 +206,9 @@ static A jtdllsymaddr(J jt,A w,C flag){A*wv,x,y,z;I i,n,wd,*zv;L*v; RZ(w); n=AN(w); wv=AAV(w); wd=(I)w*ARELATIVE(w); ASSERT(!n||BOX&AT(w),EVDOMAIN); - GA(z,INT,n,AR(w),AS(w)); zv=AV(z); + GA(z,INT,n,AR(w),AS(w)); zv=AV(z); for(i=0;ival; ASSERT(NOUN&AT(y),EVDOMAIN); @@ -250,16 +248,16 @@ A jtsymbis(J jt,A a,A w,A g){A x;I m,n,wn,wr,wt;NM*v;L*e;V*wv; n=AN(a); v=NAV(a); m=v->m; if(n==m)ASSERT(!(jt->local&&g==jt->global&&probe(a,jt->local)),EVDOMAIN) else{C*s=1+m+v->s; RZ(g=NMILOC&v->flag?locindirect(n-m-2,1+s):stfind(1,n-m-2,s));} - RZ(e=probeis(a,g)); + RZ(e=probeis(a,g)); if(jt->db)RZ(redef(w,e)); wt=AT(w); if(wt&FUNC&&(wv=VAV(w),wv->f)){if(wv->id==CCOLON)wv->flag|=VNAMED; if(jt->glock)wv->flag|=VLOCK;} - x=e->val; + x=e->val; ASSERT(!(x&&AFRO&AFLAG(x)),EVRO); if(!(x&&AFNJA&AFLAG(x))){ - RZ(w=ra(AFNJA&AFLAG(w)?w:rca(w))); - nvrredef(x); - fa(x); + RZ(w=ra(AFNJA&AFLAG(w)?w:rca(w))); + nvrredef(x); + fa(x); e->val=w; }else if(x!=w){ /* replacing mapped data */ if(wt&BOX)R smmis(x,w); diff --git a/s.h b/s.h index 60d37d9..2277647 100644 --- a/s.h +++ b/s.h @@ -6,6 +6,7 @@ #define LOCPATH(g) ((*AV(g)+jt->sympv)->val ) #define LOCNAME(g) ((*AV(g)+jt->sympv)->name) +#define NMHASH(p,s) (*(s)+(p)+99991L*(UC)(s)[(p)-1]) /* macro to define a function that walks through a symbol table */ diff --git a/sn.c b/sn.c index 6df9f5d..0808747 100644 --- a/sn.c +++ b/sn.c @@ -11,7 +11,7 @@ B jtvnm(J jt,I n,C*s){B b=0;C c,d,t;I j,k; c=*s; d=*(s+n-1); if(jt->dotnames&&2==n&&'.'==d&&('m'==c||'n'==c||'u'==c||'v'==c||'x'==c||'y'==c))R 1; RZ(CA==ctype[c]); - c='a'; + c='a'; DO(n, d=c; c=s[i]; t=ctype[c]; RZ(t==CA||t==C9); if(c=='_'&&d=='_'&&!b&&i!=n-1){j=1+i; b=1;}); if(c=='_'){DO(j=n-1, if('_'==s[--j])break;); k=n-j-2; R!b&&j&&(!k||vlocnm(k,s+j+1));} if(!b)R 1; @@ -19,7 +19,7 @@ B jtvnm(J jt,I n,C*s){B b=0;C c,d,t;I j,k; R !k; } /* validate name s, return type or 0 if error */ -B vlocnm(I n,C*s){C c,t; +B vlocnm(I n,C*s){C c,t; if(!n)R 0; DO(n, t=ctype[c=s[i]]; RZ(c!='_'&&(t==CA||t==C9));); if(C9==ctype[*s]){RZ(1==n||'0'!=*s); DO(n, c=s[i]; RZ('0'<=c&&c<='9'););} @@ -27,14 +27,14 @@ B vlocnm(I n,C*s){C c,t; } /* validate locale name */ A jtnfs(J jt,I n,C*s){A z;C c,f,*t;I m,p;NM*zv; - DO(n, if(' '!=*s)break; ++s; --n;); + DO(n, if(' '!=*s)break; ++s; --n;); t=s+n-1; DO(n, if(' '!=*t)break; --t; --n;); if((1==n||2==n&&'.'==s[1])&&strchr("mnuvxy",c=*s)){ if(1==n)R c=='y'?ynam:c=='x'?xnam:c=='v'?vnam:c=='u'?unam:c=='n'?nnam:mnam; else R c=='y'?ydot:c=='x'?xdot:c=='v'?vdot:c=='u'?udot:c=='n'?ndot:mdot; } - ASSERT(n,EVILNAME); + ASSERT(n,EVILNAME); GA(z,NAME,n,1,0); zv=NAV(z); memcpy(zv->s,s,n); *(n+zv->s)=0; f=0; m=n; p=0; @@ -43,7 +43,7 @@ A jtnfs(J jt,I n,C*s){A z;C c,f,*t;I m,p;NM*zv; ASSERT(m<=255&&p<=255,EVLIMIT); zv->flag=f; zv->sn=0; zv->e=0; - zv->m=(UC)m; zv->hash=nmhash(m,s); + zv->m=(UC)m; zv->hash=NMHASH(m,s); R z; } /* name from string */ @@ -73,11 +73,11 @@ static F1(jtstdnm){C*s;I j,n,p,q; F1(jtonm){A x,y; RZ(x=ope(w)); y=stdnm(x); ASSERTN(y,EVILNAME,nfs(AN(x),CAV(x))); R y;} -F1(jtnc){A*wv,x,y,z;I i,n,t,wd,*zv;L*v; +F1(jtnc){A*wv,x,y,z;I i,n,t,wd,*zv;L*v; RZ(w); n=AN(w); wv=AAV(w); wd=(I)w*ARELATIVE(w); ASSERT(!n||BOX&AT(w),EVDOMAIN); - GA(z,INT,n,AR(w),AS(w)); zv=AV(z); + GA(z,INT,n,AR(w),AS(w)); zv=AV(z); for(i=0;inla[*((UC*)NAV(d->name)->s)]&&jt->nlt&AT(d->val), +static SYMWALK(jtnlxxx, A,BOX,20,1, jt->nla[*((UC*)NAV(d->name)->s)]&&jt->nlt&AT(d->val), RZ(*zv++=sfn(1,d->name)) ) SYMWALK(jtnlsym, A,BOX,20,1, jt->nla[*((UC*)NAV(d->name)->s)], @@ -97,8 +97,8 @@ static SYMWALK(jtnlxxx, A,BOX,20,1, jt->nla[*((UC*)NAV(d->name)->s)]&&jt->nlt&AT static I nlmask[] = {NOUN,ADV,CONJ,VERB, MARK,MARK,SYMB,MARK}; static F1(jtnlx){A z=mtv;B b;I m=0,*v,x; - RZ(w=vi(w)); v=AV(w); - DO(AN(w), x=*v++; m|=nlmask[x<0||6nlt=m&RHS; b=1&&jt->nlt&RHS; ASSERT(!(m&MARK),EVDOMAIN); if(b )RZ(z=nlxxx(jt->global)); @@ -113,7 +113,7 @@ F1(jtnl1){memset(jt->nla,C1,256L); R nlx(w);} F2(jtnl2){UC*u; RZ(a&&w); ASSERT(LIT&AT(a),EVDOMAIN); - memset(jt->nla,C0,256L); + memset(jt->nla,C0,256L); u=UAV(a); DO(AN(a),jt->nla[*u++]=1;); R nlx(w); } /* 4!:1 name list */ @@ -121,7 +121,7 @@ F2(jtnl2){UC*u; F1(jtscind){A*wv,x,y,z;I n,wd,*zv;L*v; RZ(w); - n=AN(w); + n=AN(w); ASSERT(!n||BOX&AT(w),EVDOMAIN); wv=AAV(w); wd=(I)w*ARELATIVE(w); GA(z,INT,n,AR(w),AS(w)); zv=AV(z); @@ -143,7 +143,7 @@ static A jtnch1(J jt,B b,A w,I*pm,A ch){A*v,x,y;C*s,*yv;I*e,i,k,m,p,wn;L*d; if(b){ if(m==AN(ch)){RZ(ch=ext(0,ch)); v=m+AAV(ch);} x=d->name; k=NAV(x)->m; - GA(y,LIT,k+2+p,1,0); yv=CAV(y); + GA(y,LIT,k+2+p,1,0); yv=CAV(y); MC(yv,NAV(x)->s,k); MC(1+k+yv,s,p); yv[k]=yv[1+k+p]='_'; *v++=y; ++m; }} diff --git a/test/g100.ijs b/test/g100.ijs index 8ed786f..60dce33 100644 --- a/test/g100.ijs +++ b/test/g100.ijs @@ -1,3 +1,12 @@ +NB. arm NaN smoke test -------------------------------------------------- + +'NaN error' -: _ (- etx) _ +'NaN error' -: _ (% etx) _ +'NaN error' -.@-: (123 j. 0) (% etx) 1e307 +'NaN error' -.@-: 123j456 (% etx) 1e307 +'NaN error' -.@-: 1 (o. etx) 2p1 * 0.99 +'NaN error' -.@-: 1 (o. etx) 2p1 * 1.01 + NB. +y ------------------------------------------------------------------ t -: +t=.1=?100$2 diff --git a/test/g15x.ijs b/test/g15x.ijs index 708c19d..b4ce306 100644 --- a/test/g15x.ijs +++ b/test/g15x.ijs @@ -11,7 +11,7 @@ require 'dll' NB. DLL utils 3 : 0'' if. pc do. - require 'winapi' NB. API utils + require '~addons/api/winapi/winapi.ijs' NB. API utils else. winset=:1: end. @@ -44,11 +44,11 @@ fsetptr =: 4 : '>{.Fsetptr x;y;(<0);FILE_BEGIN' fcreate=: 3 : 0 NB. fcreate name >{.Fcreate y,(GENERIC_READ+GENERIC_WRITE);0;(<0);CREATE_NEW ;0;0 ) - + fopen =: 3 : 0 NB. fopen name >{.Fcreate y,(GENERIC_READ+GENERIC_WRITE);0;(<0);OPEN_EXISTING;0;0 ) - + fwrite =: 4 : 0 NB. string fwrite handle Fwrite y;x;(#x);(,0);<<0 ) diff --git a/test/g1x7.ijs b/test/g1x7.ijs index d8608c8..e720e32 100644 --- a/test/g1x7.ijs +++ b/test/g1x7.ijs @@ -17,7 +17,7 @@ mkdir d test perm d erase d -f =. <'foogoo5.x' +f =. <(((( |x|y - +x=: j./ _50 + 2 10000 ?@$ 100 +y=: j./ _500 + 2 10000 ?@$ 1000 +*./ (0=x) +. (|x) > |x|y x=: j./ _500 + 2 10000 ?@$ 1000 y=: j./ _5000 + 2 10000 ?@$ 10000 -*./ (0=x) +. (|j.~x) > |x|y +*./ (0=x) +. (|x) > |x|y 'domain error' -: 'abc' | etx 1 2 3 'domain error' -: 'abc' | etx 'feg' diff --git a/test/g331ins.ijs b/test/g331ins.ijs index 81065d0..d29d9d2 100644 --- a/test/g331ins.ijs +++ b/test/g331ins.ijs @@ -1,6 +1,6 @@ NB. f/;.n --------------------------------------------------------------- -sp =: 7!:2 +sp =: 7!:2 spa=: 3 : '7!:5 <''y''' test=: 1 : 0 @@ -21,7 +21,7 @@ test=: 1 : 0 b=: ?(#yy)$2 p=: sp 'b u/;.1 yy' q=: spa b u/;.1 yy - assert. p <: q*IF64{1.5 2 + assert. p <: q*IF64{2.5 2 end. 1 ) @@ -83,7 +83,7 @@ testb=: 3 : 0 a=: ?(#t)$2 p=: sp 'a i b./;.1 t' q=: spa a i b./;.1 t - assert. p <: 1.5*q + assert. p <: 1.5*q end. 1 ) diff --git a/test/g430ov.ijs b/test/g430ov.ijs new file mode 100644 index 0000000..de98391 --- /dev/null +++ b/test/g430ov.ijs @@ -0,0 +1,12 @@ +NB. integer overflow in +/\ +test=: 3 : 0 + yy=: 3$ >IF64{_2147483647;_9223372036854775807 + f=: (3 : '+/y')\ + g=: +/\ + assert. 3(f-:g)yy + 1 +) + +test'' + + 4!:55 ;: 'test yy f g' diff --git a/test/gbpar.ijs b/test/gbpar.ijs index 2927525..01f74b5 100644 --- a/test/gbpar.ijs +++ b/test/gbpar.ijs @@ -101,4 +101,3 @@ s ~: S"1 0 >:i.17 4!:55 ;:'A b c f g I P S s xx yy' - \ No newline at end of file diff --git a/test/gdll.ijs b/test/gdll.ijs index e3c8143..8bfc459 100644 --- a/test/gdll.ijs +++ b/test/gdll.ijs @@ -7,12 +7,12 @@ if. 0=4!:0<'libtsdll' do. 1[lib=: libtsdll return. end. t=. >IF64{'32';'64' s=. >(UNAME-:'Darwin'){'.so';'.dylib' if. IFUNIX do. - lib=: jpath '~home/dev/j/tsdll/libtsdll',t,s + lib=: 'libtsdll',t,s else. if. IF64 do. - lib=: '\dev\j\p_tsdll\release64\tsdll.dll' + lib=: 'tsdll.dll' else. - lib=: '\dev\j\p_tsdll\release\tsdll.dll' + lib=: 'tsdll.dll' end. end. lib=: lib,' ' @@ -74,7 +74,7 @@ NB. l type is same as x on J64 and and error on J32 if. IF64 do. assert. (9;(,9);2;3 4) = 'xbasic l *l l *l' dcd (,2);2;3 4 else. - assert. 'domain error'-: 'xbasic l *l l *l' dcd etx (,2);2;3 4 + assert. 'domain error'-: 'xbasic l *l l *l' dcd etx (,2);2;3 4 assert. 5 0 -: cder '' NB. error 5, result/arg declaration 0 end. ) @@ -145,7 +145,7 @@ td4=: 32$'d i ' (+/>yy)=>{.z=:('d4 d ',td4) dcd yy=:16$12.3;4 xx=:'d5 d d i d i d i d *d *f *x *i' -(+/;yy)=>{.z=: xx dcd yy=:1.1;2;3.3;4;5.5;6;7.7;2.2 3.3;3.3 4.4;23 24;46 47 +(+/;yy)=>{.z=: xx dcd yy=:1.1;2;3.3;4;5.5;6;7.7;2.2 3.3;3.3 4.4;23 24;46 47 tf=: 16$'f ' (<.+/>yy)=<.>{.z=:('f1 f ',tf ) dcd yy=:<"0 [ 1.375*?8#10 @@ -259,7 +259,7 @@ xbasic_add=: ":>{.'xbasic_add x' dcd '' NB. 1 procindex - 0 is objxxx and 1 is objddd obj_add=: <>{.'obj_add x' dcd '' 5 = >{.'objxxx x * x x' dcd obj_add;2;3 -5.75 = >{.'objddd d * d d' dcd obj_add;2.5;3.25 +5.75 = >{.'objddd d * d d' dcd obj_add;2.5;3.25 5 = >{.'1 0 x * x x' cd obj_add;2;3 5.75 = >{.'1 1 d * d d' cd obj_add;2.5;3.25 diff --git a/test/gibst.ijs b/test/gibst.ijs index 95e42b6..fb7cfe4 100644 --- a/test/gibst.ijs +++ b/test/gibst.ijs @@ -3,14 +3,14 @@ NB. i.!.0 and associates timing tests ----------------------------------- L=: 1 : 0 : f=: x&u - assert. (threshold*{.t) <: -/}.t=: 10 timer 'f y','x u y',:'/:x' + assert. (threshold*{.t) <: | -/}.t=: 10 timer 'f y','x u y',:'/:x' 1 ) R=: 1 : 0 : f=: u&y - assert. (threshold*{.t) <: -/}.t=: 10 timer 'f x','x u y',:'/:y' + assert. (threshold*{.t) <: | -/}.t=: 10 timer 'f x','x u y',:'/:y' 1 ) diff --git a/test/giph.ijs b/test/giph.ijs index c0c437a..44d835a 100644 --- a/test/giph.ijs +++ b/test/giph.ijs @@ -1,7 +1,7 @@ NB. prehashed i. family of functions ------------------------------------ g=: 4 : 0 - xx=: y{~(1e4,x) ?@$ #y + xx=: y{~(1e4,x) ?@$ #y yy=: y{~(1e3,x) ?@$ #y ss=: y{~( x) ?@$ #y fidot=: xx&i. @@ -13,11 +13,11 @@ g=: 4 : 0 assert. (fidot ss) -: xx i. ss assert. (fico ss) -: xx i: ss assert. (fedot ss) -: ss e. xx - 1 + 1 ) h=: 4 : 0 - xx=: y{~(1e4,x) ?@$ #y + xx=: y{~(1e4,x) ?@$ #y yy=: y{~(1e3,x) ?@$ #y ss=: y{~( x) ?@$ #y fidot=: xx&(i.!.0) @@ -29,7 +29,7 @@ h=: 4 : 0 assert. (fidot ss) -: xx i. ss assert. (fico ss) -: xx i: ss assert. (fedot ss) -: ss e. xx - 1 + 1 ) '' g 0 1 @@ -113,4 +113,3 @@ f=: x&i. 4!:55 ;:'f fedot fico fidot g h m ss x xx yy' - \ No newline at end of file diff --git a/test/gipht.ijs b/test/gipht.ijs index 79f5389..e530a09 100644 --- a/test/gipht.ijs +++ b/test/gipht.ijs @@ -24,7 +24,7 @@ x f0 0+x=: 1e4 4 ?@$ 1e9 x f0 0+x=: 1e4 ?@$ 0 x f0 0+x=: 1e4 4 ?@$ 0 x f0 0+x=: j./_1e4+2 1e4 ?@$ 2e4 -x f0 0+x=: j./_1e4+2 1e4 4 ?@$ 2e4 +x f0 0+x=: j./_1e4+2 1e4 4 ?@$ 2e4 x f0 0+x=: x: 1e4 ?@$ 3e3 x f0 0+x=: x: 1e4 4 ?@$ 3e3 x f0 0+x=: %/x:0 1+2 1e4 ?@$ 3e3 @@ -60,4 +60,3 @@ f1"0 ]1e1 1e3 1e5 1e7 1e9 4!:55 ;:'f f0 f1 g m mean t x xx y yy' - \ No newline at end of file diff --git a/test/gmbxx.ijs b/test/gmbxx.ijs index c3a4f7a..04a3c8a 100644 --- a/test/gmbxx.ijs +++ b/test/gmbxx.ijs @@ -34,13 +34,13 @@ q=: <'asdf' NB. 3!: ----------------------------------------------------------------- -q=: x=: <"0 (?2 12$2){(<5!:2 <'g'),< i.2 3 +q=: x=: <"0 (?2 12$2){(<5!:2 <'g'),< i.2 3 (mbxcheck_jmf_ q), x -: q (mbxcheck_jmf_ q), q -: 3!:2 (3!:1) q (mbxcheck_jmf_ q), x -: 3!:2 (3!:1) q (mbxcheck_jmf_ q), q -: 3!:2 (3!:3) q (mbxcheck_jmf_ q), x -: 3!:2 (3!:3) q -q=: x=: <"0 <"0 ?2 3 4$1e6 +q=: x=: <"0 <"0 ?2 3 4$1e6 (mbxcheck_jmf_ q), x -: q (mbxcheck_jmf_ q), q -: 3!:2 (3!:1) q (mbxcheck_jmf_ q), x -: 3!:2 (3!:1) q @@ -166,9 +166,9 @@ if. IFUNIX do. lib=: jpath '~home/dev/j/tsdll/libtsdll',t,s else. if. IF64 do. - lib=: '\dev\j\p_tsdll\release64\tsdll.dll' + lib=: 'tsdll.dll' else. - lib=: '\dev\j\p_tsdll\release\tsdll.dll' + lib=: 'tsdll.dll' end. end. lib=: lib,' ' diff --git a/test/test.ijs b/test/test.ijs index ec9a193..0e30d76 100644 --- a/test/test.ijs +++ b/test/test.ijs @@ -5,11 +5,18 @@ NB. see test/tsu.ijs for additional info testpath=: jpath (1!:43''),'/test/' NB. 1!:43 current directory load testpath,'tsu.ijs' +9!:11[6 NB. ensure default print precision 9!:21[1e8 NB. limit error rather than long memory thrash (g400) -threshold=: 0.1 NB. timer threshold failures less likely -libtsdll=: jpath ' ',~(1!:43''),'/libtsdll.',>(UNAME-:'Darwin'){'so';'dylib' - -LOGFILE=: 2 NB. log to console (2) or file (jpath'~temp\log.log') +threshold=: 0]0.1 NB. timer threshold failures less likely +3 : 0'' +if. ((IFWIN{'/tsdll.dll';~'/libtsdll.',>(UNAME-:'Darwin'){'so';'dylib' +end. +) + +LOGFILE=: 2 NB. log to console (2) or file (jpath'~temp/log.log') LOGIT=: 3 : 'y[(>y)1!:2(-.bad)#y' @@ -17,6 +24,14 @@ BAD=: 3 : '>(-.bad)#y' TEST=: (13 : '0!:3 LOGIT y')"0 TESTX=: (13 : '0!:2 LOGIT y')"0 +3 : 0'' +if. ('Android'-:UNAME) do. + if. 0= 'libc.so isatty > i i'&(15!:0) 0 do. + ddall=: ddall -. SNS 'gstack' NB. gstack always crashed in Android jconsoleapp + end. +end. +) + NB. bad=: TEST ddall NB. BAD ddall @@ -27,3 +42,4 @@ NB. TESTX SNS 'g120 gintovfl' NB. see g120 gintovfl details NB. ddt=: ddall -. SNS 'g120 gintovfl' NB. remove crashers NB. bad=: TEST ddt NB. BAD ddt +ddt=: ddall -. SNS 'gstack' NB. remove crashers diff --git a/tsdll.c b/tsdll.c index 0a14cfc..57d66d9 100644 --- a/tsdll.c +++ b/tsdll.c @@ -2,10 +2,17 @@ /* License in license.txt. */ #ifdef _WIN32 #include +#ifdef __MINGW32__ +#ifndef _stdcall +#define _stdcall __stdcall +#define _cdecl __cdecl +#endif +#else int WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) { return TRUE; } +#endif typedef wchar_t wc; #else #define _stdcall @@ -124,7 +131,9 @@ int _cdecl altinci(int i){return ++i;} I _stdcall xbasic_add(){return (I)xbasic;} // '1 procindex ...' +#ifndef __MINGW32__ typedef I (_stdcall *PROC)(); +#endif I _stdcall objxxx(void* obj,I a,I b){return a+b;} D _stdcall objddd(void* obj,D a,D b){return a+b;} //PROC vtable[]={&(PROC)objxxx,&(PROC)objddd}; diff --git a/tsdll.def b/tsdll.def new file mode 100644 index 0000000..c22c1a1 --- /dev/null +++ b/tsdll.def @@ -0,0 +1,42 @@ +LIBRARY tsdll + +EXPORTS + cbasic @4 + wbasic @5 + sbasic @6 + ibasic @7 + xbasic @8 + pc @9 + dipdpd @10 + fipfpf @11 + complex @12 + f @13 + d @14 + dd @15 + ddd @16 + dddd @17 + dx0 @18 + dx1 @19 + dx2 @20 + dx3 @21 + dx4 @22 + dx5 @23 + dx6 @24 + dx7 @25 + d1 @26 + d1a @27 + d2 @28 + d3 @29 + d4 @30 + d5 @31 + f1 @32 + f2 @33 + f3 @34 + fff @35 + fd @36 + altinci @37 + xbasic_add @38 + objxxx @1 + objddd @2 + obj_add @3 + diff --git a/va1.c b/va1.c index de15216..2603084 100644 --- a/va1.c +++ b/va1.c @@ -66,8 +66,8 @@ static A jtva1s(J jt,A w,C id,I cv,VF ado){A e,x,z,ze,zx;B c;C ee;I n,t,zt;P*wp, if(c)RZ(e=cvt(t,x)); n=AN(x); GA(zx,zt,n,AR(x),AS(x)); ado(jt,n, AV(zx),AV(x)); if(jt->jerr){ if(jt->jerr<=NEVM)R 0; - ee=jt->jerr; RZ(ze=va1(e,id)); - jt->jerr=ee; RZ(zx=va1(x,id)); + ee=jt->jerr; RZ(ze=va1(e,id)); + jt->jerr=ee; RZ(zx=va1(x,id)); }else if(cv&VRI+VRD){RZ(ze=cvz(cv,ze)); RZ(zx=cvz(cv,zx));} GA(z,STYPE(AT(ze)),1,AR(w),AS(w)); zp=PAV(z); SPB(zp,a,ca(SPA(wp,a))); @@ -100,7 +100,7 @@ static A jtva1(J jt,A w,C id){A e,z;B b,m;I cv,n,t,wt,zt;P*wp;VA2 p;VF ado; } RESETERR; }else{ - p=((va1tab+(strchr(va1fns,id)-(C*)va1fns))->p1)[wt&B01?0:wt&INT?1:wt&FL?2:wt&CMPX?3:wt&XNUM?4:5]; + p=((va1tab+((C*)strchr(va1fns,id)-(C*)va1fns))->p1)[wt&B01?0:wt&INT?1:wt&FL?2:wt&CMPX?3:wt&XNUM?4:5]; ado=p.f; cv=p.cv; } if(ado==idf)R rat(w); @@ -109,7 +109,7 @@ static A jtva1(J jt,A w,C id){A e,z;B b,m;I cv,n,t,wt,zt;P*wp;VA2 p;VF ado; if(t&&t!=wt)RZ(w=cvt(t,w)); GA(z,zt,n,AR(w),AS(w)); ado(jt,n,AV(z),AV(w)); - if(jt->jerr)R NEVMjerr?va1(w,id):0; + if(jt->jerr)R NEVMjerr?va1(w,id):0; else R cv&VRI+VRD?cvz(cv,z):z; } diff --git a/ve.c b/ve.c index 90b5000..4a2e052 100644 --- a/ve.c +++ b/ve.c @@ -6,7 +6,7 @@ #include "j.h" #include "vasm.h" -#define DIVI(u,v) (u||v ? u/(D)v : 0.0) +#define DIVI(u,v) (u||v ? u/(D)v : 0.0) #define DIVBB(u,v) (v?u:u?inf:0.0) #define TYMESBX(u,v) (u?v:0) @@ -16,7 +16,7 @@ #define TYMESDD(u,v) (u&&v?u*v:0) AOVF( plusII, I,I,I, PLUSVV, PLUS1V, PLUSV1) -AOVF(minusII, I,I,I, MINUSVV,MINUS1V,MINUSV1) +AOVF(minusII, I,I,I, MINUSVV,MINUS1V,MINUSV1) AOVF(tymesII, I,I,I, TYMESVV,TYMES1V,TYMESV1) APFX( plusIO, D,I,I, PLUSO) @@ -33,9 +33,9 @@ AIFX(minusBB, I,B,B, - ) /* minusII */ AIFX(minusBD, D,B,D, AIFX(minusDB, D,D,B, - ) AIFX(minusDI, D,D,I, -) ANAN(minusDD, D,D,D, MINUS) ANAN(minusZZ, Z,Z,Z, zminus) - /* andBB */ APFX(tymesBI, I,B,I, TYMESBX) APFX(tymesBD, D,B,D, TYMESBX) -APFX(tymesIB, I,I,B, TYMESXB) /* tymesII */ APFX(tymesID, D,I,D, TYMESID) -APFX(tymesDB, D,D,B, TYMESXB) APFX(tymesDI, D,D,I, TYMESDI) APFX(tymesDD, D,D,D, TYMESDD) + /* andBB */ APFX(tymesBI, I,B,I, TYMESBX) APFX(tymesBD, D,B,D, TYMESBX) +APFX(tymesIB, I,I,B, TYMESXB) /* tymesII */ APFX(tymesID, D,I,D, TYMESID) +APFX(tymesDB, D,D,B, TYMESXB) APFX(tymesDI, D,D,I, TYMESDI) APFX(tymesDD, D,D,D, TYMESDD) ANAN(tymesZZ, Z,Z,Z, ztymes ) APFX( divBB, D,B,B, DIVBB) APFX( divBI, D,B,I, DIVI) APFX( divBD, D,B,D, DIV) @@ -43,13 +43,13 @@ APFX( divIB, D,I,B, DIVI ) APFX( divII, D,I,I, DIVI) APFX( divID, D,I,D, APFX( divDB, D,D,B, DIVI ) APFX( divDI, D,D,I, DIVI) ANAN( divDD, D,D,D, DIV) ANAN( divZZ, Z,Z,Z, zdiv ) - /* orBB */ APFX( minBI, I,B,I, MIN) APFX( minBD, D,B,D, MIN) -APFX( minIB, I,I,B, MIN) APFX( minII, I,I,I, MIN) APFX( minID, D,I,D, MIN) + /* orBB */ APFX( minBI, I,B,I, MIN) APFX( minBD, D,B,D, MIN) +APFX( minIB, I,I,B, MIN) APFX( minII, I,I,I, MIN) APFX( minID, D,I,D, MIN) APFX( minDB, D,D,B, MIN) APFX( minDI, D,D,I, MIN) APFX( minDD, D,D,D, MIN) APFX( minSS, SB,SB,SB, SBMIN) - /* andBB */ APFX( maxBI, I,B,I, MAX) APFX( maxBD, D,B,D, MAX) -APFX( maxIB, I,I,B, MAX) APFX( maxII, I,I,I, MAX) APFX( maxID, D,I,D, MAX) + /* andBB */ APFX( maxBI, I,B,I, MAX) APFX( maxBD, D,B,D, MAX) +APFX( maxIB, I,I,B, MAX) APFX( maxII, I,I,I, MAX) APFX( maxID, D,I,D, MAX) APFX( maxDB, D,D,B, MAX) APFX( maxDI, D,D,I, MAX) APFX( maxDD, D,D,D, MAX) APFX( maxSS, SB,SB,SB, SBMAX) @@ -68,7 +68,7 @@ ANAN(remZZ, Z,Z,Z, zrem ) static I jtremid(J jt,I a,D b){D r;I k; ASSERT(a&&-9e15jerr=EWOV; R z;}else R 0; } @@ -144,7 +144,7 @@ F2(jtintdiv){A z;B b,flr;I an,ar,*as,*av,c,d,j,k,m,n,p,p1,r,*s,wn,wr,*ws,*wv,*zv an=AN(a); ar=AR(a); as=AS(a); av=AV(a); wn=AN(w); wr=AR(w); ws=AS(w); wv=AV(w); b=ar>=wr; r=b?wr:ar; s=b?as:ws; ASSERT(!ICMP(as,ws,r),EVLENGTH); - if(an&&wn){m=prod(r,s); n=prod(b?ar-r:wr-r,r+s);}else m=n=0; + if(an&&wn){m=prod(r,s); n=prod(b?ar-r:wr-r,r+s);}else m=n=0; GA(z,INT,b?an:wn,b?ar:wr,s); zv=AV(z); d=wn?*wv:0; p=0xmode; if(!wr&&p&&!(p&p1)){ diff --git a/vm.c b/vm.c index b7fc21a..19f1de9 100644 --- a/vm.c +++ b/vm.c @@ -59,39 +59,39 @@ static void jtcirx(J jt,I n,I k,D*z,D*y){D p,t; case -2: DO(n, t=*y++; ASSERTW( -1.0<=t&&t<=1.0, EWIMAG ); *z++=acos(t);); break; case -3: DO(n, *z++=atan(*y++);); break; case -4: DO(n, t=*y++; ASSERTW(t<=-1.0||1.0<=t, EWIMAG ); *z++=t<-1e8||1e8t?-(p+log(-t)):log(t+sqrt(t*t+1.0));); break; - case -6: p=log(2.0); + case -6: p=log(2.0); DO(n, t=*y++; ASSERTW( 1.0<=t, EWIMAG ); *z++=1.0e8xmode==XMEXACT){jt->xmode=XMEXACT; R divide(logar1(w),logar1(a));} - z=rank2ex(cvt(XNUM,a),cvt(XNUM,w),0L,0L,0L,jtxlog2a); + z=rank2ex(cvt(XNUM,a),cvt(XNUM,w),0L,0L,0L,jtxlog2a); if(z)R z; if(jt->jerr==EWIMAG||jt->jerr==EWIRR){RESETERR; jt->xmode=XMEXACT; R divide(logar1(w),logar1(a));} R 0; } - + F2(jtroot){A z;I t; RZ(a&&w); t=maxtype(AT(a),AT(w)); @@ -112,7 +112,7 @@ F2(jtrdot2){R tymes(a,rdot1(w));} F1(jtpolar){RZ(w); R cvt(SPARSE&AT(w)?SFL:FL,df2(v2(10L,12L),w,qq(ds(CCIRCLE),v2(1L,0L))));} F1(jtrect){A e,z;B b;I r,t;P*wp,*zp;Z c; - RZ(w); + RZ(w); t=AT(w); r=AR(w); jt->rank=0; ASSERT(!AN(w)||t&NUMERIC,EVDOMAIN); if(t&CMPX){GA(z,FL,2*AN(w),1+r,AS(w)); *(AS(z)+r)=2; MC(AV(z),AV(w),AN(z)*sizeof(D)); R z;} diff --git a/vz.c b/vz.c index 74b6b97..15f0017 100644 --- a/vz.c +++ b/vz.c @@ -25,7 +25,7 @@ ZS2(jtzminus, zr=a-c; zi=b-d;) ZF1(jtztrend){D a,b,t;Z z; a=v.re; b=v.im; if(ZOV(v)){a/=2; b/=2;} - t=hypoth(a,b); + t=hypoth(a,b); if(tv.re/2)t.re-=v.re; if(t.im>v.im/2)t.im-=v.im; - v.re=u.re; v.im=u.im; u.re=t.re; u.im=t.im; - } + while(ZNZ(u)){t=zrem(u,v); v.re=u.re; v.im=u.im; u.re=t.re; u.im=t.im;} z.re=a=v.re; z.im=b=v.im; switch(2*(0>a)+(0>b)){ case 0: if(!a){z.re= b; z.im=0;} break; @@ -114,8 +111,8 @@ ZF1(jtzexp){D a,b,c,s,t;Z z; a=v.re; b=v.im; if(ac?-t:t;} @@ -167,7 +164,7 @@ ZF1(jtzsqrt){D p,q,t; static ZF1(jtzsin){D a,b,c,s;Z z; a=v.re; b=v.im; ZASSERT(-THMAXv.re ? znegate(zasinh(znegate(v))) : zlog(zplus(v,zp4(v)));} static ZF1(jtzacosh){Z z; - z=zlog(zplus(v,zm4(v))); - if(0>=z.re){z.re=0; z.im=ABS(z.im);} + z=zlog(zplus(v,zm4(v))); + if(0>=z.re){z.re=0; z.im=ABS(z.im);} R z; } @@ -219,7 +216,7 @@ static ZF1(jtzarc){D x,y;Z t,z; z.re=z.im=0; t=ztrend(v); x=t.re; y=t.im; if(0!=x||0!=y)z.re=atan2(y,x); - + #if SY_WINCE_MIPS && !defined(WIN32_PLATFORM_PSPC) if(!y) z.re=x<0?PI : 0; /* atan2(0,v) fails in mips handheld wince - 12 o. _3 */ #endif @@ -253,7 +250,7 @@ B jtztridiag(J jt,I n,A a,A x){I i,j,n1=n-1;Z*av,d,p,*xv; av=ZAV(a); xv=ZAV(x); d=xv[0]; for(i=j=0;ire); y=v->im; if(b=0>y)y=-y; th=y-2*(I)(y/2); k=(I)(2*th); if(k!=2*th)k=-1; else if(b&&k)k=4-k; if(!(0<=k&&k<=3))R expn1(pix(w)); diff --git a/win/jdll.c b/win/jdll.c index c7ba604..68d7c0e 100644 --- a/win/jdll.c +++ b/win/jdll.c @@ -22,13 +22,17 @@ #include #include "../j.h" -#include "../jlib.h" +// #include "../jlib.h" void wtom(US* src, I srcn, UC* snk); int valid(C* psrc, C* psnk); C* esub(J jt, long ec); +#ifdef OLECOM extern int uniflag; +#else +int uniflag= 0; +#endif I jdo(J, C*); @@ -67,7 +71,7 @@ int _stdcall JIsBusy(J jt){ return 0;} //! 64 bit problems - com and dll interface is 32 bit - needs test and thought static int a2v (J jt, A a, VARIANT *v, int dobstrs) { - SAFEARRAY FAR* psa; + SAFEARRAY FAR* psa; SAFEARRAYBOUND rgsabound[MAXRANK]; int er; I i,r,k,t,cb,*pi; @@ -149,13 +153,13 @@ static int a2v (J jt, A a, VARIANT *v, int dobstrs) for(i=0; i= sizeof(gn)) return EVILNAME; - if(valid(name, gn)) return EVILNAME; + if(valid(name, gn)) return EVILNAME; RZ(a=symbrd(nfs(strlen(gn),gn))); old = jt->tbase+jt->ttop; er = a2v (jt, a, v, dobstr); @@ -278,7 +282,7 @@ static A v2a(J jt, VARIANT* v, int dobstrs) for(i=0; iopbstr); - SysReAllocStringLen(&(BSTR)jt->opbstr, 0, (UINT)(len+n+k)); + SysReAllocStringLen((BSTR*)&jt->opbstr, 0, (UINT)(len+n+k)); fixoutput(s, (BSTR)jt->opbstr + len, n); } } @@ -488,7 +492,7 @@ int jsetx(J jt, C* name, VARIANT* v, int dobstrs) // validate name if(strlen(name) >= sizeof(gn)) return EVILNAME; - if(valid(name, gn)) return EVILNAME; + if(valid(name, gn)) return EVILNAME; er=jt->jerr=0; jset (gn, v2a(jt, v,dobstrs)); // no bstrs @@ -510,15 +514,15 @@ int _stdcall JSetB(J jt, C* name, VARIANT* v) int _stdcall JErrorText(J jt, long ec, VARIANT* v) { C* p; - SAFEARRAY FAR* psa; + SAFEARRAY FAR* psa; SAFEARRAYBOUND rgsabound; I cb; p=esub(jt, ec); cb=1+strlen(p); // include null - rgsabound.lLbound = 0; - rgsabound.cElements = (ULONG)cb; - psa = SafeArrayCreate(VT_UI1, 1, &rgsabound); + rgsabound.lLbound = 0; + rgsabound.cElements = (ULONG)cb; + psa = SafeArrayCreate(VT_UI1, 1, &rgsabound); if(!psa) return EVWSFULL; memcpy(psa->pvData, p, cb); v->vt = VT_ARRAY | VT_UI1; @@ -526,7 +530,7 @@ int _stdcall JErrorText(J jt, long ec, VARIANT* v) return 0; } -int _stdcall JClear(J jt){ return 0;}; +int _stdcall JClear(J jt){ return 0;} int _stdcall JTranspose(J jt, long b) { @@ -559,7 +563,7 @@ int _stdcall JDoR(J jt, C* p, VARIANT* v) v->bstrVal=jt->opbstr; R e; } -#endif wince +#endif // previously in separate file when jdll.c and jcom.c both exisited char modulepath[_MAX_PATH]; @@ -629,7 +633,7 @@ int WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) if(s.wYear != 2000 || 11 #include +#ifdef __MINGW32__ +#ifndef _stdcall +#define _stdcall __stdcall +#define _cdecl __cdecl +#endif +#endif #else #include typedef unsigned char BYTE; @@ -52,7 +58,7 @@ typedef unsigned char BYTE; #include "j.h" -#define SY_UNIX64 (SY_64 && (SY_LINUX || SY_MAC || SY_FREEBSD)) +#define SY_UNIX64 (SY_64 && (!defined(__arm__)||defined(__mips__)) && (SY_LINUX || SY_MAC || SY_FREEBSD)) #if SY_WINCE #define HINSTANCE_ERROR 0 @@ -87,8 +93,8 @@ char *toascbuf(wchar_t *src); typedef void *HMODULE; typedef char *LPSTR; typedef I (*FARPROC)(); -#define __stdcall -#define _cdecl +#define __stdcall +#define _cdecl #endif @@ -102,15 +108,15 @@ typedef I (_cdecl *ALTCALLI)(); typedef D (__stdcall *STDCALLD)(); typedef D (_cdecl *ALTCALLD)(); -#if SY_64 /* J64 requires special float result */ +#if SY_64 || defined(__arm__) /* J64 requires special float result */ typedef float (__stdcall *STDCALLF)(); typedef float (_cdecl *ALTCALLF)(); -#endif +#endif /* error return codes */ #define DEOK 0 #define DEBADLIB 1 -#define DEBADFN 2 +#define DEBADFN 2 #define DETOOMANY 3 /* too many dlls loaded */ #define DECOUNT 4 /* too many args or (#args)~:#parms */ #define DEDEC 5 @@ -180,7 +186,7 @@ static void double_trick(double*v, I n){I i=0; #define dtrick double_trick(dd,dcnt); #elif SY_64 && SY_WIN32 #define dtrick {D*pd=(D*)d; double_trick(pd[0],pd[1],pd[2],pd[3]);} -#elif SY_64 && SY_LINUX +#elif SY_64 && SY_LINUX #define dtrick double_trick(dd[0],dd[1],dd[2],dd[3],dd[4],dd[5],dd[6],dd[7]); #elif 1 #define dtrick ; @@ -313,7 +319,7 @@ static D altcalld(ALTCALLD fp,I*d,I cnt,D*dd,I dcnt){D r; R r; } -#if SY_64 +#if SY_64 || defined(__arm__) static float stdcallf(STDCALLF fp,I*d,I cnt,D*dd,I dcnt){float r; SWITCHCALL; R r; @@ -345,7 +351,7 @@ static void docall(FARPROC fp, I*d, I cnt, D* dd, I dcnt, C zl, I*v, B alternate case 'n': *v=0; break; }} else -#if !SY_64 +#if !SY_64 && !defined(__arm__) {D r; r= alternate ? altcalld((ALTCALLD)fp,d,cnt,dd,dcnt) : stdcalld((STDCALLD)fp,d,cnt,dd,dcnt); *(D*)v=r; @@ -418,7 +424,7 @@ static CCT*jtcdlookup(J jt,A a){C*s;CCT*pv;I an,hn,*hv,j,k;UC*av; static HMODULE jtcdlookupl(J jt,C*av){C*s;CCT*pv;I an,hn,*hv,j,k; hn=AN(jt->cdhashl); hv=AV(jt->cdhashl); pv=(CCT*)AV(jt->cdarg); s=CAV(jt->cdstr); - an=strlen(av); j=hic(an,av)%hn; + an=strlen(av); j=hic(an,av)%hn; while(0<=(k=hv[j])){if(an==pv[k].ln&&!memcmp(av,s+pv[k].li,an))R pv[k].h; j=(j+1)%hn;} R 0; } @@ -431,7 +437,7 @@ static CCT*jtcdinsert(J jt,A a,CCT*cc){A x;C*s;CCT*pv,*z;I an,hn,*hv,j,k; cc->ai=jt->cdns; MC(s+jt->cdns,CAV(a),an); jt->cdns+=an; z=pv+jt->cdna; MC(z,cc,sizeof(CCT)); k=jt->cdna++; if(AN(jt->cdhash)<=2*jt->cdna){k=0; RZ(x=cdgahash(2*jt->cdna)); fa(jt->cdhash); jt->cdhash=x;} - hv=AV(jt->cdhash); hn=AN(jt->cdhash); + hv=AV(jt->cdhash); hn=AN(jt->cdhash); DO(jt->cdna-k, j=hic(pv[k].an,s+pv[k].ai)%hn; while(0<=hv[j])j=(j+1)%hn; hv[j]=k; ++k;); R z; } @@ -468,7 +474,7 @@ static CCT*jtcdload(J jt,CCT*cc,C*lib,C*proc){B ha=0;FARPROC f;HMODULE h; cc->h=h; ha=1; } #if SY_WIN32 && !SY_WINCE - f=GetProcAddress(h,'#'==*proc?(LPCSTR)(I)atoi(proc+1):proc); + f=GetProcAddress(h,'#'==*proc?(LPCSTR)(I)atoi(proc+1):proc); #endif #if SY_WINCE f=GetProcAddress(h,tounibuf(proc)); @@ -481,7 +487,7 @@ static CCT*jtcdload(J jt,CCT*cc,C*lib,C*proc){B ha=0;FARPROC f;HMODULE h; /* assumes the hash table for libraries (jt->cdhashl) is fixed sized */ /* assumes cc will be cached as entry number jt->cdna */ if(ha){I hn,*hv,j; - ++jt->cdnl; hv=AV(jt->cdhashl); hn=AN(jt->cdhashl); + ++jt->cdnl; hv=AV(jt->cdhashl); hn=AN(jt->cdhashl); j=hic(cc->ln,lib)%hn; while(0<=hv[j])j=(j+1)%hn; hv[j]=jt->cdna; } R cc; @@ -524,14 +530,14 @@ static CCT*jtcdparse(J jt,A a){C c,lib[NPATH],*p,proc[NPATH],*s,*s0;CCT*cc,cct;I ASSERT(1>=AR(a),EVRANK); ASSERT(NLEFTARG>=AN(a),EVLIMIT); if(cc=cdlookup(a))R cc; - cc=&cct; cc->an=an=AN(a); s=s0=CAV(a); + cc=&cct; cc->an=an=AN(a); s=s0=CAV(a); /* library (module, file) name */ while(*s==' ')++s; p=*s=='"'?strchr(++s,'"'):strchr(s,' '); li=s-s0; cc->ln=p?p-s:0; CDASSERT(p&&NPATH>cc->ln,DEBADLIB); cc->cc=1==cc->ln&&('0'==*s||'1'==*s)?*s:0; /* procedure name */ - s=p+1+(*p=='"'); - while(*s==' ')++s; p=strchr(s,' '); if(!p)p=s+strlen(s); pi=s-s0; cc->pn=p-s; + s=p+1+(*p=='"'); + while(*s==' ')++s; p=strchr(s,' '); if(!p)p=s+strlen(s); pi=s-s0; cc->pn=p-s; CDASSERT(NPATH>cc->pn,DEBADFN); /* > + % */ s=p+1; @@ -584,7 +590,7 @@ static I*jtconvert0(J jt,I zt,I*v,I wt,C*u){D p,q;I k=0;S s; case CDT(INT,INT): * v=*(I*)u; break; case CDT(INT,FL ): p=*(D*)u; q=jfloor(p); - if(pfuzz)||IMAX*(1+jt->fuzz)fuzz)||IMAX*(1+jt->fuzz)q?IMIN:IMAX;} else if(++q,FEQ(p,q)){k=(I)q; *v=SGN(k)==SGN(q)?k:0>q?IMIN:IMAX;} @@ -594,12 +600,12 @@ static I*jtconvert0(J jt,I zt,I*v,I wt,C*u){D p,q;I k=0;S s; #endif } R v; -} /* convert a single atom. I from D code adapted from IfromD() in k.c */ +} /* convert a single atom. I from D code adapted from IfromD() in k.c */ static B jtcdexec1(J jt,CCT*cc,C*zv0,C*wu,I wk,I wt,I wd){A*wv=(A*)wu,x,y,*zv;B zbx,lit,star; C c,cipt[NCDARGS],*u;FARPROC fp;float f;I cipcount=0,cipn[NCDARGS],*cipv[NCDARGS],cv0[2], data[NCDARGS*2],dcnt=0,*dv,i,n,per,t,xn,xr,xt,*xv; D dd[NCDARGS]; - n=cc->n; + n=cc->n; CDASSERT(!n||wt&BOX||!(u=memchr(cc->star,C1,n)),DEPARM+256*(u-cc->star)); zbx=cc->zbx; zv=1+(A*)zv0; dv=data; u=wu; xr=0; for(i=0;izt,1,0,0); xv=AV(x); *(A*)zv0=x;}else xv=(I*)zv0; if('1'==cc->cc){fp=(FARPROC)*((I)cc->fp+(I*)*(I*)*data); CDASSERT(fp,DEBADFN);}else fp=cc->fp; docall(fp, data, dv-data, dd, dcnt, cc->zl, xv, cc->alternate); - + DO(cipcount, convertup(cipv[i],cipn[i],cipt[i]);); /* convert s and int to I and f to d as required */ #if SY_WIN32 t= GetLastError(); @@ -685,15 +694,15 @@ F2(jtcd){A z;C*tv,*wv,*zv;CCT*cc;I k,m,n,p,q,t,wd,wr,*ws,wt; if(1n; + RZ(cc=cdparse(a)); + n=cc->n; CDASSERT(n==(wr?ws[wr-1]:1),DECOUNT); if(cc->zbx){GA(z,BOX,m*(1+n),MAX(1,wr),ws); *(AS(z)+AR(z)-1)=1+n;} else{CDASSERT('*'!=cc->zl,DEDEC); GA(z,cc->zt,m,MAX(0,wr-1),ws);} if(m&&n&&!(wt&BOX)){ t=0; tv=cc->tletter; DO(n, k=cdjtype(*tv++); t=MAX(t,k);); CDASSERT(HOMO(t,wt),DEPARM); - if(!(wt&B01+INT+FL+LIT+C2T))RZ(w=cvt(wt=t,w)); + if(!(wt&B01+INT+FL+LIT+C2T))RZ(w=cvt(wt=t,w)); } wv=CAV(w); zv=CAV(z); k=bp(wt); wd=(I)w*ARELATIVE(w); if(1==m)RZ(cdexec1(cc,zv,wv,k,wt,wd)) @@ -731,7 +740,7 @@ F1(jtcderx){I t;C buf[1024]; ASSERTMTV(w); t=jt->getlasterror; jt->getlasterror=0; #if SY_WIN32 && !SY_WINCE - FormatMessage( + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)t, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), /* Default language */ @@ -741,7 +750,7 @@ F1(jtcderx){I t;C buf[1024]; #if SY_WINCE { WCHAR wbuf[1024]; - FormatMessage( + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)t, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), /* Default language */ @@ -861,7 +870,7 @@ I static CALLBACK cbx8(I a,I b,I c,I d,I e,I f,I g,I h){cbxn=8;cbx[0]=a;cbx[1]=b I static CALLBACK cbx9(I a,I b,I c,I d,I e,I f,I g,I h,I i){cbxn=9;cbx[0]=a;cbx[1]=b;cbx[2]=c;cbx[3]=d;cbx[4]=e;cbx[5]=f;cbx[6]=g;cbx[7]=h;cbx[8]=i;R cbnew();} I static cbvx[]={(I)&cbx0,(I)&cbx1,(I)&cbx2,(I)&cbx3,(I)&cbx4,(I)&cbx5,(I)&cbx6,(I)&cbx7,(I)&cbx8,(I)&cbx9}; -#if SY_WIN32 +#if SY_WIN32 I static _cdecl cbxalt0(){cbxn=0;R cbnew();} I static _cdecl cbxalt1(I a){cbxn=1;cbx[0]=a;R cbnew();} I static _cdecl cbxalt2(I a,I b){cbxn=2;cbx[0]=a;cbx[1]=b;R cbnew();} diff --git a/xd.c b/xd.c index 04fd752..21fde42 100644 --- a/xd.c +++ b/xd.c @@ -6,6 +6,8 @@ #ifdef _WIN32 #include #include +#else +#include #endif #include "j.h" @@ -48,7 +50,7 @@ char *toascbuf(wchar_t *src) #define _A_SUBDIR FILE_ATTRIBUTE_DIRECTORY #define _A_ARCH FILE_ATTRIBUTE_ARCHIVE -#endif +#endif #if (SYS & SYS_DOS) @@ -86,7 +88,7 @@ static A jtattv(J jt,U x){A z;C*s; } /* convert from 16-bit attributes x into 6-element string */ static S jtattu(J jt,A w){C*s;I i,n;S z=0; - RZ(w=vs(w)); + RZ(w=vs(w)); n=AN(w); s=CAV(w); for(i=0;idwFileAttributes & FILE_ATTRIBUTE_READONLY ?'-':'w'; rwx[2]=strcmp(t,"exe")&&strcmp(t,"bat")&&strcmp(t,"com")?'-':'x'; GA(z,BOX,5,1,0); zv=AAV(z); - RZ(zv[0]=str(n,s)); + RZ(zv[0]=str(n,s)); RZ(zv[1]=vec(INT,6L,ts)); #if SY_64 RZ(zv[2]=sc(((I)f->nFileSizeHigh<<32) + (I)f->nFileSizeLow)); #else - RZ(zv[2]=sc( (f->nFileSizeHigh || 0>(I)f->nFileSizeLow)?-1:f->nFileSizeLow )); + RZ(zv[2]=sc( (f->nFileSizeHigh || 0>(I)f->nFileSizeLow)?-1:f->nFileSizeLow )); #endif RZ(zv[3]=str(3L,rwx)); RZ(zv[4]=attv((S)f->dwFileAttributes)); @@ -214,7 +216,7 @@ F1(jtjdir){PROLOG;A z,fn,*zv;I j=0,n=32;HANDLE fh; WIN32_FIND_DATAW f; C fnbuffe name = fnbuffer; if(strcmp(name,".")&&strcmp(name,"..")){ if(j==n){RZ(z=ext(0,z)); n=AN(z); zv=AAV(z);} - RZ(zv[j++]=jtdir1(jt,&f,fnbuffer)); + RZ(zv[j++]=jtdir1(jt,&f,fnbuffer)); } } while (FindNextFileW(fh,&f)); FindClose(fh); @@ -229,7 +231,7 @@ F1(jtjfatt1){A y,fn;F f;U x; RZ(fn=toutf16x(y)); x=GetFileAttributesW(USAV(fn)); if(-1!=x) R attv(x); - jsignal(EVFNAME); R 0; + jsignal(EVFNAME); R 0; } F2(jtjfatt2){A y,fn;F f;U x; @@ -260,11 +262,14 @@ F2(jtjfatt2){A y,fn;F f;U x; #include #endif +#if !defined(S_IFSOCK) && defined(__S_IFSOCK) +#define S_IFSOCK __S_IFSOCK +#endif /* Return mode_t formatted into a static 10-character buffer. */ static C*modebuf(mode_t m){C c;static C b[11];I t=m; strcpy(b+1,"rwxrwxrwx"); - DO(9, if(!(m&1))b[9-i]='-'; m>>=1;); + DO(9, if(!(m&1))b[9-i]='-'; m>>=1;); if(t&S_ISUID)b[3]=(b[3]=='x')?'s':'S'; if(t&S_ISGID)b[6]=(b[6]=='x')?'s':'S'; if(t&S_ISVTX)b[9]=(b[9]=='x')?'t':'T'; @@ -283,18 +288,21 @@ static C*modebuf(mode_t m){C c;static C b[11];I t=m; R b; } -/* +/* linux32 stat fails on big files - so it uses stat64 but can't get it to work with struct stat64 so struct stat is used (wrong, but seems to work) */ +/* +replace the following lines by using compilation flag -D_FILE_OFFSET_BITS=64 #if SYS & SYS_LINUX #define stat stat64 #endif +*/ + - -static int ismatch(J jt,C*pat,C*name){ +static int ismatch(J jt,C*pat,C*name){ strcpy(jt->dirbase,name); if(stat(jt->dirnamebuf,&jt->dirstatbuf))R 0; if('.'!=*pat && ((!strcmp(name,"."))||(!strcmp(name,".."))))R 0; if(fnmatch(pat,name,0)) R 0; @@ -316,7 +324,7 @@ static A jtdir1(J jt,struct dirent*f){A z,*zv;C*s,att[16];I n,ts[6],i,m,sz;S x;s ts[3]=tm->tm_hour; ts[4]=tm->tm_min; ts[5]=tm->tm_sec; s=f->d_name; n=strlen(s); GA(z,BOX,6,1,0); zv=AAV(z); - RZ(zv[0]=vec(LIT,n,s)); + RZ(zv[0]=vec(LIT,n,s)); RZ(zv[1]=vec(INT,6L,ts)); sz=jt->dirstatbuf.st_size; sz=sz<0?-1:sz; @@ -342,7 +350,7 @@ F1(jtjdir){PROLOG;A*v,z,*zv;C*dir,*pat,*s,*x;I j=0,n=32;DIR*DP;struct dirent *f; while(f){ if(ismatch(jt,pat,f->d_name)){ if(j==n){RZ(z=ext(0,z)); n=AN(z); zv=AAV(z);} - RZ(zv[j++]=dir1(f)); + RZ(zv[j++]=dir1(f)); } f=readdir(DP); } diff --git a/xf.c b/xf.c index b0add26..26a46d3 100644 --- a/xf.c +++ b/xf.c @@ -10,15 +10,21 @@ #include #endif -#include "j.h" -#include "x.h" - #if !SY_WIN32 && (SYS & SYS_DOS) #include #endif -#if (SYS & SYS_UNIX) + +#include "j.h" +#if (SYS & SYS_UNIX) || defined(__MINGW32__) #include +#ifdef ANDROID +#ifdef link +#undef link +#endif +#endif +#include +//#include typedef long long INT64; #endif @@ -27,12 +33,14 @@ typedef long long INT64; #include #endif +#include "x.h" + #if SY_64 static I fsize(F f){fpos_t z; RZ(f); -#if SY_WIN32 - _lseeki64(_fileno(f),0,SEEK_END); +#if SY_WIN32 && !defined(__MINGW32__) + _lseeki64(_fileno(f),0,SEEK_END); #else fseek(f,0L,SEEK_END); #endif @@ -85,10 +93,10 @@ static B jtwa(J jt,F f,I j,A w){C*x;I n,p=0;size_t q=1; #else fseek(f,(long)(0>j?1+j:j),0>j?SEEK_END:SEEK_SET); #endif - + clearerr(f); while(q&&n>p){ - p+=q=fwrite(p+x,sizeof(C),(size_t)(n-p),f); + p+=q=fwrite(p+x,sizeof(C),(size_t)(n-p),f); if(ferror(f))R jerrno()?1:0; } R 1; @@ -99,7 +107,7 @@ F1(jtjfread){A z;F f; F1RANK(0,jtjfread,0); RE(f=stdf(w)); if(f)R 1==(I)f?jgets("\001"):3==(I)f?rdns(stdin):rd(vfn(f),0L,-1L); - RZ(f=jope(w,FREAD)); z=rd(f,0L,-1L); fclose(f); + RZ(f=jope(w,FREAD)); z=rd(f,0L,-1L); fclose(f); R z; } @@ -110,8 +118,8 @@ F2(jtjfwrite){B b;F f; if(2==(I)f){b=jt->tostdout; jt->tostdout=1; jt->mtyo=MTYOFILE; jpr(a); jt->mtyo=0; jt->tostdout=b; R a;} if(4==(I)f){R (U)AN(a)!=fwrite(CAV(a),sizeof(C),AN(a),stdout)?jerrno():a;} if(5==(I)f){R (U)AN(a)!=fwrite(CAV(a),sizeof(C),AN(a),stderr)?jerrno():a;} - if(b=!f)RZ(f=jope(w,FWRITE)) else RE(vfn(f)); - wa(f,0L,a); + if(b=!f)RZ(f=jope(w,FWRITE)) else RE(vfn(f)); + wa(f,0L,a); if(b)fclose(f);else fflush(f); RNE(mtm); } @@ -131,8 +139,8 @@ F2(jtjfappend){B b;F f; F1(jtjfsize){B b;F f;I m; F1RANK(0,jtjfsize,0); RE(f=stdf(w)); - if(b=!f)RZ(f=jope(w,FREAD)) else RE(vfn(f)); - m=fsize(f); + if(b=!f)RZ(f=jope(w,FREAD)) else RE(vfn(f)); + m=fsize(f); if(b)fclose(f);else fflush(f); RNE(sc(m)); } @@ -142,7 +150,7 @@ static F jtixf(J jt,A w){F f; switch(AT(w)){ default: ASSERT(0,EVDOMAIN); case B01: ASSERT(0,EVFNUM); - case BOX: ASSERT(2==AN(w),EVLENGTH); f=stdf(head(w)); break; + case BOX: ASSERT(2==AN(w),EVLENGTH); f=stdf(head(w)); break; case INT: f=(F)*AV(w); ASSERT(2<(UI)f,EVFNUM); } R f?vfn(f):f; @@ -172,7 +180,7 @@ F2(jtjiwrite){B b;F f;I i; ASSERT(!AN(a)||AT(a)&LIT+C2T,EVDOMAIN); ASSERT(1>=AR(a),EVRANK); RE(f=ixf(w)); if(b=!f)RZ(f=jope(w,FUPDATE)); - if(ixin(w,fsize(f),&i,0L))wa(f,i,a); + if(ixin(w,fsize(f),&i,0L))wa(f,i,a); if(b)fclose(f);else fflush(f); RNE(mtm); } @@ -305,7 +313,7 @@ F1(jtjgetpid){ #if (SYS & SYS_UNIX) F1(jtpathdll){ ASSERTMTV(w); R cstr(""); -} +} #else F1(jtpathdll){char p[MAX_PATH]; extern C dllpath[]; ASSERTMTV(w); diff --git a/xh.c b/xh.c index b70fd83..c138f55 100644 --- a/xh.c +++ b/xh.c @@ -8,6 +8,7 @@ #include #else #include +#include #endif #include "j.h" @@ -37,7 +38,17 @@ F1(jthost){A z; n=AN(w); GA(t,LIT,n+5+L_tmpnam,1,0); s=CAV(t); fn=5+n+s; MC(s,AV(w),n); - MC(n+s," > ",5L); {C* t=tmpnam(fn);} + #ifdef ANDROID + const char*ftmp=getenv("TMP"); + ASSERT(ftmp!=NULL,EVFACE); + strcpy(fn,ftmp); + char atmp[L_tmpnam]; + {C* t=tmpnam(atmp); } + strcat(fn,atmp+4); + #else + {C* t=tmpnam(fn); } + #endif + MC(n+s," > ",5L); b=!system(s); if(b){f=fopen(fn,FREAD); z=rd(f,0L,-1L); fclose(f);} unlink(fn); @@ -47,6 +58,7 @@ F1(jthost){A z; R z; } +#ifndef ANDROID F1(jthostne){C*s; F1RANK(1,jthostne,0); RZ(w=vs(w)); @@ -57,7 +69,7 @@ F1(jthostne){C*s; { I b; b=system(s); -#if !SY_64 && (SYS&SYS_LINUX) +#if !SY_64 && (SYS&SYS_LINUX) && !ANDROID //Java-jnative-j.so system always returns -1 if(jt->sm==SMJAVA&&-1==b) b=-1==system("")?0:-1; #endif @@ -68,6 +80,8 @@ F1(jthostne){C*s; R mtv; } + +#endif #endif @@ -80,6 +94,12 @@ F1(jtjwait ){ASSERT(0,EVDOMAIN);} #define CL(f) {close(f[0]);close(f[1]);} +#ifdef ANDROID +#define HOST_SHELL "/system/bin/sh" +#else +#define HOST_SHELL "/bin/sh" +#endif + F1(jthostio){C*s;A z;F*pz;I fi[2],fo[2],r;int fii[2],foi[2]; fii[0]=fi[0];fii[1]=fi[1];foi[0]=fo[0];foi[1]=fo[1]; F1RANK(1,jthostio,0); @@ -90,10 +110,11 @@ F1(jthostio){C*s;A z;F*pz;I fi[2],fo[2],r;int fii[2],foi[2]; if(pz[1])fclose(pz[1]); CL(fi);CL(fo);} if(!add2(pz[1],pz[2],s)){fclose(pz[1]);fclose(pz[2]); CL(fi);CL(fo);} + switch(r=fork()){ case -1:CL(fi);CL(fo);ASSERT(0,EVFACE); case 0:close(0);{int i=dup(fo[0]);};close(1);{int i=dup(fi[1]);};CL(fi);CL(fo); - execl("/bin/sh","/bin/sh","-c",s,NULL); exit(-1); + execl(HOST_SHELL,HOST_SHELL,"-c",s,NULL); exit(-1); }close(fo[0]);close(fi[1]); add2(NULL,NULL,NULL); pz[0]=(F)r; R z; diff --git a/xl.c b/xl.c index 59b86dc..d496dd8 100644 --- a/xl.c +++ b/xl.c @@ -25,7 +25,11 @@ static B jtdolock(J jt,B lk,F f,I i,I n){I e;long c;fpos_t v; fpos_t q; if(0!=c)R (B)jerrno(); e=_locking(_fileno(f),lk?_LK_NBLCK:_LK_UNLCK,(long)n); fsetpos(f,(fpos_t*)&q); +#ifdef __MINGW32__ + R !e?1:((errno==ENOENT)||(errno==EACCES))?0:(B)jerrno(); +#else R !e?1:errno==EACCES?0:(B)jerrno(); +#endif } #endif @@ -39,7 +43,7 @@ static B jtdolock(J jt,B lk,F f,I i,I n){I e; #define LKC 3 /* number of columns in jt->flkd table */ B jtxlinit(J jt){A x;I*s; - GA(x,INT,20*LKC,2,0); s=AS(x); s[0]=20; s[1]=LKC; ra(x); + GA(x,INT,20*LKC,2,0); s=AS(x); s[0]=20; s[1]=LKC; ra(x); jt->flkd=x; R 1; } @@ -49,9 +53,9 @@ F1(jtjlocks){A y; ASSERTMTV(w); y=take(sc(jt->flkn),jt->flkd); R grade2(y,y);} F1(jtjlock){B b;I*v; F1RANK(1,jtjlock,0); - RZ(w=vi(w)); + RZ(w=vi(w)); ASSERT(LKC==AN(w),EVLENGTH); - v=AV(w); RE(vfn((F)*v)); ASSERT(0<=v[1]&&0<=v[2],EVDOMAIN); + v=AV(w); RE(vfn((F)*v)); ASSERT(0<=v[1]&&0<=v[2],EVDOMAIN); if(jt->flkn==*AS(jt->flkd))RZ(jt->flkd=ext(1,jt->flkd)); RE(b=dolock(1,(F)v[0],v[1],v[2])); if(!b)R zero; @@ -65,18 +69,18 @@ static A jtunlj(J jt,I j){B b;I*u,*v; u=AV(jt->flkd); v=u+j*LKC; RE(b=dolock(0,(F)v[0],v[1],v[2])); if(!b)R zero; - --jt->flkn; - if(jflkn)ICPY(v,u+jt->flkn*LKC,LKC); else *v=0; + --jt->flkn; + if(jflkn)ICPY(v,u+jt->flkn*LKC,LKC); else *v=0; R one; } /* unlock the j-th entry in jt->flkd */ -B jtunlk(J jt,I x){I j=0,*v=AV(jt->flkd); - while(jflkn){while(x==*v)RZ(unlj(j)); ++j; v+=LKC;} +B jtunlk(J jt,I x){I j=0,*v=AV(jt->flkd); + while(jflkn){while(x==*v)RZ(unlj(j)); ++j; v+=LKC;} R 1; } /* unlock all existing locks for file# x */ F1(jtjunlock){ - F1RANK(1,jtjunlock,0); - ASSERT(INT&AT(w),EVDOMAIN); - R unlj(i0(indexof(jt->flkd,w))); + F1RANK(1,jtjunlock,0); + ASSERT(INT&AT(w),EVDOMAIN); + R unlj(i0(indexof(jt->flkd,w))); } /* w is (number,index,length); unlock the specified region */ diff --git a/xt.c b/xt.c index 72b7d54..cb82cf8 100644 --- a/xt.c +++ b/xt.c @@ -8,10 +8,22 @@ #include #endif + #include "j.h" #if !SY_WINCE && (SY_WIN32 || (SYS & SYS_LINUX)) #include +#if (SYS & SYS_LINUX) +#include + +#ifdef ANDROID +#ifdef link +#undef link +#endif +#endif + +#include +#endif #else #if (SY_GETTOD && !(SYS&SYS_IBMRS6000)) #include @@ -22,6 +34,7 @@ #include #endif + #ifndef CLOCKS_PER_SEC #if (SYS & SYS_UNIX) #define CLOCKS_PER_SEC 1000000 @@ -34,8 +47,8 @@ F1(jtsp){ASSERTMTV(w); R sc(jt->bytes);} -F1(jtspit){A z;I k; - F1RANK(1,jtspit,0); +F1(jtspit){A z;I k; + F1RANK(1,jtspit,0); jt->bytesmax=k=jt->bytes; FDEPINC(1); z=exec1(w); FDEPDEC(1); RZ(z); @@ -110,11 +123,11 @@ static D qpc(void){R tod()*CLOCKS_PER_SEC;} #endif -/* +/* // by Mark VanTassel from The Code Project __int64 GetMachineCycleCount() -{ +{ __int64 cycles; _asm rdtsc; // won't work on 486 or below - only pentium or above _asm lea ebx,cycles; @@ -131,8 +144,8 @@ F2(jttsit2){A z;D t;I n,old; F2RANK(0,1,jttsit2,0); RE(n=i0(a)); FDEPINC(1); - t=qpc(); - old=jt->tbase+jt->ttop; DO(n, z=exec1(w); if(!z)break; tpop(old);); + t=qpc(); + old=jt->tbase+jt->ttop; DO(n, z=exec1(w); if(!z)break; tpop(old);); t=qpc()-t; FDEPDEC(1); RZ(z); @@ -170,15 +183,15 @@ F1(jtpmctr){D x;I q; ASSERT(jt->pma,EVDOMAIN); x=q+(D)jt->pmctr; ASSERT(IMIN<=x&&x<=IMAX,EVDOMAIN); - jt->pmctr=q=(I)x; + jt->pmctr=q=(I)x; R sc(q); } /* add w to pmctr */ static F1(jtpmfree){A x,y;C*c;I m;PM*v;PM0*u; if(w){ - c=CAV(w); u=(PM0*)c; v=(PM*)(c+sizeof(PM0)); - m=u->wrapped?u->n:u->i; - DO(m, x=v->name; if(x&&NAME==AT(x)&&AN(x)==*AS(x))fa(x); + c=CAV(w); u=(PM0*)c; v=(PM*)(c+sizeof(PM0)); + m=u->wrapped?u->n:u->i; + DO(m, x=v->name; if(x&&NAME==AT(x)&&AN(x)==*AS(x))fa(x); y=v->loc; if(y&&NAME==AT(y)&&AN(y)==*AS(y))fa(y); ++v;); fa(w); } @@ -190,11 +203,11 @@ F1(jtpmarea1){R pmarea2(vec(B01,2L,&zeroZ),w);} F2(jtpmarea2){A x;B a0,a1,*av;C*v;I an,n=0,s=sizeof(PM),s0=sizeof(PM0),wn;PM0*u; RZ(a&&w); ASSERT(prokey, EVDOMAIN); - RZ(a=cvt(B01,a)); + RZ(a=cvt(B01,a)); an=AN(a); ASSERT(1>=AR(a),EVRANK); ASSERT(2>=an,EVLENGTH); - av=BAV(a); + av=BAV(a); a0=0pmu=u=(PM0*)v; - jt->pmv=(PM*)(s0+v); + jt->pmu=u=(PM0*)v; + jt->pmv=(PM*)(s0+v); jt->pmrec=u->rec=a0; - u->n=n=(wn-s0)/s; + u->n=n=(wn-s0)/s; u->i=0; u->s=jt->bytesmax=jt->bytes; - u->trunc=a1; + u->trunc=a1; u->wrapped=0; } R sc(n); @@ -246,14 +259,14 @@ F1(jtpmunpack){A*au,*av,c,t,x,z,*zv;B*b;D*dv;I*iv,k,m,n,p,q,wn,*wv;PM*v,*v0,*vq; GA(x,B01,n,1,0); b=BAV(x); memset(b,wn?C0:C1,n); if(wn){ DO(wn, k=wv[i]; if(0>k)k+=n; ASSERT(0<=k&&kpmv; vq=q+v0; GA(z,BOX,1+PMCOL,1,0); zv=AAV(z); GA(t,BOX,2*m,1,0); av=AAV(t); au=m+av; - v=vq; DO(p, if(b[ i]){RZ(*av++=v->name?sfn(0,v->name):mtv); RZ(*au++=v->loc?sfn(0,v->loc):mtv);} ++v;); - v=v0; DO(q, if(b[p+i]){RZ(*av++=v->name?sfn(0,v->name):mtv); RZ(*au++=v->loc?sfn(0,v->loc):mtv);} ++v;); + v=vq; DO(p, if(b[ i]){RZ(*av++=v->name?sfn(0,v->name):mtv); RZ(*au++=v->loc?sfn(0,v->loc):mtv);} ++v;); + v=v0; DO(q, if(b[p+i]){RZ(*av++=v->name?sfn(0,v->name):mtv); RZ(*au++=v->loc?sfn(0,v->loc):mtv);} ++v;); RZ(x=indexof(t,t)); RZ(c=eq(x,IX(IC(x)))); RZ(zv[6]=repeat(c,t)); @@ -262,14 +275,14 @@ F1(jtpmunpack){A*au,*av,c,t,x,z,*zv;B*b;D*dv;I*iv,k,m,n,p,q,wn,*wv;PM*v,*v0,*vq; RZ(zv[1]=vec(INT,m,m+iv)); GA(t,INT,m,1,0); zv[2]=t; iv=AV(t); v=vq; DO(p, if(b[i])*iv++=(I)v->val; ++v;); v=v0; DO(q, if(b[p+i])*iv++=(I)v->val; ++v;); GA(t,INT,m,1,0); zv[3]=t; iv=AV(t); v=vq; DO(p, if(b[i])*iv++=v->lc; ++v;); v=v0; DO(q, if(b[p+i])*iv++=v->lc; ++v;); - GA(t,INT,m,1,0); zv[4]=t; iv=AV(t); v=vq; DO(p, if(b[i])*iv++=v->s; ++v;); v=v0; DO(q, if(b[p+i])*iv++=v->s; ++v;); + GA(t,INT,m,1,0); zv[4]=t; iv=AV(t); v=vq; DO(p, if(b[i])*iv++=v->s; ++v;); v=v0; DO(q, if(b[p+i])*iv++=v->s; ++v;); GA(t,FL, m,1,0); zv[5]=t; dv=DAV(t); #if SY_WIN32 v=vq; DO(p, if(b[i] )*dv++=(((LI*)v->t)->LowPart+qpm*((LI*)v->t)->HighPart)/pf; ++v;); v=v0; DO(q, if(b[p+i])*dv++=(((LI*)v->t)->LowPart+qpm*((LI*)v->t)->HighPart)/pf; ++v;); #else - v=vq; DO(p, if(b[i] ){MC(dv,v->t,sizeof(D)); ++dv;} ++v;); - v=v0; DO(q, if(b[p+i]){MC(dv,v->t,sizeof(D)); ++dv;} ++v;); + v=vq; DO(p, if(b[i] ){MC(dv,v->t,sizeof(D)); ++dv;} ++v;); + v=v0; DO(q, if(b[p+i]){MC(dv,v->t,sizeof(D)); ++dv;} ++v;); #endif R z; } diff --git a/xu.c b/xu.c index dc37900..d714f88 100644 --- a/xu.c +++ b/xu.c @@ -3,6 +3,8 @@ /* */ /* Xenos: u: conversions */ +#include + #include "j.h" #include "x.h" @@ -98,17 +100,17 @@ static I wtomsize(US* src, I srcn){ US w;I r=0; R r; } -F1(jttoutf16){A z;I n,t,q,b=0; C* wv; US* c2v; - RZ(w); ASSERT(1>=AR(w),EVRANK); n=AN(w); t=AT(w); wv=CAV(w); - if(!n) {GA(z,LIT,n,1,0); R z;}; // empty lit list +F1(jttoutf16){A z;I n,t,q,b=0; UC* wv; US* c2v; + RZ(w); ASSERT(1>=AR(w),EVRANK); n=AN(w); t=AT(w); wv=(UC*)CAV(w); + if(!n) {GA(z,LIT,n,1,0); R z;}; // empty lit list if(LIT&t) { - DO(n, if(0>*wv++){b=1;break;}); + DO(n, if(127<*wv++){b=1;break;}); if(!b){ if(1==AR(w)) {R ca(w);}; GA(z,LIT,1,1,0); *CAV(z)=*CAV(w); R z;} // ascii list unchanged ascii scalar as list - q=mtowsize(CAV(w),n); + q=mtowsize((UC*)CAV(w),n); ASSERT(q>=0,EVDOMAIN); GA(z,C2T,q,1,0); - mtow(CAV(w),n,(US*)CAV(z)); + mtow((UC*)CAV(w),n,(US*)CAV(z)); R z; // u16 from u8 } else if(C2T&t) @@ -117,9 +119,9 @@ F1(jttoutf16){A z;I n,t,q,b=0; C* wv; US* c2v; DO(n, if(127<*c2v++){b=1;break;}); if(b) R ca(w); // u16 unchanged GA(z,LIT,n,AR(w),AS(w)); - wv=CAV(z); + wv=(UC*)CAV(z); c2v=(US*)AV(w); - DO(n, *wv++=(char)*c2v++;); + DO(n, *wv++=(UC)*c2v++;); R z; } else @@ -128,26 +130,26 @@ F1(jttoutf16){A z;I n,t,q,b=0; C* wv; US* c2v; F1(jttoutf8){A z;I n,t,q; RZ(w); ASSERT(1>=AR(w),EVRANK); n=AN(w); t=AT(w); -if(!n) {GA(z,LIT,n,AR(w),AS(w)); R z;}; // empty lit +if(!n) {GA(z,LIT,n,AR(w),AS(w)); R z;}; // empty lit if(t&LIT) R ca(w); // char unchanged ASSERT(t&C2T, EVDOMAIN); q=wtomsize((US*)CAV(w),n); GA(z,LIT,q,1,0); -wtom((US*)CAV(w),n,CAV(z)); +wtom((US*)CAV(w),n,(UC*)CAV(z)); R z; } // 8 u: x - utf8 from LIT or C2T F1(jttoutf16x){I q;A z; ASSERT(LIT&AT(w),EVDOMAIN); -q=mtowsize(CAV(w),AN(w)); +q=mtowsize((UC*)CAV(w),AN(w)); ASSERT(q>=0,EVDOMAIN); GA(z,C2T,q,1,0); -mtow(CAV(w),AN(w),(US*)CAV(z)); +mtow((UC*)CAV(w),AN(w),(US*)CAV(z)); R z; // u16 from u8 } void jttoutf8x(J jt,C* f, I n, US* fw){I q; q=wtomsize(fw,wcslen(fw)); -wtom(fw,wcslen(fw),f); +wtom(fw,wcslen(fw),(UC*)f); f[q]=0; }