SUGGESTION aux concepteurs de PB sur la gestion des chaînes

Vous avez une idée pour améliorer ou modifier PureBasic ? N'hésitez pas à la proposer.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

SUGGESTION aux concepteurs de PB sur la gestion des chaînes

Message par PAPIPP »

SUGGESTION aux concepteurs de PB sur la gestion des chaînes de caractères entre un prg principal et une procédure
La valeur ou adresse de la chaîne est passée par procedurereturn comme exemple ci-dessous

Code : Tout sélectionner

Macro __HT(__HQ)
  "$"+RSet(Hex(PeekQ(@__HQ+2),#PB_Quad),16,"0")+RSet(Hex(PeekC(@__HQ+1),#PB_Byte),2,"0")+RSet(Hex(PeekC(@__HQ),#PB_Byte),2,"0")
EndMacro
Structure stt
  StructureUnion
    st.s{1}[10]
    st10.s{10}
  EndStructureUnion
EndStructure
Global s1.stt
s1\st10="1234506789"
s1\st[5]=Chr(0)
Debug " st10="+__ht(S1\st10)+" @st10="+Str(@S1\st10)

Procedure.s procs()
  s.s=Space(10)
  CopyMemory(@s1,@s,10)
  Debug "s="+__ht(s)+" @s="+Str(@s)
  ProcedureReturn s
EndProcedure
Procedure.s procsf()
  sf.s{10}=Space(10)
  CopyMemory(@s1,@sf,10)
  Debug "sf="+__ht(sf)+" @sf="+Str(@sf)
  ProcedureReturn sf
EndProcedure
Ss.s=procs()
Debug "ss="+__ht(ss)+" @ss="+Str(@ss)
sfp.s{10}=procsf()
Debug "sfp="+__ht(sfp)+" @sfp="+Str(@sfp)

1) Sur les chaînes non fixe type : s.s ou ch$
On peut remarquer qu’une chaîne non fixe créée ou copiée dans un sous programme, a la même adresse que celle passée au prg principal
Elle peut donc être modifiée dans le prg principal alors que nous ne maîtrisons pas sa création.
Ce qui veut dire que si nous modifions cette chaîne elle sera remise dans le premier état si on appel le sous prg
Par ailleurs on peut remarquer que la chaîne de longueur 10 n’a pas été tronquée ce qui est normal puisque l’adresse est la même

2) sur les chaînes fixes type sf.s{10}
Cette chaîne est bien recopiée et tronquée ce qui est conforme à la gestion des chaînes de caractères
Remarques ; alors que dans la chaîne non fixe on peut accéder au informations après null chr(0) ce qui n’est pas le cas dans une chaîne fixe. Hormis la remarque précédente le travail sur les deux chaînes sera identique

3) En conclusion
Les routines ASM qui affectent les deux chaînes sont différentes
Pour chaîne non fixe

Code : Tout sélectionner

Ss.s=procs()
	PUSH	 dword [_PB_StringBasePosition]
	CALL	 _Procedure0
	PUSH	 dword v_Ss
	CALL	 _SYS_AllocateString4@8
Pour chaîne fixe :

Code : Tout sélectionner

sfp.s{10}=procsf()
	PUSH	 dword [_PB_StringBasePosition]
	CALL	 _Procedure2
	LEA	 eax,[v_sfp]
	PUSH	 dword 10
	CALL	 _SYS_AssignFixedString@8
Imaginons que la routine pour chaîne fixe passe tous les caractères sur la longueur donnée sans les tronquer ce qui est sans incidence sur la suite du traitement puisque cela existe déjà sur les chaînes non fixe
On pourrait passer des structures complexes entre prg principal et sous/prg par exemple

Code : Tout sélectionner

Structure lf
ww.w
qq.q
EndStructure
Structure xx
StructureUnion
 Ch.s{10}
Zone_str_complex.lf
EndStructureUnion
EndStructure
Pouvez_vous modifier la routine _SYS_AssignFixedString@8 de façon à ce qu'elle puisse passer tous les caractères sur la longueur donnée?
Cela donnerait une forte potentialité à PB et l'on pourrait passer des structures complexes entre prg et sous/prg

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: SUGGESTION aux concepteurs de PB sur la gestion des cha

Message par Ollivier »

Salut PAPIPP,

J'ai beaucoup de mal à comprendre. Je vais essayer de débroussailler. Et je me permets, par la même, de te demander d'accepter mes excuses pour la dernière fois où l'on s'est embrouillé : ce n'était bien évidemment pas utile.

Ollivier
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: SUGGESTION aux concepteurs de PB sur la gestion des cha

Message par Ollivier »

Pour l'instant, je ne saisis pas l'avantage par rapport à ce type classique de syntaxe:

Code : Tout sélectionner

Structure lf
ww.w
qq.q
EndStructure
Structure xx
StructureUnion
Ch.s{10}
Zone_str_complex.lf
EndStructureUnion
EndStructure

Procedure Proc(*Mem.xx)
      
EndProcedure

Mem.xx

Proc(Mem)
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: SUGGESTION aux concepteurs de PB sur la gestion des cha

Message par PAPIPP »

Merci Ollivier de ta réponse.
Tu as tout à fait raison mais ma demande ne porte pas sur le type de syntaxe d'une structure mais sur la possibilité de passer une structure >8 bytes et qui peut comporter des $00.
Sur le forum anglais Fred m’a demandé des explications voici les explications que j’ai fournies :

http://www.purebasic.fr/english/viewtop ... =3&t=43530

Toutefois il me semble que cela n’est pas encore assez clair.
Voici une autre explication.

Il existe dans PB 2 types de chaînes de caractères :
1) une chaîne libre limitée par $00 ex: CAR.s
2) une chaîne fixe dont on connaît la longueur ex : car.s{20}
Toutes les expériences que j’ai réalisées démontrent 2 problèmes mineurs mais intéressants.

1) Sur les chaînes libres en passage par valeur entre un sous/prg et le prg/principal c’est l’adresse qui est passée et non une copie de la valeur (risque d’écrasement des données si l’on ne recopie pas immédiatement. Il faut que le programmeur le sache) ceci est anecdotique mais ce n’est pas là l’objet de ma demande

2) Sur les chaînes fixes en passage par valeur entre un sous/prg et le prg/principal c’est bien la copie qui est envoyée au prg/principal mais il y a un mais. Malgré la connaissance de la longueur la chaîne est tronquée lorsque le système rencontre $00 conformément au principe adoptée sur les chaînes libres. Or cette contrainte n’est pas nécessaire sur ce type de chaîne puisque la chaîne est limitée par sa longueur connue.

Si cette restriction était levée et c’est l’objet de ma demande c'est-à-dire que l’on aurait une copie identique et de même longueur.

On pourrait passer entre un sous/prg et prg/principal des structures complexes comportant des $00
Avantage des passages par valeur en utilisant dans la structure une chaîne fixe:
1) Indépendance totale (autre adresse) ente sous/prg et prg/principal (moins de risque d’écrasement)
2) Possibilité des passer en sortie de sous/prg des structures complexes > 8 bytes ce qui est impossible actuellement.

EXEMPLE :
Nous pourrions réaliser une routine de conversion de type W L I F D Q ou T en copie de valeur
C'est-à-dire un sou /prg qui passe une structure complexe en sortie de la façon suivante
Alors que la routine qui fonctionne actuellement fonctionne par adresse et non par valeur
La routine rêvée fonctionnerait avec des infos passées en valeur plus simple
Ici les deux routines

Code : Tout sélectionner

Macro __HT(__HQ)
"$"+RSet(Hex(PeekQ(@__HQ+2),#PB_Quad),16,"0")+RSet(Hex(PeekC(@__HQ+1),#PB_Byte),2,"0")+RSet(Hex(PeekC(@__HQ),#PB_Byte),2,"0")
EndMacro
Structure ten
  vq.q
  vw.w
EndStructure
Structure lf
  StructureUnion
    fword.w[5]
    tbyte.b[10]
    vw.w[5]
    vu.u[5]
    vc.c[10]
    vb.b[10]
    vs10.s{10}
    vs.s{1}[10]
    vt.ten
  EndStructureUnion
EndStructure

; Routine classique en passage par adresse difficile pour imbriquer  comme F(G(H(j)))

Procedure convx2lf(*x.lf, *y.q, typ.s = "quad")
  ; avec Word, Integer, Long, Float simple, D flot double ,Quad, Ten routine de conversion entre une forme W,L,F,D,I,Q,T en Lf 
  ; forme flottant Intel sur 80 bits 10 Bytes ou 10 octets
  tp.s{1} = Mid(UCase(Trim(typ)), 1, 1)
  FINIT
  MOV ebx, *y
  Select tp
    Case "W" ;en 16 bits
      FILD word[ebx]
    Case "L" ; en 32 bits
      FILD dword[ebx]
    Case "I" ; en 32 bits
      FILD dword[ebx]
    Case "F" ; en float simple précision 32 bits
      FLD dword[ebx]
    Case "Q" ; en 64 bits
      FILD qword[ebx]
    Case "D" ; en 64 bits
      FLD qword[ebx]
    Case "T" ; en 80 bits
      FLD tword[ebx]
  EndSelect
  MOV ebx, *x
  FSTP tword[ebx]
EndProcedure

; Routine révée en passage pour des valeurs > 8 bytes dans une structure complexe trés facile pour imbriquer  comme F(G(H(j)))

Procedure.s conv_x2lf(y.q, typ.s = "quad")
  ; avec Word, Integer, Long, Float simple, D flot double ,Quad, Ten routine de conversion entre une forme W,L,F,D,I,Q,T en Lf 
  ; forme flottant Intel sur 80 bits 10 Byte ou 10 octets
  Define x.lf
  tp.s{1} = Mid(UCase(Trim(typ)), 1, 1)
  FINIT
  LEA ebx,dword[p.v_y]
  Select tp
    Case "W" ;en 16 bits
      FILD word[ebx]
    Case "L" ; en 32 bits
      FILD dword[ebx]
    Case "I" ; en 32 bits
      FILD dword[ebx]
    Case "F" ; en float simple précision 32 bits
      FLD dword[ebx]
    Case "Q" ; en 64 bits
      FILD qword[ebx]
    Case "D" ; en 64 bits
      FLD qword[ebx]
    Case "T" ; en 80 bits
      FLD tword[ebx]
  EndSelect
  LEA ebx,dword[p.v_x]
  FSTP tword[ebx]
  ProcedureReturn x\vs10
EndProcedure

Define sortie.lf
qq.q=1234567890

sortie\vs10=conv_x2lf(qq)
Debug "sortie type lf="+__ht(sortie\vs10)+" @sortie\vs10="+Str(@sortie\vs10)

;POUR LA ROUTINE QUI FONCTIONNE ACTUELLEMENT

convx2lf(@sortie\vs10, @qq, "quad")
Debug "sortie type lf="+__ht(sortie\vs10)+" @sortie\vs10="+Str(@sortie\vs10)
; la routine en passage par valeur est plus simple d'utilisation et il y a moins de risque d'effet de bord écrasement par un autre programme
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: SUGGESTION aux concepteurs de PB sur la gestion des cha

Message par Ollivier »

Mais quand tu sors une valeur d'une procédure avec ProcedureReturn, tu quittes bien cette même procédure: où serait l'avantage d'une copie de donnée, puisque l'originale n'est plus utile dans la procédure échue?
PAPIPP a écrit :Sur les chaînes fixes en passage par valeur entre un sous/prg et le prg/principal c’est bien la copie qui est envoyée au prg/principal mais il y a un mais. Malgré la connaissance de la longueur la chaîne est tronquée lorsque le système rencontre $00 conformément au principe adoptée sur les chaînes libres. Or cette contrainte n’est pas nécessaire sur ce type de chaîne puisque la chaîne est limitée par sa longueur connue.
Je pense au contraire que cette contrainte est nécessaire. Maintenant, je n'en ai pas la preuve.

Je ne comprends pas qu'est-ce qui te rebute avec les pointeurs. Un traitement de données en ASM qui serait accompagné d'une copie de mémoire n'annihile-t-il la vitesse d'exécution des opérations?
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: SUGGESTION aux concepteurs de PB sur la gestion des cha

Message par PAPIPP »

Merci Ollivier de ta réponse.
J’avais déjà anticipé les remarques que tu fais. Et c’est pourquoi ma demande n’était pas claire.

Pour l’élégance de la programmation je préfère les formes explicites du type y=f(x) à la place des forme implicites f(x,y)=0
Elles permettent d’affecter immédiatement une valeur à une info, d’imbriquer les fonctions. Elles sont beaucoup plus souples et plus sûres d’emploi que les fonctions implicites et elles ressemblent aux instructions de PB.

Prenons l'exemple d'une addition sur une structure flottant étendu sur 80 bits interne à Intel.
Essayons de réaliser une addition de type X=A+B+C avec la forme implicite.
Avec cette forme et afin de ne pas alourdir ce post je prends la routine de conversion que j’ai placée dans le précédent post tout en fonction implicite. Ces routines sont extraites d’une de mes lib qui sont toutes en fonctions implicites.(environ 60 routines) Je ne suis pas rebuté par les pointeurs bien au contraire .mais l’imbrication des fonctions est impossible ce qui n’est pas le cas pour une fonction explicite.
Soit une fonction ADD(X,Y,Z) avec X premier paramètre comme résultat et avec pour objectif (X=A+B+C)
on a Add(X,A, Add(X,B,C) si l’écriture est possible, l’exécution est impossible puisque Add(X,B,C) ne sort qu’une valeur 0 ce qui provoque une erreur à l’exécution. On sera donc obligé pour l’opération X=A+B+C d’utiliser une variable intermédiaire Y qu’il faudra définir ou d’utiliser 2 fois la variable X.
De plus l’adresse du résultats est un paramètre que certains auteurs placent soit en premier soit en dernier .et les erreurs de syntaxe ne sont pas rares.(Il faut souvent faire référence à la documentation)
Tout ceci me parait lourd.

Alors pour éviter cette lourdeur j’ai essayé de sortir par adresse une fonction explicite ADD appelé ici lfadde
Exemple sur l’addition

Code : Tout sélectionner

Procedure.l lfadde(*y.lf,*z.lf);x=y+z
  ;  Protected x.lf
  Static x.lf
;****************************************************************************************************************
;   Pour utiliser les infos Pb dans ASM suivant les différents cas observez les consignes suivantes
;                 ATTENTION RESPECTER la CASSE sinon erreur dans ASM
;               ; Attention noninfo avec global     v_nominfo
;               ; Attention noninfo avec static     s_nomprocedure.v_nominfo
;               ; Attention noninfo avec protected  p.v_nominfo
;               ; Attention noninfo avec share      v_nominfo
;               ; Attention noninfo avec rien       p.v_nominfo
;                                            attention pour les pointeurs remplacer v_ par p_
;****************************************************************************************************************
  FINIT
  MOV ebx,*z
  ! fld tword [ebx]
  FST st1
  MOV ebx,*y
  ! fld tword [ebx]
  FADD st0,st1
  ;   MOV ebx,*x
  ! fstp tword [s_lfadde.v_x]
  ProcedureReturn @x
EndProcedure
J’ai essayé d’utiliser l’option protected mais j’ai eu des pertes d’info que je n’ai pas trop approfondies c’est pourquoi j’utilise Static. .L’imbrication est possible mais il faut faire très attention à la priorité dans l’exécution les opérations et les écrasements de valeurs sont courantes car l’adresse est toujours la même
Il faut donc sauvegarder les résultats s’ils peuvent encore servir après chaque groupe d’opération
Avec par exemple copymemory(*source, *destination, longueur) mais cela est un peu lourd

L’exemple suivant le montre :

Code : Tout sélectionner

Structure ten
  vq.q
  vw.w
EndStructure
Structure lf
  StructureUnion
    fword.w[5]
    tbyte.b[10]
    vw.w[5]
    vu.u[5]
    vc.c[10]
    vb.b[10]
    vs${10}
    vs.s{1}[10]
    vt.ten
  EndStructureUnion
EndStructure

ProcedureDLL.s _mh(*ad,lng)
  For i=0 To lng-1
    num.q=PeekC(*ad+i)
    cart$=cart$+Chr(num)
    hexs.s=hexs.s+RSet(Hex(num),2,"0")+" "
  Next
  ;   sort.s=RSet(Hex(*ad),8,"0")+"  "+hexs+ "    "+cart$
  sort.s="$"+Hex(*ad)+" "+hexs+"  "+cart$
  ProcedureReturn sort
EndProcedure

Procedure lf2lf(*x.lf,*y.quad,typ.s="quad")
  tp.s{1}=Mid(UCase(Trim(typ)),1,1)
  FINIT
  MOV ebx,*y
  Select tp
    Case "W" ;en 16 bits
      FILD word[ebx]
    Case "L" ; en 32 bits
      FILD dword[ebx]
    Case "I" ; en 32 bits
      FILD dword[ebx]
    Case "F" ; en float simple précision 32 bits
      FLD dword[ebx]
    Case "Q" ; en 64 bits
      FILD qword[ebx]
    Case "D" ; en 64 bits
      FLD qword[ebx]
    Case "T" ; en 80 bits
      FLD tword[ebx]
  EndSelect
  MOV ebx,*x
  FSTP tword[ebx]
EndProcedure
Procedure lfadd(*x.lf,*y.lf,*z.lf);x=y+z
  FINIT
  MOV ebx,*z
  ! fld tword [ebx]
  FST st1
  MOV ebx,*y
  ! fld tword [ebx]
  FADD st0,st1
  MOV ebx,*x
  ! fstp tword [ebx]
EndProcedure
Procedure.l lfadde(*y.lf,*z.lf);x=y+z
  ;  Protected x.lf
  Static x.lf
;****************************************************************************************************************
;   Pour utiliser les infos Pb dans ASM suivant les différents cas observez les consignes suivantes
;                 ATTENTION RESPECTER la CASSE sinon erreur dans ASM
;               ; Attention noninfo avec global     v_nominfo
;               ; Attention noninfo avec static     s_nomprocedure.v_nominfo
;               ; Attention noninfo avec protected  p.v_nominfo
;               ; Attention noninfo avec share      v_nominfo
;               ; Attention noninfo avec rien       p.v_nominfo
;                                            attention pour les pointeurs remplacer v_ par p_
;****************************************************************************************************************
  FINIT
  MOV ebx,*z
  ! fld tword [ebx]
  FST st1
  MOV ebx,*y
  ! fld tword [ebx]
  FADD st0,st1
  ;   MOV ebx,*x
  ! fstp tword [s_lfadde.v_x]
  ProcedureReturn @x
EndProcedure
Procedure.s LF_DECOMPOS(*y.lf,SIG=0)
  Define M.lf,md.d,E.w
  !fninit ;
  MOV ebx,*y
  FLD tword[EBX]
  !fxtract ;Extrait  la Valeur de la Mantisse (st0) et l' Exponsant (st1) en base 2
  !fstp qword[p.v_md] ;Mantisse
  !fistp word [p.v_E] ;Exposant
  expo$=Str(E)
  mantd$=StrD(md,18)
  ProcedureReturn mantd$+"*"+expo$+"  ="+StrD(md*Pow(2,e))
 EndProcedure 
  Define X.lf,A.lf,B.lf,C.lf,Y.lf,es.lf,*TE.lf,*XE.lf; pour fonction explicite
  AD.D=12345.67E10
  BD.D=14567.89E10
  CD.D=00975.86E10
  Debug lf2lf(@A,@AD,"D") ; résultat du debug dépend de la valeur du procedurereturn ici 0
         lf2lf(@B,@BD,"D")
         lf2lf(@C,@CD,"D")
  Debug lfadd(@Y,@B,@C)  ;; résultat du debug dépend de la valeur du procedurereturn ici 0
         lfadd(@X,@Y,@A)
  Debug _mh(@x,10)
  ;essai d'imbrication avec des fonctions implicites
  ; lfadd(@x,@A,lfadd(@X,@B,@C)) ; impossible d'imbriquer des fonctions implicites (Accès mémoire invalide  erreur de lecture à l'adresse ..
  Debug *xe
  
  ; en imbriquant les fonctions  c'est nettement moins lourd 
  *xe=lfadde(lfadde(@A,@B),@c) ; ici cela fonctionne très bien mais on ne peut conserver le résultat sans le sauver car ...
  Debug "********** val de *XE ***********"
  Debug lf_decompos(*xe)
  Debug _mh(*xe,10)

  
  *YE=lfadde(@B,@A) ; fonction explicite avec passage par adresse
  Debug "********** val de *YE ***********"
  Debug lf_decompos(*YE)
  Debug _mh(*Ye,10)
  ; mais que devient *XE? La valeur a été écrasée c'est normal puisque nous avons la même adresse pour *XE et *YE
  Debug "********** val de *XE écrasé ***********"
  Debug lf_decompos(*XE)
  Debug _mh(*Xe,10)



En conclusion:

1) les fonctions implicites ne peuvent être imbriquées, ce qui alourdi la programmation
Leur mise en œuvre demande plus d’effort.

2) les fonctions explicites avec transfert du résultat par adresse peuvent être imbriquées en respectant les priorités, mais le résultat doit être sauvegardé avant d’utiliser à nouveau cette fonction, car la valeur précédente sera écrasée.

3) les fonctions explicites avec transfert par valeur sont les plus souples, les plus sûres et les plus faciles à mettre en œuvre. J’attends donc cette possibilité pour des zones >8 bytes et pouvant comporter $00 au moins en sortie(*1) de fonction
car en entrée je n'ai pas étudié le cas. Mais si cela pouvait être fait ce serait le TOP
Je pense au contraire que cette contrainte est nécessaire. Maintenant, je n'en ai pas la preuve.
Je me suis aussi posé cette question.
Tout d’abord j’ai montré dans le premier post que pour passer une chaîne libre et bien que le programmeur utilise le passage par valeur en sortie c’est une adresse qui est passée. Donc toutes les fonctions string seront bien limitées par $00. et les opérations sur cette chaîne donnent les mêmes résultats corrects
Par contre ce que je demande c’est la modification de la routine de copie des chaînes FIXE " _SYS_AssignFixedString@8" que j’ai trouvé à la sortie de la routine pour assigner la valeur à la variable externe à la routine et c’est la seule modification que je demande ce qui n’aurait aucune incidence sur les autres fonctions string puisque les fonctions string fonctionnent bien sur les chaînes libres qui ne sont limitées que par $00(*1).
J’ai réalisé des essais sur les chaînes FIXES (les libres fonctionnent très bien) mais je n’ai pas trouvé de bug (prg ici) donc la demande est réalisable.

Code : Tout sélectionner

; Conversion mémoire sortie Hexa
Procedure.s _mh(*ad,lng)
  For i=0 To lng
    num.c=PeekC(*ad+i)
    cart$=cart$+Chr(num)
    hexs.s=hexs.s+RSet(Hex(num),2,"0")+" "
  Next
  sort.s=RSet(Hex(*ad),8,"0")+"  "+hexs+"    "+cart$
  ProcedureReturn sort
EndProcedure
;                 1         2         3         4         5         6         7         8         9         10
; 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
b.s{100}="12345678901234567890 purebasic est le meilleur langage purebasic est très bon 12345678901234567890 +"
; b.s{10}="1234567890"
Debug _mh(@b,100)
Gosub routinestr
LEA eax,dword[v_b]
XOR bx,bx
MOV[eax+50],bx
Debug "*********************** La chaine fixe a en position 50 $0000 *********************************"
Debug _mh(@b,50)
Debug _mh(@b+51,50)

Gosub routinestr

End
routinestr:
Debug "         1         2         3         4         5         6         7         8         9         10"
Debug "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"

Debug b +"   long="+Str(Len(b))
Debug "CountString(B,'bon 1234567')="+Str(CountString(B,"bon 1234567"))
Debug "FindString(B,'purebasic',50)="+Str(FindString(B,"purebasic",50))
; Debug "InsertString(B,'FFFFF',50)="+Str(InsertString(B,"FFFFF",50))
Debug "RemoveString(B,'purebasic')="+RemoveString(B,"purebasic")
Debug "ReplaceString(B,'purebasic','PB',#PB_String_NoCase,50)="+ReplaceString(B,"purebasic","PB",#PB_String_NoCase,50)
Debug "ReverseString(B)="+ReverseString(B)
Debug "StringByteLength(B)="+Str(StringByteLength(B))
For i=1 To 15
  Debug "StringField(B,i,' ') i="+Str(i)+" "+StringField(B,i," ")
Next
Debug "LCase(B)="+LCase(B)
Debug "RSet(B, 110 ,'_')="+ RSet(B, 110 ,"_")

Debug "LSet(B, 110,'_')="+ LSet(B,110,"_")
Debug "UCase(B)="+UCase(B)
Debug "Right(B, 60)="+Right(B,60)
Debug "Left(B, 60)="+ Left(B, 60)
Return

De toute manière ceci n’est pas de notre ressort mais de celui des concepteurs de PB qui doivent faire des essais.
Ceci fait aussi partie de la demande mais à priori il n'y a pas de problème.

(*1) la routine " _SYS_AssignFixedString" bien qu'elle connaisse la longueur de chaîne à copier s'arrête de copier lorsqu'elle
rencontre $00. Je demande simplement que cette routine copie tout ce qu'elle rencontre sur la longueur demandée.

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Répondre