OPEN.FILE

From Pickwiki
Revision as of 23:48, 26 February 2015 by Conversion script (talk) (link fix)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search
                  function OPEN.FILE( FILENAME, FLAGS, FILEVAR, ERR.MSG )
* Return File handle: open file and keep file variable in Named Common or just return it.
* =======================================================================================
* 19.Jan.2012 james: Check if FLAGS is assigned to avoid errors going to the log.
* 31.Jan.2009 james: Major restructuring: Let's USE this thing !?
* 08.Feb.2008 james: Finally doing this the right way !? (From U2 Users maillist, etc).
* =======================================================================================
*
*   This is a hybrid of version from U2 Users group list and APP.PROGRS OPEN.FILE.B
*   (we don't want to use the UV version anyway in case we switch to Cache?)
*
*  Usage:
*
*    if not( OPEN.FILE("MYFILE", FLAGS, MYFILEVAR, ERR.MSG) ) then <error handling using ERR.MSG>
*
* ---------------------------------------------------------------------------------------
*
*  In :
*       FILENAME
*       FLAGS    : 'RESET' to reset COMMON.OPEN.FILE; not normally used.
*
*  Out:
*       FILEVAR  : Return the regular UV 'File Variable' used to READ[[/WRITE/etc]].
*       ERR.MSG  : If returned non-blank THERE'S A PROBLEM
*
*
*  @TODO :
*
*    - Replace all 'OPEN' statements with call to this program !!!!
*
*    - Enable commented code in REP.WRITE '[[OpenLocalFile]]' to use this instead.
*
*    - Comment out (make 'ununsed' ?) R$[[LOCAL_FILE_NAME_S]], etc, in REPLICATION.COMMON
*
*    - Once this is being called everywhere, we can REMOVE the 'Common' opens in STD.SETUP.
*
* =======================================================================================

  $include RMS.BP  RMS.COMMON        ;*  DEBUG.FLAG to check for 'OPEN.FILE' flag.
  $include UTIL.BP COMMON.OPEN.FILE

  ERR.MSG = ""
  OK      = @TRUE  ;*  Assume we get the file opened until proven otherwise.
  if not( assigned( FLAGS ) ) then FLAGS = ''  ;*  Avoid errors: not normally used anyway.
  
  locate 'OPEN.FILE.LOG' in FLAGS<1> setting dum then [[OpenFileLog]] = @TRUE else [[OpenFileLog]] = @FALSE
  
  gosub [[CheckResetCommon]]  ;*  Set '[[ResetCommon]]' but do it later (so we can log it if necessary):

  *  --- Setup logging flag :
  
  locate "OPEN.FILE.LOG" in DEBUG.FLAG<1> setting dummy then
    [[OpenFileLog]] = @TRUE
    [[OpenFileLogName]] = "/var/log/uv_OPENFILE.log"
  end else [[OpenFileLog]] = @FALSE
  
  * --- Reset the first time this is called _OR_ if we've switched UV Accounts:
  
  if [[ResetCommon]] then gosub [[ResetOpenFileCommon]]
  
  if FILENAME # '' then  ;*  Send '' for dummy options (e.g. 'RESET')
  
    * --- Finally: If we have the File open already, then return the cached FILEVAR:
    *     (use FM locate since it may be optimized ? TEST IT ?)
    
    if not( OF$USE.CACHE ) then  ;*  The hard way for testing:
      OF$FILE.POS = 1 ; gosub [[OpenNewFile]]
    end else
    
      locate(FILENAME, OF$FILENAME.S; OF$FILE.POS) then  ;*  Already open ?:
        [[LogMsg]] = "File ":FILENAME:" is already open in position ":OF$FILE.POS ; gosub [[WriteLog]]
        FILEVAR = OF$FILEVAR.S( OF$FILE.POS )
      end else
        gosub [[OpenNewFile]]
      end
    
    end
    OF$LAST.OPENED     = FILENAME
    OF$LAST.OPENED.POS = OF$FILE.POS

  end
return( OK )

*  --- Check if we need to Reset the commons: if this is the first time this is run; or
*      if the RESET flag is sent in.

[[CheckResetCommon]]:
  [[ResetCommon]] = @FALSE  ;*  This may still get set below too
  locate "RESET" in FLAGS<1> setting dummy then  ;*  Special flag to clear Global Common
    [[ResetCommon]] = @TRUE
  end else

    if not( assigned( OF$USE.CACHE ) ) then
      [[ResetCommon]] = @TRUE
    end else                ;*  And also reset if we change Accounts (LOGTO) :
      if OF$CURRENT.ACCOUNT # @WHO then [[ResetCommon]] = @TRUE
    end

  end

return ('')

[[ResetOpenFileCommon]]:
  [[LogMsg]] = "Clearing Global Common OPEN.FILE" ; gosub [[WriteLog]]
  OF$FILENAME.S      = ''    ;*  Reset the dynamic array of File Names
  mat OF$FILEVAR.S   = ''    ;*  This is not strictly necessary but may help hiding bugs
  OF$CURRENT.ACCOUNT = @WHO  ;*  Keep track of the current UV Account
  mat OF$ITEM.ID.S   = ''
  mat OF$ITEM.S      = ''
  OF$LAST.OPENED     = ''
  OF$LAST.OPENED.POS = 0
  open "CONTROL"   to CONTROL.FILE  else stopm "Unable to open CONTROL file"
  read OF$USE.CACHE from CONTROL.FILE, "USE.OPEN.FILE.CACHE"  else OF$USE.CACHE = @TRUE
return ('')

*  Open it first; so we let it open normally even if it can't be cached : (?)

[[OpenNewFile]]:
  open FILENAME to FILEVAR else
    ERR.MSG = 'Unable to open ':FILENAME ; [[LogMsg]] = ERR.MSG ; gosub [[WriteLog]]
    OK = @FALSE ; return('')
  end
  
  if OF$FILE.POS > MAX.OPEN.FILES then
    ERR.MSG = 'TOO MANY FILES OPEN !?' ; OK = @FALSE
    if [[OpenFileLog]] then [[LogMsg]] = ERR.MSG ; gosub [[WriteLog]]
  end else
    [[LogMsg]] = "Opening ":FILENAME:" in position ":OF$FILE.POS ; gosub [[WriteLog]]

    OF$FILENAME.S< OF$FILE.POS > = FILENAME  ;*  VM's to use standard Locate
    OF$FILEVAR.S( OF$FILE.POS )  = FILEVAR
    OF$ITEM.ID.S( OF$FILE.POS )  = ''        ;*  The LAST Id ONLY for READ.FILE
    OF$ITEM.S   ( OF$FILE.POS )  = ''        ;*  The LAST item ONLY for READ.FILE
  end
return ('')

*  This writes a Log file if '[[OpenFileLog]]' is set; also displays if '[[DebugIt]]' is set:

[[WriteLog]]:
  *if [[DebugIt]] then crt [[LogMsg]] ;* input j ; if j = 'D' then debug
  
  if [[OpenFileLog]] then
    *  We don't have 'CALLER' here like REP.WRITE; would it be useful ? We can get the PID though:
    [[LogMsg]] := ' (':USER.ID:'; pid:':RMS$PID:')'   ;*  PID now set in STD.SETUP
    
    call APPEND.UNIX.LOG( [[LogMsg]], [[OpenFileLogName]], [[AppendErr]])
    
    if [[AppendErr]] # '' then
      ERR = "Unable to Append to Log file ":[[OpenFileLogName]]:" !" 
      crt char(7):ERR
      ERR.MSG := ERR    ;*  Add to existing ERR.MSG if there ?
    end
  end
return ('')