home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / developmen / oplexamp / UNDEL.OPL < prev   
Text File  |  1994-06-13  |  13KB  |  515 lines

  1. PROC Start:
  2. REM  =====
  3. REM THIS PROGRAM UNDELETES DELETED DATABASE RECORDS AND WRITES
  4. REM THEM INTO A NEW DATABASE. JUNK RECORDS SHOULD THEN BE
  5. REM DELETED FROM THIS NEW DATABASE, BEFORE LINK-PASTEING OR
  6. REM MERGING SOME OF ITS CONTENTS BACK INTO (SAY) THE ORIGINAL
  7. REM DATABASE. THE DUFF RETRIEVED RECORDS ARE STYLE RECORDS
  8. REM WHOSE STRUCTURE FOLLOWS THE VALID MAIN RECORD STRUCTURE.
  9. REM RETRIEVAL OF A FEW OF THESE IS UNAVOIDABLE SINCE, ONCE A
  10. REM RECORD HAS BEEN DELETED IT IS IMPOSSIBLE TO TELL ITS
  11. REM ORIGINAL TYPE. ALL THAT CAN BE DONE IS A VERIFCATION THAT ITS
  12. REM STRUCTURE IS CORRECT FOR MAIN RECORDS (TYPE 1).
  13. REM THE PROGRAM ONLY WORKS WITH FILES THAT THE PERSONAL DATABASE
  14. REM WILL ACCEPT.
  15. REM DATE: 7/2/91   AUTHOR:NJB
  16. REM
  17. REM execution starts here, and finishes at the end of this proc
  18.     GLOBAL Outch%,Inpch%   :REM output and input files
  19.     GLOBAL Wrkbuf$(255)    :REM used generally for file reads
  20.     GLOBAL Infname$(255)   :REM input file name
  21.     GLOBAL Ofname$(255)    :REM where undeleted 'deleted' records go
  22.     GLOBAL Undels%         :REM undeletions made
  23.     GLOBAL Unrecog%        :REM num of deleted recs definitely 
  24. REM                                                      not of type 1
  25.     LOCAL ret%
  26.     LOCAL tret%
  27.  
  28.  
  29.     SCREEN 50,15
  30.     
  31.     ONERR inerrs::
  32.     Undels%=0   :REM initialise globals 
  33.     Unrecog%=0
  34.     Outch%=0
  35.     Inpch%=0
  36.     tret%=0
  37.     
  38.     REM Open files as binary files since normal OPL database
  39.     REM handling can only see 32 fields, a database can have more
  40.     REM Temporary usage of the database open calls is used to create
  41.     REM the heade of the new file, sadly it cannot be used on
  42.     REM the input file to check validity, because CLOSE removes
  43.     REM deleted records.
  44.     
  45.     ret%=OpenChs:  
  46.     IF ret%<>0
  47.         RAISE ret%
  48.     ENDIF
  49.     CLS
  50.     PRINT "UNDELETING..."
  51.     PRINT "INPUT FILE: ";Infname$
  52.     PRINT "OUTPUT FILE: ";Ofname$
  53.     
  54.     ONERR stderrs::
  55.  
  56.  
  57.     REM Check FIR directly using I/O file handling
  58.     REM also check file signature and version nos
  59.     ret%=CheckVal:
  60.     IF ret%<>0
  61.         RAISE ret%
  62.     ENDIF
  63.     REM come out of this positioned at start of first main record
  64.     
  65.     REM parse for deleted records and write them into new file
  66.     ret%=Retr:
  67.     IF ret%<>0
  68.         RAISE ret%
  69.     ENDIF
  70.     
  71.     stderrs::
  72.     tret%=CloseChs:   :REM can't raise an error
  73.  
  74.     inerrs::
  75.     REM report completion status
  76.     
  77.     ONERR OFF
  78.     CLS
  79.     PRINT "COMPLETION REPORT"
  80.     PRINT "-----------------"
  81.     PRINT
  82.     PRINT "INPUT FILE: ";Infname$
  83.     PRINT "OUTPUT FILE: ";Ofname$
  84.   IF tret%<0
  85.       PRINT "COULD NOT CLOSE NEW FILE"
  86.   ELSEIF ERR=0
  87.         PRINT "COMPLETED SUCCESSFULLY"
  88.     ENDIF
  89.   IF ERR<0
  90.         PRINT "ERROR:",ERR$(ERR)
  91.     ELSEIF ERR>0
  92.         REM special errors
  93.         PRINT "ERROR:",ErrStr:(ERR)   :REM error string in Wrkbuf
  94.         PRINT Wrkbuf$
  95.     ENDIF
  96.     PRINT "UNDELETED",Undels%,"RECORDS"
  97.     IF Unrecog%>0
  98.         PRINT  Unrecog%,"DELETED RECORDS COULD NOT BE OF TYPE 1"
  99.     ENDIF
  100.     PRINT
  101.     PRINT "PRESS <ENTER> TO EXIT"
  102.     INPUT Wrkbuf$
  103.     
  104. ENDP 
  105. REM end of Start
  106.  
  107. REM ======= PROCEDURES CALLED BY MAIN PROCEDURE ========
  108.  
  109. PROC OpenChs:
  110. REM  =======
  111. REM opens the file to read from, and creates file to write to
  112. REM Uses global buffer Wrkbuf$
  113. REM > Returns 0 if all OK, else error number
  114.     LOCAL opfail%
  115.     LOCAL ret%
  116.     
  117.     ONERR operrs::
  118.     opfail%=0
  119.     
  120.     REM     open the input file
  121.     PRINT "NAME INPUT FILE>"
  122.     INPUT Infname$
  123.     REM        open with read and seek access, as an existing binary file
  124.     ret%=IOOPEN(Inpch%,Infname$,$0200)
  125.     IF ret%<0
  126.         RAISE ret%
  127.     ENDIF
  128.         
  129.     REM open output file, creating header using OPL CREATE call
  130.     PRINT "NAME OUTPUT FILE>"
  131.     INPUT Ofname$
  132.     IF EXIST(Ofname$)
  133.         DELETE Ofname$
  134.     ENDIF
  135.     opfail%=-1
  136.     CREATE Ofname$,A,c$,d$ :REM get OPL header creation for free
  137.     opfail%=0
  138.     CLOSE
  139.     REM        reopen with read, write and seek access, as an existing binary file
  140.     ret%=IOOPEN(Outch%,Ofname$,$0303)
  141.     IF ret%<0
  142.         RAISE ret%
  143.     ENDIF
  144.     
  145.     operrs::
  146.     ONERR endop::
  147.     IF opfail%=-1
  148.         CLOSE :REM raise occured during CREATE
  149.     ENDIF
  150.     endop::
  151.     ONERR OFF
  152.     RETURN ERR
  153. ENDP     
  154. REM OpenChs
  155.  
  156. PROC Retr:
  157. REM  =========
  158. REM Retrieves deleted records and puts them into new file
  159. REM > Returns 0 if OK, else an error code
  160.     LOCAL ret%
  161.     LOCAL contlen%
  162.     LOCAL rectype%
  163.     LOCAL typlen%
  164.     
  165.     ONERR reterrs::
  166.     WHILE -1
  167.         ret%=ReadHead:
  168.         IF ret%=-36
  169.             ret%=0
  170.             BREAK
  171.         ENDIF
  172.         typlen%=PEEKW(ADDR(Wrkbuf$)+1)  
  173.         IF ret%<>0
  174.             RAISE ret%
  175.         ENDIF
  176.         rectype%=(typlen% AND $F000)  :REM top nibble of this is type code
  177.         contlen%=(typlen% AND $0FFF)
  178.         IF (rectype%<>0) OR (contlen%=0)
  179.             ret%=SkipCont:(contlen%)
  180.             IF ret%<>0
  181.                 RAISE ret%
  182.             ENDIF
  183.             REM just go round the loop again
  184.         ELSE
  185.             REM read, check, then write new record
  186.             ret%=ChkWrite:(contlen%)
  187.             IF ret%<>0
  188.                 RAISE ret%
  189.             ENDIF
  190.         ENDIF
  191.     ENDWH
  192.     
  193.     reterrs::
  194.     ONERR OFF
  195.     RETURN ERR
  196. ENDP  
  197. REM Retr
  198.  
  199. PROC ChkWrite:(contlen%)
  200. REM  =========
  201. REM  read record content from current position twice to validate
  202. REM  it, then read it again and write it to the new file
  203. REM  increments global variables Undels% and Unrecog%
  204. REM  if the record was undeleted, or had invalid structure
  205. REM  to be a type=main record
  206. REM  the input file is positioned at the next byte after the
  207. REM  end of the record on exit
  208. REM  > returns error code on error
  209.     LOCAL ret%
  210.     LOCAL lines%
  211.     LOCAL toread%
  212.     LOCAL todo%
  213.     LOCAL stpos&
  214.     
  215.     ONERR chkwerrs::
  216.     stpos&=0
  217.     ret%=IOSEEK(Inpch%,3,stpos&) :REM save position for 2nd pass
  218.     IF ret%<0
  219.         RAISE ret%
  220.     ENDIF
  221.     
  222.     REM Pass 1 - check that all record may be read
  223.     todo%=contlen%
  224.     WHILE todo%>0
  225.         toread%=255 :REM read in a buffer full at a time
  226.         IF todo%<toread%
  227.             toread%=todo%
  228.         ENDIF
  229.         ret%=IOREAD(Inpch%,ADDR(Wrkbuf$)+1,toread%)
  230.         IF ret%<0
  231.             RAISE ret%
  232.         ELSEIF ret%<>toread%
  233.             ret%=100   :REM file must be corrupt!
  234.             RAISE ret%
  235.         ENDIF
  236.         todo%=todo%-toread%
  237.     ENDWH
  238.     
  239.     REM Pass 2 - check it is formed of up to 128 leading byte
  240.     REM          strings, and that are no 00 or 01-valued bytes
  241.     ret%=IOSEEK(Inpch%,1,stpos&) :REM seek to start of content
  242.     IF ret%<0
  243.         RAISE ret%
  244.     ENDIF
  245.     lines%=0    
  246.     todo%=contlen%
  247.     WHILE todo%>0
  248.         ret%=IOREAD(Inpch%,ADDR(Wrkbuf$)+1,1)
  249.         IF ret%<0
  250.             RAISE ret%
  251.         ENDIF
  252.         POKEB ADDR(Wrkbuf$),1
  253.         toread%=ASC(Wrkbuf$)
  254.         todo%=todo%-1
  255.         IF todo%<toread%
  256.             REM cannot be main type record - is a descriptive record
  257.             ret%=8000 :REM must not raise with this, since its not an error
  258.             RAISE 0
  259.         ENDIF
  260.         ret%=IOREAD(Inpch%,ADDR(Wrkbuf$)+1,toread%)
  261.         IF ret%<0
  262.             RAISE ret%
  263.         ELSEIF ret%<>toread%
  264.             ret%=101   :REM file error - certainly should not occur
  265.             RAISE ret%
  266.         ENDIF
  267.         POKEB ADDR(Wrkbuf$),toread%
  268.         todo%=todo%-toread%
  269.         ret%=ChkLine:(toread%)
  270.         lines%=lines%+1
  271.         IF lines%>128
  272.             REM can't have been a main type record
  273.             ret%=8000
  274.             RAISE 0
  275.         ENDIF
  276.         IF ret%=8000 :REM may be returned by ChkLine 
  277.             RAISE 0    :REM cant have beena main type record
  278.         ENDIF
  279.     ENDWH
  280.  
  281.     REM Read 3 - read it again, and write it to the new file
  282.     ret%=WriteHd:(contlen%)
  283.     IF ret%<0
  284.         REM write error to new file
  285.         RAISE ret%
  286.     ENDIF
  287.     ret%=IOSEEK(Inpch%,1,stpos&) :REM seek to start of content
  288.     IF ret%<0
  289.         RAISE ret%
  290.     ENDIF
  291.     todo%=contlen%
  292.     WHILE todo%>0
  293.         toread%=255
  294.         IF todo%<toread%
  295.             toread%=todo%
  296.         ENDIF
  297.         ret%=IOREAD(Inpch%,ADDR(Wrkbuf$)+1,toread%)
  298.         IF ret%<0
  299.             RAISE ret%
  300.         ELSEIF ret%<>toread%
  301.             ret%=102   :REM Should not occur: so could not form record
  302.             RAISE ret%
  303.         ENDIF
  304.         todo%=todo%-toread%
  305.         ret%=WriteDat:(toread%)
  306.         IF ret%<0
  307.             REM write error to new file
  308.             RAISE ret%
  309.         ENDIF
  310.     ENDWH
  311.     Undels%=Undels%+1
  312.  
  313.     chkwerrs::
  314.     ONERR OFF
  315.     IF ret%=8000
  316.         REM raise used to break when record deduced to be a Descriptive record
  317.         Unrecog%=Unrecog%+1
  318.     ENDIF
  319.     ret%=ERR
  320.     IF ret%=0
  321.         REM position to start of next record
  322.         ret%=IOSEEK(Inpch%,1,stpos&)
  323.         IF ret%=0
  324.             stpos&=contlen%
  325.             ret%=IOSEEK(Inpch%,3,stpos&)  :REM relative seek
  326.         ENDIF
  327.     ENDIF
  328. RETURN ret%
  329. ENDP        
  330. REM ChkWrite
  331.  
  332. PROC ChkLine:(llen%)
  333. REM  ===============
  334. REM  checks that the line stored in the global buffer does
  335. REM  not have bytes equalling 00 and 01, which are used
  336. REM  in the edit box displaying database records for control
  337. REM  purposes.
  338. REM  The record we're look