Silverfrost Forums

Welcome to our forums

List Select (%ls) - How to get the selection

2 Mar 2019 11:30 #23302

I know by using this control that you specify a variable that has the number of the item currently selected.

My question is: Is there a clearwin_info@() call that can give me this same number?

I would use a %ud approach, but I need that for another variable that is affected by the item selected.

I've done an exhaustive search in cwplus.enh and the help file, but alas, no joy. If the answer is that there is not one, so be it.

TIA, Bill

3 Mar 2019 7:23 #23308

Try clearwin_info@('THIS').

It would be useful if %ud could point to a user TYPE so that multiple data items could be accessed from one address. I will see if this can easily be implemented.

3 Mar 2019 11:43 #23309

Paul, 'THIS' does not work.

I have thought long and hard about how to use the %ud for a type. One issue is that a pointer has (for everything else other than numbers) a complex 'structure' underneath to support. That being said, the first element in a pointer is always the actual pointer value. But there is not easy way to set that pointer value. I have tried everything other than one of the core() functions to get the pointer value set easily (except as listed at the end of this message). Perhaps a special non-transportable function to set the value of the internal pointer (pcore()?).

So, for an arbitrary TYPE (ABCD):: QRST, loc(QRST) gives the address of the TYPE that can go into the %ud. In the receiving module, the syntax would be

  TYPE(ABCD),pointer::DEFG
  pcore(DEFG) = clearwin_info@('USER_DATA')

] so you can get the elements of DEFG using standard FORTRAN syntax and rules.

As an experiment, I did some code/edoc testing and that worked to get a value set for a pointer within a TYPE as I have described. It is a non-trivial method. That said, there is no 'standard' way that I can see to 'simulate' the equivalent of an ALLOCATE. But, maybe there is!

In a section of my own code, I use a COMMON declaration to do this. It works, but the disadvantage is that you can't just use an INCLUDE to get the declarations performed. So it has very limited use. Should anyone wish to see how it works, I can post a separate set of code segments. The basic technique is to declare an intrinsic data type in the 'driver' COMMON, and the 'receiver' defines this common as containing the pointer to the data type.

5 Mar 2019 12:01 #23316

In doing some research on POINTERs, I ran across an implementation that would work, but would be an additional language element that might be considered 'out of scope' for implementation. It is difficult to get the syntactical elements as they may be specific to one particular FORTRAN compiler, but here goes.

Using a syntax of:

INTEGER,POINTER:: POINTEE
POINTER (POINTED,POINTEE)

lets the variable POINTED to be treated as an integer, meaning you can do a statement such as:

POINTED = LOC(ABCD)

and reference the pointer as a destination:

POINTEE = 10

will set the integer variable ABCD to a value of 10.

POINTEE can be anything from an intrinsic type to a TYPE.

Just another thought.

I am preparing a document on a method by which the %ud can be used to reference an arbitrary data type by devolving into assembly language in lieu of a different solution.

7 Mar 2019 1:40 #23328

In the next release of ClearWin+ you will be able to use clearwin_info@('THIS') with %ls.

7 Mar 2019 2:29 #23329

A backhanded approach to using %ud with a user TYPE is illustrated below. An array of INTEGERs (say) would be simpler.

WINAPP
program main
integer iw,winio@
character*1024 buffer
integer,external::cb
type mytype
sequence
double precision x1
integer k1
end type mytype
type (mytype) zz
zz%k1 = 7
buffer = ' '
iw = winio@('%ca[User data]&')
iw = winio@('%30.10^re&',buffer,cb)
iw = winio@('%ud&', loc(zz))
iw = winio@('%ff%nl%cn&')
iw = winio@('%10rd',zz%k1)
end

integer function cb()
use clrwin
integer(7) addr
addr = clearwin_info@('USER_DATA')
call sub(core8(addr))
cb = 1
end function

subroutine sub(tt)
type mytype
sequence
double precision x1
integer k1
end type mytype
type (mytype)::tt
tt%k1 = tt%k1 + 1
end
7 Mar 2019 9:19 #23331

Paul, this is a very elegant way to achieve the results!

A warning may be generated when performing a compile.

An error is thrown when using /CHECKMATE.

The technique I will be using is shown in the code below. I used yours as a template. In this sample, no compile warnings, and no run-time error will be thrown with /CHECKMATE.

WINAPP 
program main 
integer iw,winio@ 
character*1024 buffer 
integer,external::cb 
type mytype 
sequence 
double precision x1 
integer k1 
end type mytype 
type (mytype) zz 
zz%k1 = 7 
buffer = ' ' 
iw = winio@('%ca[User data]&') 
iw = winio@('%30.10^re&',buffer,cb) 
iw = winio@('%ud&', loc(zz)) 
iw = winio@('%ff%nl%cn&') 
iw = winio@('%10rd',zz%k1) 
end 

integer function cb() 
use clrwin 
type mytype 
sequence 
double precision x1 
integer k1 
end type mytype 
type (mytype), pointer::tt ! requires that the TYPE be declared as a pointer
integer(7) addr 
addr = clearwin_info@('USER_DATA') 
code  ! DEVOLVE TO ASSEMBLY
mov eax%,addr
mov tt,eax%
edoc ! BACK TO FORTRAN
call sub(tt) ! this is the same (in concept) as using the core8() function but retains type checking at the subroutine
cb = 1 
end function 

subroutine sub(tt) 
type mytype 
sequence 
double precision x1 
integer k1 
end type mytype 
type (mytype)::tt 
tt%k1 = tt%k1 + 1 
end

There are disadvantages to either approach, I guess.

I have an example using %ud and my technique that someone might find useful in understanding how to do their own data passing.

https://drive.google.com/file/d/1IMSR_3dbf2teY9LWrTMMbowWjR7fyCQt/view?usp=sharing

Bill

8 Mar 2019 8:14 #23332

Bill

I will take a look to see if FTN95 can be fixed so that (/CHECK) argument type checking is avoided when COREx routines are used in this way.

I used CORE8 with /64 otherwise you would use CORE4.

8 Mar 2019 3:07 #23334

I think that would be a great idea!

Thanks!

9 Mar 2019 10:03 #23335

I have fixed FTN95 so that /CHECK will allow CORE8 etc. to be used in this way.

9 Mar 2019 3:58 #23336

Bill's post of March 4 reminds me of the 'Cray Pointers' feature, which is an extension provided by several vendors of Fortran 77. See, for example, http://www.icl.utk.edu/~mucci/MPPopt/additional/pointers.pdf .

Many current Fortran 95, 2003 and 2008 compilers support Cray pointers. However, since the feature is not much used in new code, code containing Cray pointers can be quite confusing to most users of modern Fortran.

9 Mar 2019 7:46 #23337

Awesome! Thanks, Paul!

mecej4, this is exactly what I saw that intrigued me. Something like this can make the use of pointers relatively easy, and still have good documentation as to the uses of it.

The idea of adding ',target' to all the data items that I might pass via pointer is daunting. But that does help in documenting the usage of variables. At least TARGET does say that this might be referenced as a pointer, and FTN95 is great at pointing out differences between the definition of the pointer and the definition of the target!

12 Mar 2019 12:27 #23351

A new FTN95 intrinsic function PCORE7 has been added for the next release. It works rather like the pointer assignment:

p ⇒ NULL()

and takes the form

p ⇒ PCORE7(addr)

where addr is the LOC of any object.

Here is some code that illustrates how it will work:

integer(7),target::addr
type mytype
 real x
 integer kk
end type mytype
type(mytype),target:: inst
type(mytype),pointer:: this

addr = loc(inst)
this => pcore7(addr)
this%kk = 42
print*, inst%kk

end
12 Mar 2019 9:12 #23353

This is awesome, Paul! Thanks a million!

Bill

13 Mar 2019 1:54 #23363

It turns out that there is an existing way to do this using the FTN95 keyword absolute_address in an ALLOCATE statement as follows...

integer(7),target::addr
type mytype
 real x
 integer kk
end type mytype
type(mytype),target:: inst
type(mytype),pointer:: this
addr = loc(inst)
allocate(this,absolute_address=addr)
this%kk = 42
print*, inst%kk
end
13 Mar 2019 4:37 #23365

Nice to know.

Since neither is 'portable' (correct?), I guess it doesn't really matter. That said, I like the syntactical completeness of this solution. It is clear what you are doing! The other methods, perhaps not so much.

That said, the pcore7() is still an awesome addition.

I can't get your example to run. It gives me an undefined variable at thge PRINT statement.

13 Mar 2019 6:32 #23368

Sorry for the incomplete information. It appears that this is currently for 64 bits only.

13 Mar 2019 7:13 #23369

Thanks for the update.

Bill

14 Mar 2019 10:42 #23371

The ALLOCATE keyword argument absolute_address has now been added to 32 bit FTN95 for the next release.

14 Mar 2019 2:11 #23372

Many thanks. I appreciate the work you all do on getting the compiler and support tools working and bug-free. It's not an easy task, and it is valued.

Bill

Please login to reply.