![]() | |
![]() |
| | Thread Tools | Display Modes |
#11
| |||
| |||
|
|
michael (AT) preece (DOT) net wrote: For D3 you could google cdp for WhatHaveIGot Hmmm, if you don't have a file variable and you use it as part of a Read, you get a run-time abort. The code to which you refer has an "else debug" clause for that. Neither result is desirable in production code. Up until that point the code is ok, but that's exactly the part that Neil needs. I'm not aware of any complete solutions to this problem as-yet. T |
#12
| |||
| |||
|
|
Tony Gravagno wrote: michael (AT) preece (DOT) net wrote: For D3 you could google cdp for WhatHaveIGot Hmmm, if you don't have a file variable and you use it as part of a Read, you get a run-time abort. The code to which you refer has an "else debug" clause for that. Neither result is desirable in production code. Up until that point the code is ok, but that's exactly the part that Neil needs. I'm not aware of any complete solutions to this problem as-yet. T Hi Tony I don't have access to a D3 box at present but I thought that when I wrote and tested this that if I passed it a non-file variable it would be trapped by the "if CheckIds<2>=''". Not so? Mike. PS. Code for WhatHaveIGot pasted below: Subroutine WhatHaveIGot(FileVariable,WhatIsIt) WhatIsIt='' if not(assigned(FileVariable)) then WhatIsIt = 'Unassigned' return end clearselect CheckIds select FileVariable to CheckIds if CheckIds<2>='' then ;* This seems to be the key that unlocks it all WhatIsIt = 'A variable' return end readnext id from CheckIds else WhatIsIt = 'An empty file' return end read dummy from FileVariable,id else debug clearselect CheckIds fofid=oconv('','u90') open 'fof' to foffv else debug read fofitem from foffv,fofid else debug WhatIsIt = fofitem<1>:',':fofitem<2>:',':fofitem<3 return |
#13
| |||
| |||
|
|
This can only work if you know the offset in the descriptor table for any particular variable. They are inserted in the order they are found, but in some programs, that's a nightmare. You would never be able to say is.file(var) because the PUSH process will choke trying to push the variable onto the stack. Another poster in this thread mentioned that. Hmm, unless is.file looked like a subroutine, I just don't know. I do know only difference between a file variable and a long string variable is that first byte, so just looking at the data isn't always a good check unless you have some static data that you can key on. Mark "Tony Gravagno" <g6q3x9lu53001 (AT) sneakemail (DOT) com.invalid> wrote in message news:42psn1hek8dkou8picicft3b14e3l0hfk4 (AT) 4ax (DOT) com... Hmm, Mark, you just gave me an idea. If we %malloc space and copy a file descriptor to that space, then we should see binary data, maybe leading with x01, whereas a normal var would have its value inserted into the memory space. This is assuming that the %functions won't choke on use of a file descriptor being used, like the BASIC runtime chokes on other instructions - but %functions aren't processed by the BASIC runtime. Do you think this is worth a try? This could all be resolved down to a small subroutine which returned IS.FILE=0 or 1, and might be extended to return other info like Mike P's proggie. |
#14
| |||
| |||
|
|
I was thinking of something like this: call is.it.a.file(var,is.file) print is.file stop sub is.it.a.file(var1,is.file) precision 0 ; * required char var2[4] ; * required for buffer, can't just use var2="" dummy = %memxcpy( var2, (char*)var1, 2) ; * (char*) not required var3 = trim(var2) ; * eliminates extra buffer spaces if var3 = '01' then is.file = 1 else is.file = 0 return For the wiseguys in the group, yes, this is the equivalent of this: is.file = ( seq(var[1,1]) = '01' ) But as we've seen, if var is a file descriptor then we get a runtime abort: "File variable used where string expression expected." However, the %memxcpy function accepts a pointer to a string or a D3 string variable. I was hoping that it would see a file descriptor like a memory pointer. Well, a memory pointer is just a number stored in a regular variable, so when it sees a file var we still get a runtime abort with "Bad stack descriptor". So much for that approach. For a Unix environment, you can peek your PCB for the pointer to your BASIC stack (no idea what the Register or offsets are for anything anymore), and using frame references you can drill down to see the value of a particular variable. For Windows, frames are "virtual", and change from second to second (Mark understands this, I don't). Bottom line is that this would not be a cross-platform solution so it's useless to Neil. This is a fun one, I'll post if I get any more ideas. T "Mark Brown" <mbrown (AT) drexelmgt (DOT) com> wrote: This can only work if you know the offset in the descriptor table for any particular variable. They are inserted in the order they are found, but in some programs, that's a nightmare. You would never be able to say is.file(var) because the PUSH process will choke trying to push the variable onto the stack. Another poster in this thread mentioned that. Hmm, unless is.file looked like a subroutine, I just don't know. I do know only difference between a file variable and a long string variable is that first byte, so just looking at the data isn't always a good check unless you have some static data that you can key on. Mark "Tony Gravagno" <g6q3x9lu53001 (AT) sneakemail (DOT) com.invalid> wrote in message news:42psn1hek8dkou8picicft3b14e3l0hfk4 (AT) 4ax (DOT) com... Hmm, Mark, you just gave me an idea. If we %malloc space and copy a file descriptor to that space, then we should see binary data, maybe leading with x01, whereas a normal var would have its value inserted into the memory space. This is assuming that the %functions won't choke on use of a file descriptor being used, like the BASIC runtime chokes on other instructions - but %functions aren't processed by the BASIC runtime. Do you think this is worth a try? This could all be resolved down to a small subroutine which returned IS.FILE=0 or 1, and might be extended to return other info like Mike P's proggie. |
#15
| |||
| |||
|
|
Subroutine WhatHaveIGot(FileVariable,WhatIsIt) WhatIsIt='' if not(assigned(FileVariable)) then WhatIsIt = 'Unassigned' return end clearselect CheckIds select FileVariable to CheckIds if CheckIds<2>='' then ;* This seems to be the key that unlocks it all WhatIsIt = 'A variable' return end readnext id from CheckIds else WhatIsIt = 'An empty file' return end read dummy from FileVariable,id else debug clearselect CheckIds fofid=oconv('','u90') open 'fof' to foffv else debug read fofitem from foffv,fofid else debug WhatIsIt = fofitem<1>:',':fofitem<2>:',':fofitem<3 return |
#16
| |||
| |||
|
|
The original post/example of WhatHaveIGot seems to work except that because my FOF does not contain the files I am looking at it goes to debug. BTW, I have tried on numerous occasions to create the FOF for the whole system but no matter what I try the file numbers for all NEW files that were not in the original downloaded D3 system (i.e. DM, SQLDEMO etc.) show with a minus sign "next" to them and they do not appear in the FOF. I have tried FILE-SAVE, SAVE (s,f,d,g and SAVE (s,f,d,g,t. Can anyone suggest what I am doing wrong or why this would happen, because without the FOF the WhatHaveIGot works but does not return the file name? The system I am working with is D3 7.4.5 on Win2K3 Server and all of the accounts in question are FSI's. That last line says it all. |
#17
| |||
| |||
|
|
michael (AT) preece (DOT) net> wrote Subroutine WhatHaveIGot(FileVariable,WhatIsIt) WhatIsIt='' if not(assigned(FileVariable)) then WhatIsIt = 'Unassigned' return end clearselect CheckIds select FileVariable to CheckIds if CheckIds<2>='' then ;* This seems to be the key that unlocks it all WhatIsIt = 'A variable' return end readnext id from CheckIds else WhatIsIt = 'An empty file' return end read dummy from FileVariable,id else debug clearselect CheckIds fofid=oconv('','u90') open 'fof' to foffv else debug read fofitem from foffv,fofid else debug WhatIsIt = fofitem<1>:',':fofitem<2>:',':fofitem<3 return Thanks for posting that! It works great on d3/linux {haven't tested on d3/nt yet -- note fof numbers are negative for files in the fsi on that platform} I've been using d3 & its ancestors for over ten years and _never_ thought I'd see this trick accomplished! I'm going to rush right out and add it to my little fwinans,bp, 'fragments' cheat-sheet item on all the servers we install/maintain! Or add a custom item in the D3REF.DOC HELP database file... Maybe I'm google-illiterate, but it seems to want to make me paw through 23000 topics to get to the august 2000 posting of WHATISIT() subr... |
#18
| |||
| |||
|
|
michael (AT) preece (DOT) net> wrote Subroutine WhatHaveIGot(FileVariable,WhatIsIt) WhatIsIt='' if not(assigned(FileVariable)) then WhatIsIt = 'Unassigned' return end clearselect CheckIds select FileVariable to CheckIds if CheckIds<2>='' then ;* This seems to be the key that unlocks it all WhatIsIt = 'A variable' return end readnext id from CheckIds else WhatIsIt = 'An empty file' return end read dummy from FileVariable,id else debug clearselect CheckIds fofid=oconv('','u90') open 'fof' to foffv else debug read fofitem from foffv,fofid else debug WhatIsIt = fofitem<1>:',':fofitem<2>:',':fofitem<3 return Thanks for posting that! It works great on d3/linux {haven't tested on d3/nt yet -- note fof numbers are negative for files in the fsi on that platform} I've been using d3 & its ancestors for over ten years and _never_ thought I'd see this trick accomplished! I'm going to rush right out and add it to my little fwinans,bp, 'fragments' cheat-sheet item on all the servers we install/maintain! Or add a custom item in the D3REF.DOC HELP database file... Maybe I'm google-illiterate, but it seems to want to make me paw through 23000 topics to get to the august 2000 posting of WHATISIT() subr... |
#19
| |||
| |||
|
|
"Mark Brown" <mbrown (AT) drexelmgt (DOT) com> wrote in message news:Vvrff.6205$Hs.5834 (AT) tornado (DOT) socal.rr.com... A stack error isn't a compiler error, it's a run time error. The compiler could care less what the various variables will hold even if it could know. Run time sets a flag on every entry of the descriptor table telling what that variable is, the closest thing traditional Pick has to data typing. Most of the time id doesn't care so you can play with list variables to some extent, but with file variables, it's different. They're binary, so you can't treat them like strings; there's nothing at the adress they point at that would be interesting, and realistically, what would you ever want to do You may want to do what the OP asked for. And, ultimately, someone somewhere made a decision at some point that there was nothing you would ever WANT to do to a file variable, therefore you CAN'T do anything with it. Yeah, the decision was made by default, so to speak, ie, it fell out of the loop of legal pushable variables, except when needed as in READ. But as it's still this way, it's is an example of why systems programmers should be forced to write an application every now and then (say, maybe we need to have a license to write systems and this could be a requirement). After all, in mvE, R91 and Ultimate etc fv's are treated as something manageble. It would be a trivial runtime change. Chandru Murthi Mark Brown "Frank Winans" <fwinans (AT) sbcglobal (DOT) net> wrote in message news:Vspff.498$rq3.457 (AT) newssvr19 (DOT) news.prodigy.com... Our D3 gave a stack error when I tried copying a file handle to another variable then doing an IF (a = myfile) THEN crt 'same' -- a fine example of a compiler bug too trivial to fix. |
#20
| |||
| |||
|
|
Google CDP for "Data Abstraction Layer" for more details. |
![]() |
| Thread Tools | |
| Display Modes | |
| |