diff --git a/CommKrnl.dll b/CommKrnl.dll index 58159be..d9d5dca 100644 Binary files a/CommKrnl.dll and b/CommKrnl.dll differ diff --git a/LIBCURL-TSL.dll b/LIBCURL-TSL.dll index f7a0317..410f690 100644 Binary files a/LIBCURL-TSL.dll and b/LIBCURL-TSL.dll differ diff --git a/MathKrnl.dll b/MathKrnl.dll index 2126421..d6fc5de 100644 Binary files a/MathKrnl.dll and b/MathKrnl.dll differ diff --git a/Mod_TSL24.dll b/Mod_TSL24.dll index 9a6795a..9c4fb76 100644 Binary files a/Mod_TSL24.dll and b/Mod_TSL24.dll differ diff --git a/TSCrypt.dll b/TSCrypt.dll index 7a1540a..0da62aa 100644 Binary files a/TSCrypt.dll and b/TSCrypt.dll differ diff --git a/TSL.exe b/TSL.exe index 3c7eb91..cc2c29b 100644 Binary files a/TSL.exe and b/TSL.exe differ diff --git a/TSLDebugModule.dll b/TSLDebugModule.dll index 04bf899..324bd10 100644 Binary files a/TSLDebugModule.dll and b/TSLDebugModule.dll differ diff --git a/TSLInterp.dll b/TSLInterp.dll index 9eaf7b5..e7ee1ce 100644 Binary files a/TSLInterp.dll and b/TSLInterp.dll differ diff --git a/TSLPlugin.dll b/TSLPlugin.dll index 5f321b7..94497d3 100644 Binary files a/TSLPlugin.dll and b/TSLPlugin.dll differ diff --git a/TSLR.dll b/TSLR.dll index fb49c73..95f27d8 100644 Binary files a/TSLR.dll and b/TSLR.dll differ diff --git a/TSSVRAPI.DLL b/TSSVRAPI.DLL index 2e930cc..7205b3b 100644 Binary files a/TSSVRAPI.DLL and b/TSSVRAPI.DLL differ diff --git a/TinyODBC.dll b/TinyODBC.dll index 98b8e16..b39d2e8 100644 Binary files a/TinyODBC.dll and b/TinyODBC.dll differ diff --git a/designer/utslcodeeditor.tsf b/designer/utslcodeeditor.tsf index b1c2b46..1140b03 100644 --- a/designer/utslcodeeditor.tsf +++ b/designer/utslcodeeditor.tsf @@ -2124,12 +2124,13 @@ type TEditer=class(TCustomcontrol) // o.SaveCurrentEditer(); self.Enabled := false; FIsFinding := true; - if not(d["c_reg"])then + if {not(d["c_reg"])}true then begin if(d["section"]="查找")and(d["btn"]="计数")then begin ct := "noshow"; - FindAllInCurrent(d,o,nil,ct); + //FindAllInCurrent(d,o,nil,ct); + Find_All(d,o,nil,ct); o.SetStatusText(format("查找到 %d处",ct)); return EndFind(); end else @@ -2137,18 +2138,25 @@ type TEditer=class(TCustomcontrol) // begin FFindListWnd.Clean(); ShowFindWnd(); - FindAllInCurrent(d,o,nil,ct); + //FindAllInCurrent(d,o,nil,ct); + Find_All(d,o,nil,ct); o.SetStatusText(format("查找到 %d处",ct)); return EndFind(); end else if(d["section"]in array("查找","替换"))and(d["btn"]="查找")then begin - FindInCurrent(d,o); + find_one(d,o); + //FindInCurrent(d,o); return EndFind(); end else if(d["section"]in array("替换"))and(d["btn"]="替换")then begin - if d["replace"]<> d["target"]then FindInCurrent(d,o,nil,1); + if d["replace"]<> d["target"]then + begin + + //FindInCurrent(d,o,nil,1); + find_one(d,o,nil,1); + end return EndFind(); end else if(d["section"]in array("替换"))and(d["btn"]="全部替换")then @@ -2157,7 +2165,8 @@ type TEditer=class(TCustomcontrol) // begin FFindListWnd.Clean(); ShowFindWnd(); - ReplaceAllInCurrent(d,o,nil,idx); + //ReplaceAllInCurrent(d,o,nil,idx); + replace_allincurrent(d,o,nil,idx); o.SetStatusText(format("替换 %d处",idx)); end return EndFind(); @@ -2167,7 +2176,8 @@ type TEditer=class(TCustomcontrol) // if messageboxa("即将在目录中替换内容!!","提示",mb_YesNo,self.Handle)<> IDYES then return EndFind(); FFindListWnd.Clean(); ShowFindWnd(); - FindInFiles(d,o,true,ct); + //FindInFiles(d,o,true,ct); + Find_InFiles(d,o,true,ct); o.SetStatusText(format("总共替换 %d处",ct)); return EndFind(); end else @@ -2175,7 +2185,8 @@ type TEditer=class(TCustomcontrol) // begin FFindListWnd.Clean(); ShowFindWnd(); - FindInFiles(d,o,false,ct); + //FindInFiles(d,o,false,ct); + Find_InFiles(d,o,false,ct); o.SetStatusText(format("总共查找 %d处",ct)); return EndFind(); end @@ -3913,216 +3924,46 @@ type TEditer=class(TCustomcontrol) // r["c_reg"] := FCheck_reg.Checked; r["c_dir"] := FCheck_subdir.Checked; } - function ReplaceAllInCurrent(data,fo,it,idx); + function replace_allincurrent(data,fo,it,idx); begin - data["c_revers"]:= 0; - data["c_cycle"]:= 0; + //data["c_revers"]:= 0; + //data["c_cycle"]:= 0; if not it then it := GetCurrentItem(); if not it then return; ed := it.FEditer; if not ed then return; + if ed.ReadOnly then return ;//不能替换 + TryDispatch(); + if not FIsFinding then return rt; + fs := data["target"]; + finder := finder_set_info(data,ed.Text); idx := 0; - try - ed.IncPaintLock(); - ed.ExecuteCommand(ed.ecGotoXY,array(1,1)); - cidx := 0; - while FindInCurrent(data,fo,it,1)=0 do - begin - if idx=0 then - begin - FFindListWnd.AppendItem(array("caption":format("replace:%s in file:%s",data["target"],it.OrigScriptPath))); - end - if idx>0 then - begin - ed.MergeLastUndo(); - end - idx++; - L := ed.CaretY; - if cidx=L then continue; - cidx := L; - scap := format(" %d:(第%d行) ",idx,L)+limitstringlength(ed.LineText); - FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":L)); - end - finally - ed.DecPaintLock(); - end - //fo.SetStatusText(format("共替换:%d 处",idx)); - end - function matchword(f,d); - begin - wr := d["c_wrap"]; - cw := d["c_case"]; - tg := d["target"]; - if not tg then return ; - ctl2 := "m"; - if not d["c_reg"] then - begin - ntg := ""; - ltg := length(tg); - for i := 1 to length(tg) do - begin - vi := tg[i]; - cvi := ord(vi); - if cvi>=9 and cvi<=13 then - begin - ntg +="\\s"; - if i=1 then wrp :=1; - if i=ltg then wrp .|= 2; - end else - if (cvi>=0x21 and cvi<=0x2f) or - (cvi>=0x3a and cvi<=0x40) or - (cvi>=0x5b and cvi<=0x60) or - (cvi>=0x7b and cvi<=0x7e) then - begin - ntg +="\\"+vi; - if i=1 then wrp :=1; - if i=ltg then wrp .|= 2; - end else - begin - ntg+=vi; - end + rsult := finder.replace_all(r); + if rsult then + begin + idx := length(rsult); + ed.ExecuteCommand(ed.ecSelectAll); + ed.SelText := r; + lastidx := -1; + for i,v in rsult do + begin + if i=0 then + FFindListWnd.AppendItem(array("caption":format("replace:%s in file:%s",fs,it.OrigScriptPath),"file":it.OrigScriptPath,"line":1)); + rdx := v[1,0]; + if rdx=lastidx then continue; + lastidx := rdx; + if not ifstring(v[3]) then continue; + scap := format(" %d:(第%d行) ",i,rdx)+limitstringlength(v[3]); + FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":rdx)); end - tg := ntg; end - - ctl := tg; - if wr then - begin - if not((wrp .& 1) >1) then ctl := "\\b"+ctl; - if not((wrp .& 2) >1) then ctl := ctl+"\\b"; - end - if cw then ctl2 += "i"; - linesi := array(0:1); - if (1 = readfile(rwraw(),"",f,0,filesize("",f),s)) and s then - begin - strcode := 0; - if(length(s)>= 2)and ord(s[1])=0xFE and ord(s[2])=0xFF then //ucs2-big - begin - strcode := 1; - if length(s)=2 then s := ""; - else - begin - s1 := ""; - setlength(s1,length(s)-2); - for i := 3 to length(s)-1 step 2 do - begin - s1[i-2]:= s[i+1]; - s1[i-1]:= s[i]; - end - s := unicodetomultibyte(s1,936); - end - end else - if(length(s)>= 2)and ord(s[1])=0xFF and ord(s[2])=0xFE then //ucs2-little - begin - strcode := 1; - if length(s)=2 then s := ""; - else - begin - s := unicodetomultibyte(s[3:],936); - end - end else - if(length(s)>= 3)and ord(s[1])=0xEF and ord(s[2])=0xBB and ord(s[3])=0xBF then - begin - strcode := 1; - if length(s)=3 then s := ""; - else s := utf8toansi(s[4:]); - end - if(0=strcode)then - begin - if IsTextUTF8(s)=1 then - begin - s := utf8toansi(s); - end - end - //////////////////////////////////////////////////////////////////////////////////// - slen := length(s); - orid := -1; - if 1= parseregexpr(ctl,s,ctl2,m,mp,mlen) then - begin - r := array(); - idx := 1; - rid := 1; - jid := 1; - ip := 1; - if pos("\r\n",s) or pos("\n",s) then - begin - fgf := "\n"; - end else - fgf := "\r"; - p1 := 1; - p2 := 0; - for i,v in m do - begin - mi := mp[i,0]; - - while idxp1) and (rid<>orid) then - begin - isset := 1; - for ii := p2 to slen do - begin - if s[ii]=fgf then - begin - isset := 0; - p2 := ii; - break; - end - end - if isset then p2 := slen; - r[i][2] := trim(s[p1:p2]); - end - else r[i,2] := ""; - orid := rid; - end - return r; - end - end end - function FindInFiles(d,o,rep,ct); + + + function Find_InFiles(d,o,rep,ct); begin fs := GetFilesFormSearchInfo(d); ct := 0; - if not rep then - begin - for i,v in fs do - begin - if not FIsFinding then break; - ri := matchword(i,d); - if ri then - begin - ril := length(ri); - FFindListWnd.AppendItem(array("caption":format("find:%s in file:%s has:%d",d["target"],i,ril))); - orii := -1; - for ii,vi in ri do - begin - rii := vi[0]; - ct++; - if orii=rii then continue; - orii := rii; - scap := format(" %d:(第%d行) ",ct,rii)+limitstringlength(vi[2]); - FFindListWnd.AppendItem(array("caption":scap,"file":i,"line":rii)); - end - end - end - return ; - end - for i,v in fs do begin if not FIsFinding then break; @@ -4136,130 +3977,76 @@ type TEditer=class(TCustomcontrol) // end if rep then begin - ReplaceAllInCurrent(d,o,it,idx); + //ReplaceAllInCurrent(d,o,it,idx); + replace_allincurrent(d,o,it,idx); SavePageItem(it); end else begin - FindAllInCurrent(d,o,it,idx); + //FindAllInCurrent(d,o,it,idx); + Find_All(d,o,it,idx); end ct += idx; end end - function FindInCurrent(data,fo,it,rep); + + function finder_set_info(data,txt); + begin + finder := static new t_gbk_text_finder(); + finder.set_text(txt); + finder.set_find_str(data["target"]); + finder.iscase := data["c_case"]; + finder.iswrap := data["c_wrap"]; + finder.isReg := data["c_reg"]; + finder.isprev := data["c_revers"]; + finder.iscycle := data["c_cycle"]; + finder.ismline := data["c_mline"]; + finder.set_replace_str(data["replace"]); + return finder; + end + function find_one(data,fo,it,rep); begin if not it then it := GetCurrentItem(); if not it then return -2; ed := it.FEditer; if not ed then return -2; cy := ed.CaretY; - cx := ed.CaretX; - wordwrap := data["c_wrap"]; + cx := ed.CaretX; fs := data["target"]; if not(fs and ifstring(fs))then begin fo.SetStatusText("查找内容为空!"); return -2; end - stringiswrapword := isCaseWords(fs); - if data["c_case"]then fs := lowercase(fs); - rstring := data["replace"]; - lfs := length(fs); - L := ed.Lines; - ct := L.length(); - if data["c_revers"]then - begin - for i := cy-1 downto cy-ct do + finder := finder_set_info(data,ed.Text); + finder.set_rc(array(cy,cx)); + reslt := finder.find_one(); + if reslt then + begin + if data["c_revers"] then + begin + p1 := reslt[0,4]; + p2 := reslt[0,3]; + end else + begin + p1 := reslt[0,3]; + p2 := reslt[0,4]; + end + ed.ExecuteCommand(ed.ecGotoXY,p1); + ed.ExecuteCommand(ed.ecSelGotoXY,p2); + fo.SetStatusText(format("位置: %d %d",p1[0],p1[1])); + if rep then begin - ridx := i; - if data["c_cycle"]then - begin - ridx :=(ridx<0)?(ridx+ct):ridx; - end - if ridx<0 then - begin - fo.SetStatusText("到达顶部"); - return -2; - end - s := L.GetStringByIndex(ridx); - ls := length(s); - while cx-lfs+1>1 do - begin - if not FIsFinding then return-2; - TryDispatch(); - subs := s[cx-lfs:cx-1]; - if data["c_case"]then subs := lowercase(subs); - if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 - begin - ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx)); - ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx-lfs)); - if rep then - begin - ed.SelText := rstring; - end - fo.SetStatusText(format("位置: %d %d",ridx+1,cx-lfs)); - return 0; - end - cx--; - end - tidx := ridx-1; - if data["c_cycle"]then - begin - tidx += ct; - tidx := tidx mod ct; - end else - begin - if tidx<0 then - begin - fo.SetStatusText("到达顶部"); - return-2; - end - end - s := L.GetStringByIndex(tidx); - cx := length(s)+1; - end - fo.SetStatusText("到达顶部"); + rs := finder.format_rep_Str(reslt); + ed.SelText := rs; + end + return 0; + end else + begin + fo.SetStatusText("没找到"); return -2; - end - for i := 0 to ct do - begin - ridx := i+cy-1; - if data["c_cycle"]then - begin - ridx := ridx mod ct; - end - if ridx >= ct then - begin - fo.SetStatusText("到达底部"); - return-2; - end - s := L.GetStringByIndex(ridx); - ls := length(s); - if data["c_case"] then s := lowercase(s); - while cx+lfs-1 <= ls do - begin - if not FIsFinding then return-2; - //GetAndDispatchMessageA(); - TryDispatch(); - subs := s[cx:cx+lfs-1]; - if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 - begin - ed.ExecuteCommand(ed.ecGotoXY,array(ridx+1,cx)); - ed.ExecuteCommand(ed.ecSelGotoXY,array(ridx+1,cx+lfs)); - if rep then - begin - ed.SelText := rstring; - end - fo.SetStatusText(format("位置: %d %d",ridx+1,cx)); - return 0; - end - //没找到 - cx++; - end - cx := 1; - end - fo.SetStatusText("到达底部"); - return -2; - end + end + end + function FindListChoosed(o,e); begin it := o.GetItem(o.GetCurrentSelection()); @@ -4283,77 +4070,46 @@ type TEditer=class(TCustomcontrol) // GetAndDispatchMessageA(); end end - function FindAllInCurrent(data,fo,it,rt); + function Find_All(data,fo,it,rt); begin if rt = "noshow" then begin fnoshow := true; end + TryDispatch(); + if not FIsFinding then return rt; rt := 0; if not it then it := GetCurrentItem(); if not it then return; ed := it.FEditer; if not ed then return; - wordwrap := data["c_wrap"]; + finder := finder_set_info(data,ed.Text); + rsult := finder.find_all(); fs := data["target"]; - if not(fs and ifstring(fs))then return fo.SetStatusText("找到 0 处"); - if data["c_case"]then fs := lowercase(fs); - stringiswrapword := isCaseWords(fs); - lfs := length(fs); - L := ed.Lines; - ct := L.length(); - - for i := 0 to ct-1 do - begin - s := L.GetStringByIndex(i); - ls := length(s); - cx := 1; - if data["c_case"] then s := lowercase(s); - cidx := 0; - while cx+lfs-1 <= ls do - begin - if not FIsFinding then return rt; - //GetAndDispatchMessageA(); - TryDispatch(); - subs := s[cx:cx+lfs-1]; - //((stringiswrapword .& 2) and (IsWordsChar(s,cx-1,ls)) ( (stringiswrapword .& 1) and IsWordsChar(s,cx+lfs,ls)) ) - if subs=fs and(wordwrap?((stringiswrapword=3)or(((stringiswrapword .& 1)or IsWordsChar(s,cx-1,ls))and((stringiswrapword .& 2)or IsWordsChar(s,cx+lfs,ls)))):true)then //找到了 - begin - if rt=0 and (not fnoshow) then FFindListWnd.AppendItem(array("caption":format("find:%s in file:%s",fs,it.OrigScriptPath),"file":it.OrigScriptPath,"line":1)); - cx += lfs; - rt++; - if cidx then continue; - cidx := 1; - if not fnoshow then - begin - scap := format(" %d:(第%d行) ",rt,i+1)+limitstringlength(s); - FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":i+1)); - end - continue; - end - //没找到 - cx++; - end - end - return rt; - end - function isCaseWords(s); //判断全词匹配 - begin - if ifstring(s)and s then - begin - len := length(s); - if len=1 then return IsWordsChar(s,1,1); - return IsWordsChar(s,1,1).|(2 * IsWordsChar(s,len,len)); - end - end - function IsWordsChar(s,idx,len); - begin - if not(len>0)then len := length(s); - if idx>len then return true; - if idx<1 then return true; - ivi := ord(s[idx]); - if(ivi<48)or(ivi>57 and ivi<65)or(ivi>90 and ivi<95)or(ivi>95 and ivi<97)or(ivi>122 and ivi <= 127)then return true; - end + lastidx := -1; + if rsult then + begin + rt := length(rsult); + for i,v in rsult do + begin + if i=0 and (not fnoshow) then + FFindListWnd.AppendItem(array("caption":format("find:%s in file:%s",fs,it.OrigScriptPath),"file":it.OrigScriptPath,"line":1)); + if not fnoshow then + begin + rdx := v[1,0]; + if rdx=lastidx then continue; + lastidx := rdx; + if not ifstring(v[3]) then continue; + scap := format(" %d:(第%d行) ",i,rdx)+limitstringlength(v[3]); + FFindListWnd.AppendItem(array("caption":scap,"file":it.OrigScriptPath,"line":rdx)); + end + end + end else + begin + fo.SetStatusText("找到 0 处"); + end + end + function TabCheckChanged(); begin if not FListPages.Visible then return; @@ -6053,23 +5809,16 @@ type TFindWnd=class(TPage) FCheck_cycle.top := lg * 8; FCheck_cycle.parent := self; FCheck_reg.caption := "正则匹配"; - FCheck_reg.Enabled := false; + FCheck_reg.Enabled := true; FCheck_reg.top := lg * 9; FCheck_reg.parent := self; - FCheck_gt.caption := "\\t转义tab"; - FCheck_gt.Checked := false; + FCheck_gt.Visible := true; + FCheck_gt.caption := "多行"; + FCheck_gt.Checked := true; FCheck_gt.top := lg * 9; FCheck_gt.Left := FCheck_reg.width+FCheck_reg.Left+10; - FCheck_gt.parent := self; + //FCheck_gt.parent := self; FCheck_subdir.parent := self; - FCheck_reg.OnClick := function(o,e) - begin - ck := o.Checked; - FCheck_revers.Enabled := not(ck); - FCheck_wrap.Enabled := not(ck); - //FCheck_case.Enabled := not(ck); - FCheck_cycle.Enabled := not(ck); - end FStatus := new TStatusBar(self); //FStatus.Align := alNone; FStatus.Items := array(("text":"","width":700)); @@ -6099,16 +5848,9 @@ type TFindWnd=class(TPage) r := array(); r["section"]:= CurrentITem.Caption; s := FEdit_target.Editer.Text; - if FCheck_gt.Checked then - begin - s := Replacestr(s,"\\t","\t"); - end r["target"]:= s; + r["c_mline"] := FCheck_gt.Checked; s := FEdit_repace.Editer.Text; - if FCheck_gt.Checked then - begin - s := Replacestr(s,"\\t","\t"); - end r["replace"]:= s; r["filetype"]:= FEdit_type.Editer.Text; r["dir"]:= FEdit_dir.Editer.Text; diff --git a/designer/utslvclsyntaxparser.tsf b/designer/utslvclsyntaxparser.tsf index 79b556a..e707986 100644 --- a/designer/utslvclsyntaxparser.tsf +++ b/designer/utslvclsyntaxparser.tsf @@ -638,27 +638,25 @@ type tslparserbase= class // {** @explan(说明) tsl语言解析基类 %% **} - static TT_IDE; //标示符 - static TT_STR; //字符串 - static TT_SYM; //分隔符 - static TT_OK; + private + fcomments; + fcomments2; + public + static TT_IDE = "标示符"; //标示符 + static TT_STR = "字符串"; //字符串 + static TT_SYM = "分割"; //分隔符 function create(); begin - if not TT_OK then - begin - TT_IDE := "标示符"; - TT_STR := "字符串"; - TT_SYM := "分割"; - TT_OK := true; - end + fcomments := array("说明0":1,"说明1":1,"说明2":1,"说明":1); + fcomments2 := array("空格":1,"回车":1,"换行":1); end function setdata(ret,nk,vs,tp,idx,hh) //解析 begin {** @explan(说明)保存数据 **} - if tp="空格" or tp="回车" or tp="换行" then return; - if tp in array("说明0","说明1","说明2","说明")then + if fcomments2[tp] then return; + if fcomments[tp] then begin vs := ""; return; diff --git a/funcext/tvclib/utslvclauxiliary.tsf b/funcext/tvclib/utslvclauxiliary.tsf index 3ff461e..9d13517 100644 --- a/funcext/tvclib/utslvclauxiliary.tsf +++ b/funcext/tvclib/utslvclauxiliary.tsf @@ -27,8 +27,9 @@ function pointinrect(p,rec); function intersectrect(rec1,rec2,irec); function bitcombination(s,v,f); -function IsTextUTF8(str); +function istextascii(s); //ansi编码 function isTextGBK(str); +function IsTextUTF8(str); function exportjsonformat(d,tbw,ct); function get_resource_by_name(n,full); //**************************** @@ -50,6 +51,8 @@ function TS_ExecPath():string; function TS_GetAppPath():string; function TS_GetIniPath(t:integer;iname:string):string; function gettslexefullpath(); +//function tsl_str_head_at(s,n); +function get_tsl_mem_ptr(s,n); type tuiglobaldata=class() //全局对象存储 static UIData; class Function uisetdata(n,d); @@ -2889,6 +2892,380 @@ type t_ini_format_operator=class() ft; end end +type t_gbk_text_finder = class() //查找对象 + function create(); + begin + ffindstr:=""; + fstr := ""; + Fismline := true; + findflag := false; + FisReg := false; + fiswrap := false; + fiscase := false; + fiscycle := true; + fisprev := false; + frc := array(1,1); + end + function set_text(s); //文本 + begin + if fstr<>s then + begin + fstr := s; + ftextrows := text_2_array(fstr); + findflag := true; + end + end + function set_replace_str(s); + begin + if frstr<>s then + begin + frstr := s; + frstrflag := true; + end + end + function set_find_str(s); + begin + if ffindstr <> s then + begin + ffindstr := s; + findflag := true; + end + end + function set_rc(rc); //设置当前行列 1,1 为初始位置 + begin + if ifarray(rc) and rc[0]>0 and rc[1]>0 then + begin + frc := rc; + end + end + function find_one(); //查找下一个 + begin + if fisprev then return find_prev(); + return find_next(); + end + function format_rep_Str(info); //构造替换 + begin + ms :=get_rep_str_info(); + if ifarray(ms) then + begin + fr :=frstr; + for j := length(ms)-1 downto 0 do + begin + si := fmachs[i,ms[j,3],0]; + if not ifstring(si) then return false; + fr[ms[j,1]:ms[j,2]] := si; + end + return fr; + end + return ms; + end + function find_all(); //全部查找 + begin + do_find(); + r := array(); + for i,v in fmachs do + begin + //array(vj,p,pe,array(r1,c1),array(r2,c2),row_text(r1)) + r[i] := format_find_return(v); + end + return r; //返回信息 + end + function replace_all(var r);//全部替换,为变参返回,返回结果是行列信息 + begin + do_find(); + if not fmachs then return 0; + ms := get_rep_str_info(); + r := fstr; + rinfo := array(); + for i := length(fmachs)-1 downto 0 do + begin + info := fmachs[i]; + rs := format_rep_Str(info); + if rs=0 then return false; + p1 := info[0,1] ; + p2 := info[0,2]; + r[p1:p2] := rs; + rinfo[i] := format_find_return(info); + end + if r=fstr then return 0; + return rinfo; + end + function find_next();//下一个 + begin + do_find(); + label findtwo; + for i,v in fmachs do + begin + if frc[0]v[0,3,0] or(frc[0]=v[0,3,0] and frc[1]>=v[0,4,1]) then + begin + frc := v[0,3]; + return v; + end + end + if not fiscycle then return array(); + if two then return array(); + two := true; + ls := length(ftextrows); + frc := array(ftextrows[ls-1,0],ftextrows[ls-1,1]); + goto findtwo; + end + property isReg read FisReg write set_reg;//正则 + property iscase read fiscase write set_case;//大小写 + property iswrap read fiswrap write set_wrap;//全词匹配 + property iscycle read fiscycle write set_cycle;//循环查找 + property isprev read fisprev write set_prev;//朝前 + property ismline read Fismline write set_mline;//朝前 + private + function set_mline(v); + begin + nv := v?true:false; + if nv<>Fismline then + begin + Fismline := nv; + findflag := true; + end + end + function set_prev(v); + begin + nv := v?true:false; + if nv<>fisprev then + begin + fisprev := nv; + end + end + function set_cycle(v); + begin + nv := v?true:false; + if nv<>fiscycle then + begin + fiscycle := nv; + end + end + function set_reg(v); + begin + nv := v?true:false; + if nv<>fisreg then + begin + fisreg := nv; + findflag := true; + frstrflag := true; + end + end + function set_case(v); + begin + nv := v?true:false; + if nv<>fiscase then + begin + fiscase := nv; + findflag := true; + end + end + function set_wrap(v); + begin + nv := v?true:false; + if nv<>fiswrap then + begin + fiswrap := nv; + findflag := true; + end + end + function row_text(i);//获得行文本 + begin + return ftextrows[i-1,2]; + end + function p_to_rc(p,r,c);//位置到行列 + begin + r := -1; + c := -1; + for i,v in ftextrows do + begin + if p>=v[0] and p<=(v[1]) then + begin + r := i+1;c := p-v[0]+1; + return ; + end + end + end + function fmt_unreg_ctl(tg,rg,wr);//正则控制串 + begin + if not tg then return ""; + ctl := tg; + if not rg then + begin + ctl := ""; + ltg := length(tg); + for i := 1 to length(tg) do + begin + vi := tg[i]; + cvi := ord(vi); + if cvi>=9 and cvi<=13 then + begin + ctl +="\\s"; + if i=1 then wrp :=1; + if i=ltg then wrp .|= 2; + end else + if (cvi>=0x21 and cvi<=0x2f) or + (cvi>=0x3a and cvi<=0x40) or + (cvi>=0x5b and cvi<=0x60) or + (cvi>=0x7b and cvi<=0x7e) then + begin + ctl +="\\"+vi; + if i=1 then wrp :=1; + if i=ltg then wrp .|= 2; + end else + begin + ctl+=vi; + end + end + if wr then + begin + if not((wrp .& 1) >0) and not((ord(ctl[1]) .& 0x80 )>0) then ctl := "\\b"+ctl; + if not((wrp .& 2) >0) and not((ord(ctl[length(ctl)]) .& 0x80 )>0) then ctl := ctl+"\\b"; + end + end + + return ctl; + end + function text_2_array(s); //获得行位置 + begin + r := array(); + fgf := "\n"; + if pos("\r\n",s) or pos("\n",s) then + begin + fgf := "\n"; + end else + if pos("\r",s) then + fgf := "\r"; + r[0,0] := 1; + idx := 0; + for i := 1 to length(s)-1 do + begin + vi := s[i]; + if vi=fgf then + begin + r[idx,1]:=i; + r[idx,2]:=s[r[idx,0]:(i-1)]; + idx++; + r[idx,0] := i+1; + end + end + r[idx,1]:=length(s)+1; + r[idx,2]:=s[r[idx,0]:]; + return r; + end + function do_find();//查找 + begin + if not findflag then return ; + findflag := false; + fs := fmt_unreg_ctl(ffindstr,FisReg,fiswrap); + ctl2 := ""; + if Fismline then ctl2 += "m"; + if fiscase then ctl2+="i"; + fmachs := array(); + frows := array(); + if 1= ParseRegExpr(fs,fstr,ctl2,m,mp,ml) then + begin + for i ,v in m do + begin + for j,vj in v do + begin + p := mp[i,j]; + pe := p+ml[i,j]-1; + p_to_rc(p,r1,c1); + p_to_rc(pe+1,r2,c2); + if j=0 and not(frows[r1]) then + begin + frows[r1] := true; + fmachs[i,j] := array(vj,p,pe,array(r1,c1),array(r2,c2),row_text(r1)); + end else fmachs[i,j] := array(vj,p,pe,array(r1,c1),array(r2,c2)); + end + end + end + end + + function get_rep_str_info(); //替换字符串信息 + begin + if frstrflag then + begin + frstrflag := false; + if frstr then // + begin + if FisReg then //正则表达式 + begin + if 1= ParseRegExpr("\\$(\\d+)",frstr,"",m,mp,ml) then //占位符计算 + begin + ms := array(); + for i:= 0 to length(m)-1 do + begin + ms[i,0] := m[i,0]; + ms[i,1] := mp[i,0]; + ms[i,2] := mp[i,0]+ml[i,0]-1; + ms[i,3] := strtointdef(m[i,1],0); + end + end else + begin + ms := frstr; + end + end else + begin + ms := frstr; + end + end else + begin + ms := ""; + end + freginfo := ms; + end else + begin + ms := freginfo; + end + return ms; + end + function format_find_return(v); //格式化一个匹配结果 + begin + r := array(); + r[0] := v[0,0];//匹配结果 + r[1] := v[0,3];//配合开始的行列 + r[2] := v[0,4];//截止的行列 + r[3] := v[0,5];//行内容 + return r; + end + private + frstr; + ffindstr; + fstr; + Fismline; + findflag; + frstrflag; + freginfo; + fisprev; + fiscycle; + FisReg; + fiscase; + fiswrap; + ftextrows; + fmachs; + frc; +end implementation function iffuncptr(fn); begin @@ -3617,6 +3994,22 @@ function TS_ModulePath():string;cdecl;external {$ifdef linux}"libTSSVRAPI.so"{$ function TS_ExecPath():string;cdecl;external {$ifdef linux}"libTSSVRAPI.so"{$else}"TSSVRAPI.dll"{$endif} name "TS_ExecPath"; function TS_GetAppPath():string;cdecl;external {$ifdef linux}"libTSSVRAPI.so"{$else}"TSSVRAPI.dll"{$endif} name "TS_GetAppPath"; function TS_GetIniPath(t:integer;iname:string):string;cdecl;external {$ifdef linux}"libTSSVRAPI.so"{$else}"TSSVRAPI.dll"{$endif} name "TS_GetIniPath"; +function istextascii(s); //ansi编码 +begin + len := length(s); + //m := new TMemoryStream(); + //dp := get_tsl_mem_ptr(s); + //m.setmemory(dp,len); + //ci := 0; + i := 1; + for i:= 1 to len do + begin + ci := ord(s[i]); + //m.read(ci,1); + if((ci .& 0x80)<> 0) then return false; + end + return true; +end function isTextGBK(data) //gbk编码 begin if not ifstring(data) then return 0; @@ -3843,7 +4236,7 @@ begin if n=2 then return g_w_tfm_resource_withdir; if n=3 then return (g_w_tfm_resource union g_w_tfm_resource_withdir); if n=4 then return g_w_tfm_resource_names; - p := filesize("","d:\\test\\get_source.txt"); + //p := filesize("","d:\\test\\get_source.txt"); r := g_w_tfm_resource[n]; if r then return r; @@ -3894,7 +4287,43 @@ begin end except end +end +function get_tsl_mem_ptr(s,n); +begin + ptr := static makeinstance(thisfunction(get_tsl_ptr_drift)); + if ifstring(s) then + begin + _f_ := static function(var v:string;n:integer):pointer;cdecl;external ptr; + end else + if ifint(s) then + begin + _f_ := static function(var v:integer;n:integer):pointer;cdecl;external ptr; + end else + if ifint64(s) then + begin + _f_ := static function(var v:int64;n:integer):pointer;cdecl;external ptr; + end else + if ifnumber(s) then + begin + _f_ := static function(var v:double;n:integer):pointer;cdecl;external ptr; + end else + if ifobj(s) then + begin + _f_ := static function(var v:TObject;n:integer):pointer;cdecl;external ptr; + end + return call(_f_,s,((n>0)?n:0)); end +{function tsl_str_head_at(s,n); +begin + _f_ := static function(var v:string;n:integer):string;cdecl;external makeinstance(thisfunction(get_tsl_ptr_drift)); + return ##_f_(s,n); +end } +function get_tsl_ptr_drift(v:pointer;n:integer):pointer;cdecl; +begin + if n>0 then return v+n; + return v; +end + initialization uinit(); end. diff --git a/funcext/tvclib/utvclgraphics.tsf b/funcext/tvclib/utvclgraphics.tsf index 2bc77b6..2a7c5b2 100644 --- a/funcext/tvclib/utvclgraphics.tsf +++ b/funcext/tvclib/utvclgraphics.tsf @@ -307,18 +307,22 @@ type tfm = class(tvcform) begin inherited; caption := "pie"; + width := 800; + Height := 800; fg := new tg_WinControl(self); fg.Caption := "hello1"; fg.parent := self; fg.Align := alClient; //////////设置坐标轴属性//////////////////////// axs := new tg_axes(); + axs.box := true; axs.figure := fg.figure; axs.title.text := "hello pie "; axs.axises(1).tics_color := 0x0000ff; axs.axises(1).fontinfo.size := 8; axs.data_bounds(0) := array(-0.1,2.1); axs.data_bounds(1) := array(-0.1,2.1); + axs.data_bounds(2) := array(-0.5,0.5); args := array( (pi()/4,pi()/3,0x0000ff), (pi()/3,pi()/2,0x00ff00), @@ -326,32 +330,44 @@ type tfm = class(tvcform) (pi()*3/2,pi()*9/4,0xff00ff) ); + prominentidx := 0; //凸显的块 + prominentrate := 0.1; //凸显的块 for i,v in args do begin line := new tg_Polyline(); line.polyline_style := line.tgc_LS_filled; line.closed := true; - line.graph_data := 1+get_pie_lines(v[0],v[1]); + c := (i=2)?1.1:1; + line.graph_data := 1+get_pie_lines(v[0],v[1],i=prominentidx,prominentrate); line.lineinfo.bkcolor := v[2]; line.parent := axs; end end - function get_pie_lines(arg1,arg2); + function get_pie_lines(arg1,arg2,prominent,prominentrate); begin stp := pi()/180; d := 1; - r := array((0,0)); + r := array(); + r[0] := array(0,0); idx := 1; - for i:= arg1 to arg2 step stp do + for i:= arg1+(prominent?stp:0) to arg2-(prominent?stp:0) step stp do begin - r[idx++] := array(sin(i),cos(i)); - + r[idx++] := array(sin(i),cos(i)); + end + r[idx] :=array(0,0); + if prominent then + begin + rx := r[integer(idx/2)]*prominentrate; + for i := 0 to idx do + begin + r[i]+=rx; + end end - r[length(r)] :=array(0,0); return r; end fg; end + } type tg_WinControl = class(tcustomcontrol,tg_const) //绘图窗口 function create(AOwner); diff --git a/plugin/PocoExecSQL.DLL b/plugin/PocoExecSQL.DLL index 88b66e3..aea03a4 100644 Binary files a/plugin/PocoExecSQL.DLL and b/plugin/PocoExecSQL.DLL differ diff --git a/plugin/TSCURL.DLL b/plugin/TSCURL.DLL index 810fde8..9c58d9f 100644 Binary files a/plugin/TSCURL.DLL and b/plugin/TSCURL.DLL differ diff --git a/plugin/TSLCPLUGIN.DLL b/plugin/TSLCPLUGIN.DLL index 8ef79db..09b5d63 100644 Binary files a/plugin/TSLCPLUGIN.DLL and b/plugin/TSLCPLUGIN.DLL differ diff --git a/plugin/TSLClient.dll b/plugin/TSLClient.dll index 7437104..7f16cec 100644 Binary files a/plugin/TSLClient.dll and b/plugin/TSLClient.dll differ diff --git a/plugin/TSLUIL.dll b/plugin/TSLUIL.dll index 4f4fe31..4063ae1 100644 Binary files a/plugin/TSLUIL.dll and b/plugin/TSLUIL.dll differ diff --git a/plugin/TSSecurity.dll b/plugin/TSSecurity.dll index 427a942..fb4edf4 100644 Binary files a/plugin/TSSecurity.dll and b/plugin/TSSecurity.dll differ diff --git a/plugin/office_plugin.DLL b/plugin/office_plugin.DLL index bf0020e..1e218c6 100644 Binary files a/plugin/office_plugin.DLL and b/plugin/office_plugin.DLL differ diff --git a/protocol.dll b/protocol.dll index 95574f4..4a7df07 100644 Binary files a/protocol.dll and b/protocol.dll differ diff --git a/tsleditor.exe b/tsleditor.exe index c62a0f9..5abb124 100644 Binary files a/tsleditor.exe and b/tsleditor.exe differ diff --git a/tslkrnl.dll b/tslkrnl.dll index 1c550ce..2da8057 100644 Binary files a/tslkrnl.dll and b/tslkrnl.dll differ diff --git a/tslpcre.dll b/tslpcre.dll index 7e8ea05..fbda914 100644 Binary files a/tslpcre.dll and b/tslpcre.dll differ diff --git a/tslskele b/tslskele index 8900114..149090a 100644 Binary files a/tslskele and b/tslskele differ diff --git a/tslsklib b/tslsklib index 404045f..b6ccec5 100644 Binary files a/tslsklib and b/tslsklib differ diff --git a/tsnet.dll b/tsnet.dll index 4f47bbd..3dad3ff 100644 Binary files a/tsnet.dll and b/tsnet.dll differ diff --git a/whatsnew.txt b/whatsnew.txt index e964f16..47ee59c 100644 --- a/whatsnew.txt +++ b/whatsnew.txt @@ -1,3 +1,515 @@ +更新日志--------2024-03-21 + 修订:integer*复数的BUG。 + +更新日志--------2024-03-20 + 升级:新增数组统计类函数对复数的支持(包括FMARRAY以及ARRAY),包含单序列以及双序列,复数支撑工作基本完成。 + 偏度丰度以及和大小相关的因复数的特殊性不支持,TS-SQL聚集及数仓统计未做复数支持计划。 + 修订:因复数支撑产生的BUG以及复数支撑自身的BUG。 + 升级:客户端支持复数数据类型的显示以及调试。 + 升级:Python以及R语言支撑部分支持复数和TSL类型进行互相转换。 + +更新日志--------2024-03-14 + 修正:TSCURL对邮件编码会因为HEADER项超长时丢失一些字的问题。 + 升级:复数的绝大部分支撑已经完成,包括各种算符以及新增imag、conj、ifcomplex等函数以及基础函数的支持。 + 剩下未完成的部分是数组统计类函数对复数的支持。 + 目前客户端未对复数显示等做支持,但TSL.EXE等已经支持直接使用。复数仍属于测试阶段。 + +更新日志--------2024-03-05 + 修正:pk_sql_mysql.dll的问题。 + +更新日志--------2024-03-04 + 升级:chromium版本升级到120.0.6099.109,cef升级到120.1.8。 + 修正:office-lib import xlsx存在sheet参数的时候的问题。 + 修正:covof,cov等对第二参数具有nil时的处理存在瑕疵的问题。 + 修正:pocoExecSQL对原本是gbk的进行了utf8到gbk转换导致的字段为column1..的问题。 + 修正:sysparams[]当系统参数已经被引用时的赋值无法进行的问题。 + 升级:poco新增pk_sql.dll/libpk_sql.so,具体对应的支持库为pk_sql_*.dll和libpk_sql_*.so。 + +更新日志--------2024-02-07 + 修正:THashedStringList问题。 + 变动:TSSecurity改变对unrar的默认静态链接支持,如果需要unrar依赖其动态库,libunrar.so和Unrar64.dll。 + +更新日志--------2024-02-05 + 修正:THashedStringList的效率问题。 + 更新:TSL.exe的日期申明等。 + +更新日志--------2024-01-22 + 修正:Select keepnull无效的问题。 + +更新日志--------2024-01-19 + 升级:FireDac oracle clob fix. ts-sql insert update ,dml execsql... + 修正:编辑器自动完成功能 + +更新日志--------2024-01-18 + 升级:FireDac oracle clob fix. + +更新日志--------2024-01-16 + 修正:CHART图功能的一些出错问题。 + +更新日志--------2024-01-14 + 升级:加密配置串等方面的效率升级以及其他问题。 + 升级:office_plugin浮点精度的问题。 + +更新日志--------2024-01-08 + 升级:因修复老版本重新编译。 + 升级:增加函数收藏内鼠标右键从最近执行列表删除功能。 + 升级:文件菜单内增加清除最近运行列表功能。 + 升级:文件菜单内增加清除最近编辑列表功能。 + +更新日志--------2024-01-05 + 升级:板块管理新增【导出】【复制到剪切板】【复制为TSL数组】【从剪切板粘贴】等功能。 + 升级:数据专家支持将选择的内容以【多因子数组模式复制到剪切板】的功能。 + 升级:函数分类卷滚窗口支持滚轮。 + +更新日志--------2024-01-02 + 升级:通讯支持SM2/SM4国密加密算法,需平台支持。(新增gmssl.dll) + 升级:数据专家的证券代码搜索显示支持排序。 + 升级:技术指标数值窗口设置新增不显示。 + 升级:表格显示支持关闭多行模式。 + 升级:函数分类采用卷滚窗口。 + 升级:支持配置串等高强度加密(支持RSA,AES及国密SM2,SM4) + 优化:函数特性设置证券代码和类型为行业时候导致性能问题。 + 修正:客户端服务器列表维护不成功登录未保存的问题。 + +更新日志--------2023-12-20 + 修正:内核TStringList类兼容性。 + 修正:ReadFile兼容性。 + 增强:内核支持将配置存贮到扩展安全设施中。 + +更新日志--------2023-12-18 + 修正:内核TStringList类某些方法的缺陷。 + +更新日志--------2023-12-15 + 修正:parsehtml保持和老版本一致。 + +更新日志--------2023-12-13 + 优化:数组设置取值效率提升。 + 优化:提高旧流生成的效率,提升30%左右。 + 修正:syssendmail附件功能。 + +更新日志--------2023-12-11 + 修正:libcurl-TSL在WINDOWS上某些认证提示错误的问题。 + 修正:数据中心服务在-fullcompactionnewstream -fullcompaction执行过程中未删除老文件的问题。 + 升级:-fullcompaction加速,无需对数据重新解压和压缩。 + 升级:新增-fullcompactionoldstream参数,允许全部转换为旧流模式。(可用于测试新旧格式下数据的效率表现等差异) + +更新日志--------2023-12-12 + 修正:LIBCURL-TSL认证兼容性。 + +更新日志--------2023-12-8 + 升级:新增函数sysencodecryptstr(s:string;t:integer):string + t为0,ExecSQL.ini中的加密连接串,含义见TSL帮助里的-ENCODE + t为1,TSL.ini调试配置的密码串,含义见TSL帮助里的-ENCODEDEBUGPASS + t为2,TSL字符串编码 + 修正:新一代的smtp/pop3类 authtype保持和老版兼容。 + +更新日志--------2023-12-5 + 修正:internetrequest函数设置header时有可能会送入错误头的问题。 + 修正:importfile/exportfile如果导入导出失败返回错误字符串,保持和旧版的兼容。 + +更新日志--------2023-12-4 + 修正:老模式下使用OFFICE模式importfile ftxls CSV格式导致失败的问题。 + 升级:ftcsv模式支持utf8 bom格式csv。 + +更新日志--------2023-12-1 + 修正:ExcelGetDataRange函数当区域非从第一个单元格开始会存在错误。 + +更新日志--------2023-11-30 + 升级:优化老格式流的加载性能。 + 修正:隐藏菜单功能。 + 修正:Poco模式对pg 适用TS-SQL insert into批量插入出错的问题。 + +更新日志--------2023-11-29 + 升级:增强快速流格式的兼容支持。 + 升级:支持服务端设置隐藏客户端不需要的菜单和导航功能。 + +更新日志--------2023-11-28 + 升级:优化从TSL流加载到内存的性能,传统流模式有百分之几十的性能提升。 + 升级:新版本的执行返回结果集将使用快速流格式,快速流模式空间需求小,且加载效率快300%。 + 升级:采用新客户端时,新版本的执行savetable将缺省采用快速流格式(如果存在有不支持新格式的古老执行版本(2020年6月之前的版本)在同一套体系内运行,会导致问题)。 + savetable支持第三个参数,如果缺省,则根据前端的版本决定是否存储为新流格式,也设定第三参数为0指定原始流格式,1强制为新流格式。 + 升级:新一代客户端上传用户数据将采用快速流,为了客户端保持和古旧的平台的兼容性,原有客户端上传的数据依旧采用原始流模式。 + 注意:如果同时使用老旧的客户端(2020年6月之前的版本)和新的客户端,老旧客户端无法处理新的流模式。 + +更新日志--------2023-11-17 + 修正:11-16版本在没有funcext路径时可能会出现监控函数变动的线程忙的问题(CPU被占据一个核心)。 + +更新日志--------2023-11-16 + 升级:TSL.INI新增配置 +[WebApp] +;OutErrorFlag .& 1 = 1:Disable out error +;OutErrorFlag .& 2 = 2:Disable write error to logfile +OutErrorFlag=1 +设置为1,不会在WEB端输出运行错误。 + +更新日志--------2023-11-6 + 升级:修正sysgetpidtidofwnd函数将pid当tid返回的问题。 + +更新日志--------2023-11-2 + 升级:修正var ss:=array();ss[1]:=1;会报出错的问题。 + 升级:修正未选择返回内容时间序列数据专家会因生成错误执行串而报错的问题。 + 升级:TSL.EXE支持--runpkg=和--pkg=同时存在,--pkg支持多个包以逗号分隔。 + 升级:修复使用office_plugin时候import/export xls文件时中文乱码以及xlsx无法导出的问题。 + +更新日志--------2023-10-25 + 修正:由于特殊汉字使用CP18030转换失败,默认采用ACP转换。影响包括:L"䶮"的转换,以及wordwritetable内包含特殊此汉字变为问号的问题。 + 升级:TSL编译输出函数参数支持array of double/integer/int64模式,C语言以double*,size_t len模式来调用,默认转换成为FMARRAY。并支持var模式回写。。 + +更新日志--------2023-10-19 + 升级:TSL编译资源的pattern支持,分割,支持*.dfm,*.ini模式。 + +更新日志--------2023-10-18 +*************************************************************************************************************************************** + 升级:支持将TSL代码编译成为可执行文件(windows .exe/linux 可执行),动态链接库(windows .dll/linux .so)。 +*************************************************************************************************************************************** + 升级:升级external执行的效率。 + 修订:FindFunction("a.b")的模式下,如果是查找a类的b类方法,当a类未被使用过时,会存在不正常的问题。 + 修订:FindFunction("a.b")的模式下,如果a类为私有的情况下,无法被查找到的问题。但由于a.b模式最初为unit设计,因而私有a类是特例,而单元a优先,因而全局优先于私有,和其他优先级有差异。查找类方法建议使用FindFunction("b",class(a))模式,这样符合私有优先。 + 修订:无法对数组内的网格使用sum等函数(从加速统计函数以来便一直存在该问题)。 + 修正:内核BUG(影响极小的个别函数对fmarray类型数据处理上的)。 + 修正:betainc等一系列函数在处理fmarray的时候可能报错的问题。 + +更新日志--------2023-09-27 + 修订:commkrnl可能会丢失断开前数据的问题。 + 修订:登录失败可能无法显示错误原因仅显示被断开的问题。 + 升级:JDBC驱动包。 + +更新日志--------2023-09-22 + 修正:代理服务器被选用但未设置客户端可以登录但导致WEB浏览白屏的问题。 + 升级:JDBC支持openforwardonly模式。 + 升级:新函数,通过标题获得窗口列表sysgetwndofcaption(cap:string[,isContainString=true]):array of HWND如果第二个参数为真,则包含字符串,否则为相等。 + 升级:新函数,通过窗口句柄获得进程id和线程id sysgetpidtidofwnd(wnd:HWND:string[,Var ThreadId:Integer]):Integer; + 更正:sysgetpidofcom函数目前仅支持PID<65535的进程。如果PID获取为65535,需通过上述方式获得。例如Excel Application具备hwnd属性,而Word Application具备caption属性修改标题栏。 + +更新日志--------2023-09-20 + 升级:分发支持oa看到网格计算的GID,GID是其启动任务的ID。需要平台升级。 + 升级:支持sysgetpidofcom函数,获得指定COM对象的进程ID。 +范例: +getoleobject("Word.application",0,v); +echo sysgetpidofcom(v); + + 升级:支持ExecSql默认使用openforwardonly的模式,增加0x4000000作为NotOpenForwardOnly模式来取消。 + openforwardonly的模式可以防止访问大结果集的时候数据库数据集占据内存,导致容易形成内存空洞 + + 具体设置方法如下(此选项对ts-sql无效,ts-sql目前要手动设定openforwardonly): +plugin\ExecSql.ini +[ExecSql Config] +ExecSqlForwardOnly=1 +#设置此处则,默认任何别名在EXECSQL均启用openforwardonly模式 +[DBAlias] +ExecSqlForwardOnly=1 +#设置此处则,默认别名DBAlias在EXECSQL均启用openforwardonly模式 + +更新日志--------2023-09-18 + 更新:第三方包的LICENSE信息更新,具体见3rdPartyLicense目录。 + 升级:关于中加入第三方信息。 + 修正:启动tssecurity库的加载项打印的问题。 + +更新日志--------2023-09-17 + 修正:客户端错误检查不报错的问题。 + +更新日志--------2023-09-15 + 升级:Execsql flag或者tssql selectopt 0x8000000 支持openforwardonly。采用此种方式可以让大结果集的访问内存占用大大降低。 + 升级:支持makeinstance 第三个参数,0为单线程,1为多线程单次用于createthread,2为回调多线程,TSL用户可以脱离C++等开发工具直接使用TSL开发多线程以及开发多线程回调函数。 + +更新日志--------2023-09-12 + 修订:formatfloat当格式中存在千分位但区域设定不存在千分位时被截断的问题。 + 升级:提供本地化脚本网格#的多线程调用支持。使用方式和平台网格调用一样,支持本地多线程网格计算,可通过TSL.INI进行配置相关参数。 +TSL.INI +[multitask] +#本地网格计算启动的最大线程数 +maxthread=128 +#最大计算任务的等待队列 +maxpending=16777216 +#未完成的任务等待判断间隔毫秒数 +busyinterval=3000 +#最大等待的次数 +busyretry=100000 + + 修订:内核将函数保存成对象会诱发mymem负数的问题。 + 修订:在类成员函数中使用动态绑定的匿名函数存在问题。 + 修订:array下标里设定fmarray后再次设置该小标的行为会对fmarray赋值的问题。 + 修订:median,large,small,percentile,percentrank,quartile,rank,trimmean以及对应的largeof,sp_large等聚集函数以及数据仓库的事件序列方法在存在NAN的时候的问题。 + 修订:const第二次运行失败的问题。 + +更新日志--------2023-08-31 + 修订::.操作符对数组遍历时break的问题。 + 修订::.操作符导致的?1:.!!2的操作符兼容问题。 + +更新日志--------2023-08-30 + 升级:增加:.算符以及:.=,使用方式和::以及::=一样,对于fmarray而言行为一致,但对于数组而言,不假定维度数,而是对数组的节点进行深度遍历。 + 升级:增加:mfindsparse,对于fmarray而言行为一致,但对于数组而言,不假定维度数,而是对数组的节点进行深度遍历。 + +更新日志--------2023-08-24 + 修订:TinyODBC使用中文DSN时的问题。 + 修订:curl处理邮件里的附件长文件名的编码分行问题。 + 修订:FIREDAC API模式下ORACLE空clob处理错误问题。 + +更新日志--------2023-08-18 + 修订:python模块以及R连接平台的问题。 + +更新日志--------2023-08-17 + 修订:python模块连接平台的问题。 + +更新日志--------2023-08-04 + 修订:报告模板某些调用无法正常的问题。 + 修订:对静态计算过多不再报错,直接使用非静态化计算。 + 修订:office_plugin在大小写方法名上出错的问题。 + +更新日志--------2023-08-02 + 备注:下述升级已经升级至客户端本地解释器以及服务端的新一代测试以及测试版。 + 修订:内核BUG。 + 修订:在进行计算出现错误类型的时候,提示的行号可能是错误的。 + 优化:对+-*/等基础计算进行了百分之几十的效率提升。 + 优化:对minus、outersect等集合运算以及SQL相关的group by,distinct,order by等操作有着从百分之几十到数倍的性能提升。 + 新增:1L->10L模式的支持,同时提供for对64位整数的支持。 + 新增:提供PYTHON 3.12的支持包。 + 新增:新增pn_reporttype()作为底层参数函数。 + 升级:登录认证提供代理服务器支持,并支持SOCKS5模式。TSL下使用:tslclient.ini 里增加ProxyAuthMode=5代表SOCKS5。在python和r语言里,描述代理服务器的数组增加一项,0为HTTP代理,5为SOCKS5代理。 + 升级:connectserver函数当使用proxy参数时,proxy参数数组的"AuthMode"下标为5为SOCKS5模式。 + +更新日志--------2023-07-21 + 升级:完整支持const定义中的常量计算,包括对父类的常量的引用。 + 升级:external支持常量以及常量计算,这样对Linux和Windows跨平台定义起到帮助。 + 修正:TinyODBC的问题。 + 修正:Apache GetContentLength函数以及HTTP...GET...SERVER_NAME的问题。 + 修正:CGI模式下的Session onlineuser获得不了以及INI文件不回收的问题。 + 修正:HTTP请求最大超时只支持1分钟的问题。 + +更新日志--------2023-07-06 + 修正:filterin/filternotin字符串下标数据会被返回数字下标的问题。 + 新增:ansistr2array,支持MBCS字符串的处理。 + 升级:TinyODBC驱动。 + 修正:libcurl版本的邮件发送附件文件名过长的时候可能会存在某些版本邮件客户端无法正确解析问题。 + 修正:COM调用属性和方法同名失败的问题。 + +更新日志--------2023-06-21 + 修正:round/roundto对inf的问题。 + 修正:管理器在递归时在相应函数的根打开不了的问题。 + 升级:函数编辑器新增缺省参数支持,运行需要新一代平台和新一代终端和解释器支撑。 + +更新日志--------2023-06-20 + 修正:globalcache问题。 + 升级:新增dbgloginasync,loginserverasync函数,...async(channel,user,pwd[ver:double=8.88])。 + 升级:支持rdo2以及网格计算的命名参数。 + +更新日志--------2023-06-16 + 修正:pycall直接调用失败未做失败返回的问题。 + 升级:内核升级。 + 升级:python pycall直接支持命名参数。 + pycall("numpy.random","randint",low:200,high:900) + 升级:python以及COM对象调用支持命名参数。 + 升级:TSL全面直接支持函数及类方法缺省参数定义以及命名参数调用,二进制实现的类或函数需要本身实现支持。 +abcd(); +abcd(2,d:99,c:88); //直接命名调用 +call("abcd",2,d:88,c:99); //支持call命名构造 +c:=new cc(10,c:99); //new 构造支持缺省以及命名 +c.bbb(1,e:999);//类方法命名调用 +c:=createobject("cc",10,c:9988);//支持createobject命名构造 +function abcd(a,b="bbb",e,c,d) //缺省定义 +begin + echo "a:",a," b:",b," e:",e," c:",c," d:",d,"\r\n"; +end; + +type cc=class + public + function create(a,b=100,c); //构造缺省定义 + begin + echo "a:",a," b:",b," c:",c,"\r\n"; + end; + function bbb(a,b=-100.0,c,d,e) //类方法缺省定义 + begin + echo "a:",a," b:",b," c:",c," d:",d," e:",e,"\r\n"; + end; +end; + +更新日志--------2023-06-08 + 修正:用户定义的多选列表参数问题。 + 修正:python调用失败未做失败返回的问题。 + 升级:python pycall支持在数组中送入字符串下标作为命名参数。 + 升级:python在FileMgr.ini里[python Config] Unicode=整数 这个整数可以控制unicode行为,如果Unicode .& 2 为真,则TSL的ansi串直接转为unicode给PYTHON,如果 UniCODE .& 1 为真,则Python的unicode串直接转为TSL的unicode串 + 升级:新增office_plugin支持直接对xlsx,docx等直接读写操作。 + +更新日志--------2023-05-22 + 修正:债券市场更新有时候会导致客户端极慢的问题。 + 修正:apache模块的问题。 + 修正:其他内核修正。 + 升级:JDBC升级。 + +更新日志--------2023-04-25 + 修正:函数管理器里排序后查找定位问题。 + +更新日志--------2023-04-24 + 升级:支持字符串结果类型显示窗口对字符串的查找。 + 修正:TSLPy35.pyd的问题。 + +更新日志--------2023-04-11 + 修正:管理器查找在排序时的定位问题。 + +更新日志--------2023-04-10 + 修正:批量导入加密函数并去除加密函数体引发的问题。 + 修正:管理器查找当存在排序时定位问题。 + 修正:帮助文件前置的问题。 + +更新日志--------2023-04-07 + 修正:下拉选择板块,一旦当前节点是板块,展开其他节点会导致下拉关闭。 + 修正:帮助支持CTRL+C的操作。 + 升级:批量导入导出函数支持进行加密解密操作。 + 升级:管理器支持递归显示子目录内的函数(由于函数数量原因,如果选中公用函数这种可能会极慢),方便用户对时间排序等操作获得最新的更新函数。 + 升级:在线升级对话框将同时显示在线升级的whatsnew文件。 + 修正:API模式下对ORACLE的CLOB/NCLOB支持的瑕疵。 + + +更新日志--------2023-03-09 + 修正:imap.ListFolders存在解析不正确的情况。 + +更新日志--------2023-03-05 + 修正:cpu忙的问题。 + +更新日志--------2023-02-28 + 修正:firedac数据库连接以及其他内核修正。 + +更新日志--------2023-02-22 + 升级:Apache模块参数解析问题。 + 升级:sysparamstr中文参数问题。 + 升级:JDBC驱动。 + 升级:加入poco版本数据库驱动支持。 + +更新日志--------2023-02-17 + 升级:数组*维度更多的fmarray的行为和数组*数组一致。 + 升级:makeinstance支持多线程回调,调用在TSL的makeinstance所在线程内调用完成。 + 新增: setfilemode,getfilemode,fileattrtostr,filemodetostr,strtofileattr,strtofilemode + 新增:ExecSQL以及ts-sql新增jdbc的支持,支持数据库别名使用JDBC连接数据库的模式。 + +更新日志--------2023-02-15 + 修订:[:]:=一个数组会导致右边的数组在copyonwrite模式下字符串内容出错。 + 新增:weakref,[weakref],autoref,[autoref]支撑,支持weak指针。 + +更新日志--------2023-2-7 + 修正:向导里右键的向导函数无法正常工作的问题。 + +更新日志--------2023-1-30 + 修正:修订Windows版本SetFileAttr和GetFileAttr保持和WindowsAPI一致。(新一代以及Linux版本新增SetFileMode和GetFileMode来兼容LinuxAPI) + +更新日志--------2022-12-29 + 修订:循环echo这类操作阻塞客户端通讯的问题。 + +更新日志--------2022-12-2 + 修订:本地ECHO不起效。 + 升级:其他关于fmarray的问题。 + 升级:支持findoverload。 + +更新日志--------2022-11-3 + 修正:10-27日版本API Firedac模式下内存泄漏问题。 + +更新日志--------2022-10-27 + 修正:API Firedac模式下Decimal类型超大数据越界导致的转换错误,可能诱发崩溃的问题。 + +更新日志--------2022-10-24 + 升级:客户端函数编辑器支持TAB移动切换函数的次序。 + 升级:函数编辑器打开函数会默认打开当前的函数所在的目录。 + 升级:日期时间的选择组件升级,支持保存时间序列专家里的时间起止值。 + 修订:在结果页面中搜索,不勾选“区分大小写”的行为区分大小写的问题。 + +更新日志--------2022-10-20 + 升级:客户端函数颜色确认后将保存。 + +更新日志--------2022-10-20 + 升级:客户端支持函数编辑器的颜色设定。 + 升级:数组采用copyonwrite模式,只读时采用数组引用不再复制数组,写时进行数组复制。 + 升级:内核升级,大大提升数组统计函数的效率。 + ---------注意,目前已知冲突是对存贮网格的数组进行复制将无法阻塞,需要采用dupvalue函数进行阻塞---------------- + 修正:当参数设定转换浮点数字17、18位时进行特定转换。 + +更新日志--------2022-08-23 + 修正:floattostr,tostn保留浮点最多15位有效数字。 + +更新日志--------2022-08-09 + 修正:curl处理邮件当HEADER分割多行时的问题。 + +更新日志--------2022-08-03 + 修正:productof不支持多字段聚集。 + 修正:debugreturn返回的内容不正确的问题。 + +更新日志--------2022-07-30 + ===============下一代TSL语言测试开始==================== + 下一代TSL语言进入测试阶段,可以计算设置里服务选择下一代全新测试 + 下一代TSL语言的内核以及函数库进行了重新开发,提高了TSL的性能,支持WINDOWS和LINUX,并支持ARM64架构以及准备陆续支持更多的CPU架构 + 下一代TSL语言对数组的使用上,采用高性能模式,防止因为大量数组拷贝造成的低效问题 + 下一代TSL语言会提供一些新的特性,这些新特性有的和当前的TSL版本同时支持,有的仅为下一代提供支持 + 虽然天软已经在下一代TSL版本进行了持续两年的陆续测试,并已经通过全部天软自己内部TEST CASE,但不排除存在一些未能测试覆盖的问题 + 如若测试中发现任何问题,请及时反馈。 + +更新日志--------2022-07-30 + 修订:rank,percentrank,rankof,percentrankof在对重复值保持和EXCEL同样地结果。 + 修订:exportjsonstring支持直接使用globalcache。 + 修订:不再主动进行TBB内存回收。 + 修正:ORACLE API连接可能出现错误的断言。 + +更新日志--------2022-06-23 + 修订:编辑器里语法解析在某些特殊场景下出错。 + 修订:libcurl.dll更新为libcurl-tsl.dll,避免在apache上和同名库的冲突。 + 修订:极特殊的错误写法导致问题的两个内核BUG修订(不修订也不影响正常使用)。 + 修订:日期转换失败导致的数据库执行错误,错误场景:PG存贮的日期可能存在异常数据导致对TSL日期转换不合规。 + +更新日志--------2022-05-31 + 修订:在uses的时候进行函数调用,不再重复查找已确认不存在的全局TSF函数,解决WEB模式下因为本地函数数量巨大引发的查找性能问题。 + 修订:确认算符优先级-2^4为-16,也就是说和其他语言保持一致,使得求幂的优先级高过-,另外-2147483648常量不再支持,应该和C++头定义一样写成-2147483647-1 + 修订:对于-(-2147483647-1)的操作的结果变为浮点数。(对应为0-)越界的操作。 + 修订:sqlopt(16384)下向后移动存在问题。 + 升级:新增IMAP类,支持IMAP协议。 + +更新日志--------2022-04-21 + 升级:函数编辑器的结构树内增加对成员变量以及property的支持。 + +更新日志--------2022-03-30 + 升级:curl版本的网络函数的增强。 + 升级:增加Python3.10和3.11支持库。 + +更新日志--------2022-03-24 + 修正:在界面直接输出Excel的时候,第一个SHEET名称是SHEET2的问题。 + 修订:技术图形的横坐标线位置偏离且X坐标的值显示异常的问题。 + 修订:为显示方便表格固定列数被限定。 + +更新日志--------2022-03-24 + 修正:日期时间参数无法键盘输入日期的问题。 + 升级:向导的滚动窗口支持鼠标卷滚键。 + 修正:新升级新建用户数据可能会进入编辑目录状态的问题。 + 修正:用户数据排序问题。 + +更新日志--------2022-03-24 + 升级:因客户使用用户数据数量较大,导致原有平板式用户数据管理无法满足需求,对管理器中的用户数据管理做出升级如下: + 支持类似于函数、板块的按目录显示。 + 支持新建,更名目录名等。 + 带路径的用户数据在SaveTable ,LoadTable的时候必需带全路径(\分隔)才可访问。 + 修正:管理器中某些带路径删除会中途出错的问题。 + +更新日志--------2022-03-22 + 修正:某些板块无法选中的问题。 + 修正:ADO模式下由于数据库驱动不完善所导致的MYSQL TIME类型的值被包括了日期的问题。 + 升级:市场板块支持搜索。 + 升级:在导入数据的时候如果输入XLS等类型而对话框未打开选项时显示选项而非关闭。 + 升级:TSL代码调试和WEB调试的功能修正。 + 修正:当升级的时候修正退出WORD等程序的提示信息。 + +更新日志--------2022-03-19 + 升级:内核支持TSL.EXE和WEB服务调试功能。 + 升级:支持全局缓存功能。 + 升级:调试器支持对象调试功能。 + 升级:新增libcurl为核心的HTTP,FTP,POP3,SMTP等功能,HTTP支持PROXY,会话,COOKIE等功能。 + 修正:客户端调试器下打开数据后关闭编辑器导致异常的问题。 + 修订:ZIP文件处理的中文文件名问题。 + 修订:其他内核修订问题。 + +更新日志--------2021-11-23 + 升级:客户端库支持tostm(Data,1)可以转换为新格式的流文件。平台功能升级。 + 修正:非完全矩阵的计算可能会出现重复计算的可能性。(对于使用非完全矩阵进行四则运算的影响级别高,必需升级) + +更新日志--------2021-11-18 + 升级:优化提升管理器打开的效率。 + 升级:优化数据向导的打开效率。 + 升级:新增对matlab r2021b的支持。 + 更新日志--------2021-11-7 修正:全局查找地内容点击当前函数行号会出错地问题。 升级:优化提升客户端登陆过程的效率。