Silverfrost Forums

Welcome to our forums

Attributes of file

5 Jun 2015 9:53 #16427

Which program can look at changes in attributes of file you dropped (time stamp etc) ?

files@ seems does not work with files not in current dir (files having long path)

5 Jun 2015 10:07 #16428

Dan,

Could you explain a bit more ?

Assuming you are having problems with the array dimensions, I use files8@ and find it very effective as:

      call files8@ (local_dir,                   &  ! C320 directory to scan
!4k   call files@ (local_dir,                    &  ! C320 directory to scan
                   n,                            &  ! I2   number of entries found
                   nmax,                         &  ! I2   capacity of buffers
                   file_name(next),              &  ! C320 tree name of files found
                   attr(next),                   &  ! I2   DOS attributes
                   date(next),                   &  ! I2   DOS date format
                   time(next),                   &  ! I2   DOS time format
                   file_size(next) )                ! R8   File size in bytes

For my use, the tree name array is basically : character file_name(32000)*320

As the number of entries (nmax) is I*2, there is a limit of 32,000 files to recover from a directory. The tree name length of 320 is what has suited my disk use. This is 10mb, so character file_name(32000)*1024 should work. If you are using this in a utility routine, you could make it allocatable, then deallocate when no longer needed.

I have a disk scanning program that I apply date filters and sometimes file extension filters to list all files in a tree or on the disk. The only problem I have is when I don't have read access to some directories, typically network directories. It has been a very useful utility, especially for finding hidden files, especially in hidden directories.

John

5 Jun 2015 8:51 #16430

Thanks John. Fun is that I use files@ for two decades and it is OK in a dozen of different places in many different variants. They all had problem when debugged mostly because i was missing those absurd integer*2 definitions but they all work now.

I do not know where the hell the error is here. The compiler crashes 100 times per day with other large programs though that's kind of normal since i'm permanently hitting 3-4 GB limit and stupid stack size (which moron invented it?). But the fact i can not debug 10 lines program after losing a half a day is mind torturing. I do not see some simple stupid error - this is also normal, but look what the compiler is doing! I made a demo code, may be you (others are welcome too) will tell me why the heck

  1. with 'ftn95 aaa.f95 /link /debug' compilation i get 'Bad request for stack memory' (!!!) 2)with 'ftn95 aaa.f95 /link /debug /undef' debugger does not find undefined variable even if uncommenting the line !> goto 10000 saying that the error is in line 7 (!!!). Line 7 is 'end program' statement

  2. the files8@ does not find (shows zero) the same file which was just dropped (!!!). For that uncomment 'goto 10000'

    winapp integer, external :: cbdropped

    i=winio@('%ww%es%si! Drop file here %ff&') i=winio@('%dr&', cbdropped) i=winio@('%pv%50.20cw[hscroll,vscroll]%ff&', 0) i=winio@('%cn%bt[OK]') End program

    integer function cbdropped () use clrwin integer, parameter :: MaxLengFileNames=128 ! 320

    character*(MaxLengOfFileNames) textsample, FileNameOfDroppedDataFor3D_GL02 integer2 maxNumbOfFilesInDir, NumbOfFilesInDir parameter (maxNumbOfFilesInDir = 100) character(MaxLengOfFileNames) FILES_InDir(maxNumbOfFilesInDir) integer2 ATTR_files(maxNumbOfFilesInDir),date_files(maxNumbOfFilesInDir), time_files(maxNumbOfFilesInDir) real8 file_size(maxNumbOfFilesInDir)

    !> goto 10000 FileNameOfDroppedDataFor3D_GL02 = clearwin_string@('DROPPED_FILE')

     write(*,*) 'FileNameOfDroppedDataFor3D_GL02=', FileNameOfDroppedDataFor3D_GL02
    
     textsample = FileNameOfDroppedDataFor3D_GL02
     call files8@ (textsample, NumbOfFilesInDir, maxNumbOfFilesInDir, FILES_InDir, ATTR_files, date_files, time_files, file_size)
     print*, 'NumbOfFilesInDir=', NumbOfFilesInDir ! , 'textsample, NumbFiles_InDir ', textsample, NumbFiles_InDir 
    

    10000 cbdropped = 2 end function

5 Jun 2015 10:23 #16431

Adding IMPLICIT NONE to your subroutine is probably more effective in finding the bug in your program than IMPRECATE ALL.

Adding IMPLICIT NONE and compiling would tell you that MaxLengFileNames has a value, whereas MaxLengOfFileNames does not; one of these is probably a mistyped name.

5 Jun 2015 11:35 #16432

Thanks mecej4. This solved the problem. But the debugger with /undef should find this error and it did not ! Never or rarely happens. Is this only my debugger, by the way? Please confirm.

Both methods probably have to be used, but the /undef is way more effective in finding logical swists of the large codes then implicit none and is more and more used in other compilers. That was discussed couple decades ago with good examples.

6 Jun 2015 1:06 (Edited: 6 Jun 2015 12:22) #16433

The ways in which /undef and /debug work are quite different. You should perhaps regard them as complementary rather than alternative ways of finding bugs. Nor do /debug and /undef work as any kind of team.

The /undef option (and similar options such as /check) plants extra code into the EXE to perform checks in addition to doing the calculations required by the Fortran source. These checks happen on every line of code that is visited, without needing any interaction from you. Often, these checks slow down the execution considerably.

The /debug option, on the other hand, places the responsibility on you to watch for and catch errors, but does facilitate your detective work by translating code addresses to line numbers and highlighting the corresponding source line in the source window of the debugger, and by translating data addresses to active variable names and showing the values of those variables in human-readable decimal form. In some ways, the name 'debugger' is a misnomer. If you do not have a suspicion as to where the bug is located, or if you have no idea of which values of variables are reasonable, watching the program run inside the debugger is not necessarily going to help you find any bugs, let alone de-bug the program.

The problem with both /debug and /undef is that they are of little help unless all routines contributing to the entire program, including library routines and the Fortran runtime, were also compiled with the same options.

Let me illustrate these points. Consider this program, in which a variable is used without being defined.

program tst
integer a
call sub(a)
print *,a
end program

subroutine sub(i)
integer i
i=2*i+5
return
end

The variable 'a' should have been defined before line-3. Indeed, a compiler that performs a thorough static analysis of the code can tell you so. If you compile with /undef, the error is detected not on line-3, but on line-9, where the undefined variable is used. Now suppose that the subroutine is in a library, which was compiled without /undef. To simulate this, break out the main and the subroutine into separate files. Compile the main program with /undef and compile the subroutine without /undef. If you now link and run, you will not see the program abort, but you get a garbage result printed out.

Something similar happened in your code, when you had two variables with slightly different names, assigned a value to one and used the other as an argument to a subroutine.

I think that FTN95 falls a bit short when it only says

0014)   character*(MaxLengOfFileNames) textsample, FileNameOfDroppedDataFor3D_GL02
WARNING - Variable MAXLENGOFFILENAMES has been used without being given an initial value

whereas it should have rejected the declaration CHARACTER*(<an undeclared integer variable name>) because that integer character length parameter should have been a constant or a subroutine dummy argument. In contrast, another Fortran compiler says this about the same code:

Warning: cbd1.f90, line 3: Unused PARAMETER MAXLENGFILENAMES
Error: cbd1.f90, line 5: MAXLENGOFFILENAMES is not permitted in a specification expression
6 Jun 2015 3:52 #16434

I agree that /debug is mis-named, but I find it a very useful option. It probably should be called /trace_back.

I always use /ERROR_NUMBERS and /IMPLICIT_NONE as it at least forces me to recognise what local variables I am using and when combined with the unused variable warning, picks up my many typing errors. Dan, you should try to introduce /implicit_none in your testing and then the compiler might crashe only 10 times per day. With FTN95, errors where the memory is running out are poorly reported. More use of ALLOCATE for temporary arrays, and releasing them when not needed can help memory availability a lot, although there is more planning required. We need an option to put the stack and heap at address 3.8gb! (definitely a smarter SLINK)

The difference between /undef and /check often needs to be better understood, as they pick up different errors. It can be surprising how array subscripts that =0 can remain as bugs in code for years, especially where the logic may later exclude these cases.

John

6 Jun 2015 8:03 #16435

Well, despite this damn bug ... I will probably never start using 'implicit none' 😃. That is making long code even longer. That is like adding telephone book of names and addresses in front of programs and subprograms. The way to go is i think to make compiler/debugger better and better.

The error like this should be reported by the compiler. Plus the debugger must report parameters in all debugger's windows (noticed it does not? WHY?) and also check them with /undef (why it did not???)

After fixing this compiler or debugger bug or 'feature' the only useful things about 'implicit none' is that if you hit 72/132 limit it will report an error. But that is no longer advantage after Paul implemented an option /no_truncate we were advocating here. The /undef will also tell you about truncation with large probability

So, in short, I am too lazy (or almost incapable spending more and more time, now 14-16 hours/day, in front of monitors) to declare variables in front of the code and permanently go far up and deep down (programs are long and consist of many files) to find what the variable it is and how it is declared. Besides I like i-to-n as integer by default because that is also telling me what the variable is for. The code has to be verbose and self-explaining where it is written not somewhere in different file many miles away

Yes, this compiler crashes a lot i suspect due to very strict checking policy on underflow and not great stability of Clearwin Windows-related code. The latter one is not completely this compiler's fault i suspect. Bad genetics of unfamous FTN90 is also probably not completely pesticided. If Salford C was used then this also is not a plus. But I think compiler developers have to make no slightest checking of underflow as a default. And make sure underflow does not slow down the code too. As to stack related crashes, hopefully 64bit compiler will make stack obsolete.

Debugger still scares people with its primitive look and feel and even more when it falls into assembler. If you experienced enough you do not care and keep using debugger as if nothing happened but I am sure novices are scared to death and turn away from this compiler since only 1/1000 probably will ever use the assembler. Debugger should never show the assembler windows without millions of excuses to the programmer.

6 Jun 2015 12:55 (Edited: 6 Jun 2015 4:23) #16436

Quoted from DanRRight Debugger should never show the assembler windows without millions of excuses to the programmer. On the other hand, there are cases where errors in the compiled code can be next to impossible to detect without being able to look at the compiled code in a disassembly window. In these cases, we want to give the programmer a way to request and see the disassembly -- F11 does that. If you take that tool away, you prevent others from doing what they may want to do. For example, I might not have found the bug reported in https://forums.silverfrost.com/Forum/Topic/2723 if I could not see the disassembly while stepping through the code.

The only situation when SDBG shows assembly without being asked to do so is when a breakpoint occurs inside code that was compiled without /DEBUG. Silverfrost could provide a configurable flag in SDB that lets the user specify 'do not show disassembly unless asked for'.

There is yet one more technique for finding bugs caused by misspelled variable names -- generate and examine the old-fashioned cross-reference list. If, with the source file named cbd.f90, you do

ftn95 cbd.f90 /XREF
findstr /B '[A-Z]' cbd.XRF

you see, among other lines, the following:

INTEGER, PARAMETER :: MAXLENGFILENAMES
INTEGER :: MAXLENGOFFILENAMES
6 Jun 2015 1:42 #16437

Dan,

If you have a ' telephone book of names ' then you are doing well to find any bugs. I find by grouping variables by modules or included common blocks, the variable management is easier to control. Then you only need to consider the local variables in a routine, and if this is still at telephone book size, then your routine must be too complex.

I hope my example of using files@ might have helped.

John

6 Jun 2015 2:25 #16438

Like Dan I am not a fan of IMPLICIT NONE, as I find it more valuable to know at a glance the type of a variable than to use the facility to detect misspelled names – perhaps because I am of the generation that learned to spell partly with the aid of corporal punishment, and I can read these errors (caused, I might add, usually by autocorrect, or the deletion of a highlighted letter when you type something else). Indeed, I only ever used two names that wilfully denied the implicit typing convention. One of them, LAMDA, should have been real, but I defied the Backus convention as the compiler used a maximum length of 5 letters for names, and it fitted oh so nicely. That blasted thing caused me grief for decades.

Indeed, it seems to me a little perverse that a facility for forcing the programmer to declare the type of a variable explicitly should have the dual use of indicating whether it is used uninitialized. That seems to me to be the role of something else – XREF for instance. The dual use business bothers me a lot: MODULEs for instance, as a replacement for INCLUDE as well as grouping routines and altering the very simple scoping rules of traditional FORTRAN.

I have very guilty pleasure, and that is every time an error in the compiler is found for some obscure feature of Fortran 90/95/etc, I have a warm glow inside. My programming style was locked in so very long ago that these matters rarely bother me.

Lots of naming, scoping and suchlike errors can be kept to a minimum by keeping routines simple, using as few variables as necessary, and if Dan must use NumberOfSomethingOrOther type names, then using underscores does make them easier to see errors in, as in Number_of_Something_or_Other. Lengthy meaningful names are all very well and good, but one is more likely to see if 'Cardiff' is spelt correctly than 'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'.

6 Jun 2015 10:08 #16439

There is no compulsion to use IMPLICIT NONE. Given Dan's aversion to declaring variables explicitly, and assuming that he is unwilling to enroll in a school that still uses corporal punishment in its curriculum, such as that which Eddie fondly remembers, I'd suggest using the FTN95 option /IM on Dan's unmodified sources.

Just as with the /XREF option, the output with /IM will be verbose and mostly uninteresting, which is why this output should be passed through a filter such as FINDSTR or GREP, and possibly SORT. Of course, if the search criteria are too tight, the bug (misspelled variable names) will slip through unnoticed, so different search patterns will have to be tried.

I do think that Dan is a bit unreasonable in his insistence that the compiler should have found the error. With implicit typing, the program contains valid Fortran, and most of us would want the compiler to process whatever code is given to it. The code may not do what the author intended, perhaps, but we do not expect clairvoyance from a mere compiler.

In a way, the situation is one of 'pay now (by writing explicit declarations and correcting mistyped variable names) or pay later (as a result of incorrect program output)'.

7 Jun 2015 8:30 (Edited: 7 Jun 2015 6:24) #16440

let's conclude that here definitely was a compiler/debugger bug, and i hope Paul logged it for fixing.

Thanks all for help, suggestions and ideas. I learned about new function files8@. After running this code

https://forums.silverfrost.com/Forum/Topic/2196&start=15

with the search word 'files@' and then 'files8@' i found 30 times use of files@ and zero files8@, so indeed i did not forget -i did not know about it. Brief look showed that files8@ is missing in Help file.

Interesting was idea of using /XREF, which i may use for something in the future. For my bug searches it is unfortunately useless since it generated me 49 MB (!) of crossreferences.

And yes, after trying many ways of making text more readable I use underscores for clarity more often. Recommend it too. As well as long names for text self-explanation.

Discussion convinced me even more that declarations of everything due to using 'implicit none' will be obsolete in the future, the compiler will do the work perfectly without that hemorrhaging annoyance.

How this bug could be hidden for 25 years is beyond imaginable. I think developers must issue the following warning 'The condition of using this compiler free of charge for personal use is that you will get back to us with at last few reports for bug fixes and suggestions for improvement' after fixing my 'french' of course. Or advertize it 10 times on the internet, more users - less bugs. Users have to be way more active reporting anything which might improve this great compiler.

7 Jun 2015 11:09 #16441

For me, /UNDEF would be better than /IM

7 Jun 2015 12:34 #16442

Quoted from DanRRight Brief look showed that files8@ is missing in Help file.

See the last line under 'Description' at http://www.silverfrost.com/ftn95-help/file_man/h_filesa.aspx . You will find the same information by searching for 'files8@' in the FTN95 help file.

8 Jun 2015 1:10 #16451

Eddie & Dan,

/implicit_none is not some way of making you change the way you start integers with I:N, but a way of setting up a table of valid variable names.

I use it all the time, as when writing new code, I look through all the undeclared variable names, placing them in INTEGER4 or REAL8 declaration lists, ensuring that each name is a variable I want to use. ( I have always been frugal with variable names!) All Modules have variables declared and for common, I prefer to use them as include 'name.ins' ; with all variables declared. For me, too many local variables means the routine is too complex and should be split into simpler tasks. While not always possible, it can help in confirming smaller routines do not affect other tasks when not intended.

I also check the use of common and modules in each routine, by commenting out the INCLUDE or USE line and noting the variables that are identified as undeclared, which identifies the list of variables being used in this routine from that common or module. It provides me with a useful coding error filter, which says only variables from this defined name table can be used. Changes to code also benefit from this name filter. Every time I get an error report from mis-typing a name, it reinforces my view of the usefulness of this approach.

I would certainly recommend you give it a try. You may be surprised by the number of incorrect variable names still in your code, waiting to produce a new unexpected program malfunction.

Back to the origins of this thread, FILES8@ was introduced to give the size of files larger than 2gb, so REAL8 was provided. ( I would have preferred INTEGER8 (and KIND=8!) although there has been a reluctance to use integer8 in FTN95, as it's more general use has been gradually supported. It might be due to software support? Are there I8 instruction support for x32 ? It is an essential kind for x64)

John

9 Jun 2015 1:42 (Edited: 12 Jun 2015 10:05) #16453

Thanks mecej4 and John for the info.

John, i ran the same program as above (i call Searcher and include in my Tools after adding nice GUI to it) and found 110 times i used 'implicit none' in my programs. This surprised even myself, i have to check this tool. The result you know: after years i conclude - I do not like it and stopped its use. The only bug this caused was this one above because people hesitate or are lazy to report the bugs and improvement suggestions. Those who use PE version must report 10 bugs/suggestions as 'payment' for privilege of using this unique compiler which like all software has bugs.

My subprograms are not large, one code for example has 805 subroutines in 260K lines. I'd beat that i do not have many such bugs you claim because all of them including ones in PARAMETERS (which is the compiler bug) are revealed by /UNDEF. I'd beat 20 bucks for that 😃 but adding telephone book of names on top of programs (49 MB of crossreferences!!!) is a lot of work with no benefits specifically when this bug will be fixed and /NO_TRUNCATE will be commonly used. Even if /XREF will help to automate this work it's pure waste of time for potentially obsolete feature. Talking about change in implicit integers and reals, implicit none may actually make more hidden errors then it cures when you will think the variable is real but it is actually integer 😃 and will never find that. That bug i found just by chance was the last straw recently when i said NO to IMPLICIT NONE. But may be you see some other benefits i do not see. And did i forget to say that debugging will be longer? And how about exponential decrease of prorammer's productivity (measure in new lines of code per unit time) with program size?

My general point is that it's compiler which has to find all syntax bugs, not people. It has to work like a blind immune system. Humans must fix more complex problems

But your exclusion of USE is good idea. Will try it.

10 Jun 2015 12:21 #16455

Hi John,

/implicit_none is not some way of making you change the way you start integers with I:N

Well I agree that it doesn't have to be, but it also creates verbosity that I don't like. I'm happy to believe that it could help, and that lots of people might love it, but it doesn't work for me, and worse (with my ingrained habits) I find it irritating.

I've only ever used an INCLUDE in one program, other than WINDOWS.INS, and in the end I removed it. It was a way of getting variable size array limits. But I'm content to use fixed size arrays. For example, I wrote a program for computing out and plotting student surveys on a field course. If every student recorded ten times the number of sights by working harder than they do, for ten times as many days as the spend in the field, with ten times the number of students we ever had - it still fits in a gigabyte. Not only that, but they also work in groups, so they don't all get a unique set of results every day. So there's a huge safety factor on the array sizes that we never had when we worked even in DOS.

Plus, if any variable name was mistyped, the survey plot would be wrong, and the proof of the pudding is in the eating.

I'm a great realist about these things, and don't advocate that anyone else does as I do, I just note that one can operate perfectly satisfactorily without following every fad and fashion in computer science theory, and I have the prejudiced view that many things introduced since Fortran 77 are alternative ways of doing something already doable, and are no advance in reality.

Eddie

10 Jun 2015 2:09 #16456

Dan,

Here is an example that I constructed in order to shake up your weltanschauung. I have made it easy to find the error by careful visual inspection, by aligning a couple of the lines. Using only the methods and techniques that you have declared in this thread to be acceptable to you, find the error in the program.

program buggy
integer :: Lwllllantysiliogogogoch = 13
!
! Imagine large block of code here that does some complicated
! calculations that depend on the above variable
!
if(Lwllllantysiliogogogoch > 10) &
   Lwllllantwsiliogogogoch = 10
print *, 'Factorial (',Lwllllantwsiliogogogoch, &
   ') = ',ifact(Lwllllantysiliogogogoch)

contains
   integer function ifact(n)
   integer n
      ifact = n
      do while(n > 1)
         n = n-1
         ifact=ifact*n
      end do
   return
   end function
   
end program

Remember, careful visual inspection is not one of the allowable techniques, since there could be a huge block of code placed after the declarations in the main program, which we shall assume to be too time-consuming to inspect.

[Apology to Eddie: I actually used 'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch' as the variable name in the example code, and the preview of the post came out fine. However, when I pressed the 'Submit' button the forum software gave SQL errors, so I reluctantly truncated the name, and abandoned my plan to try 'Taumatawhakatangihangakoauauotamateapokaiwhenuakitanatahu'.]

10 Jun 2015 3:04 #16457

To which I simply reply: Supercalifragilisticexpialidocious!

Eddie

PS. I'm sure that your post is akin to antidisestablishmentarianism, or perhaps it is floccipaucinihilification ...

Please login to reply.