program cre;

  
CONST
  NameSize	= 30 ;		{ sz of input file name, do not alter }

  { example labels and sizes follow - user defines buffer sizes and labels }
  KeyXSize	= 2 ;		{ user defines size of largest key }
  KeyYSize	= 6 ;		{ user defines these labels and sizes }  

TYPE

  { following record is for example only }
  RecDef = RECORD	{ user defines field names and sizes }
    CASE integer OF	
      1 : (Dat1 : ARRAY [1..10] OF CHAR ;
           Dat2 : integer ) ;
      2 : (FYItem1 : ARRAY [1..30] OF CHAR ;
           FYItem2 : REAL ) ;
    END ;	{ User Defined Record }


  TwoWord	= ARRAY [1..2] OF integer ;	{ record number size }
  KeyDef	= RECORD
    CASE integer OF	{ user defines keylabels and sizes, as many as req. }
      1 : ( KeyX : ARRAY [1..KeyXSize] OF CHAR) ;
      2 : ( KeyY : ARRAY [1..KeyYSize] OF CHAR) ;
      3 : ( RNum : TwoWord ) ;    { use this def. of relative rec. # if req. }
    END ;

  RmsFileName	= ARRAY [1..NameSize] OF CHAR ;	{ file name, do not alter }
  RmsStatus	= ARRAY [1..2] OF integer ;	{ returned rms status codes }

  OrgTypes	= (SEQ,REL,IDX) ;	{ block i/o not supported }
  AllowTypes	= (Share,NoShare) ;      { what others can do }
  AccessTypes	= (PBoth,PRead,PWrite) ; { what you can do to the file }
  FormType = (FFIX,FVAR,FSTREAM) ;	{ record format type }
  { specify file options, if field not altered, default will be selected }
  RmsFileDesc	= RECORD
    { -- Use with PRMOPE to define an existing file to be opened  -- }
    Org		: OrgTypes ;	{ spec. file type, no default }
    FileName	: RmsFileName ;	{ full spec. of rms file, no default }
    LogChan	: integer ;	{ spec. ch. n, no def., n<= TKB UNITS=n }
    Allow	: AllowTypes ;	{ what others may do with file, def Noshare }
    Access	: AccessTypes ;	{ what you may do to the file, default Both }
    RecordSize  : INTEGER ;	{ spec. max. file rec. sz, user rec. buf can 
      be < full, spec. bytes to xfer with recsize in Ret & StoRecord buffers }
    Windows	: INTEGER ;	{ no. of ret. windows, default usually 7 }

    { enable the following options with a capital "Y", any other = default }
    DeferWrite	: CHAR ;	{ IDX, defer write, def. write each record }
    Unlock    	: CHAR ;  	{ unlock if locked, def. bomb on open if "L" }
    ObeyFill	: CHAR ;	{ obey bucket fill numbers, def. fill to max }
    MassInsert	: CHAR ;	{ IDX, ref. rms-11 macro ref. man. rab rop }
    FileEnd	: CHAR ;	{ SEQ only, place file stream at end of file }

    { file creation fields }
    RecForm	: FormType ;	{ rec. format, FSTREAM for seq., Def.= FFix }
    Allocation  : TwoWord ;	{ no. blocks allocated to file, def. 0 blks }
    BucketSize	: integer ;	{ data bucket size, default size 1 bucket }
    ExtQua	: integer ;	{ no. blks dynamic extend file, default 1}
    { Enable following with capital "Y", if not loaded, default is selected }
    Contiguous	: CHAR ;	{ create a contiguous file, Def. fragmented }
    Temporary	: char ;	{ delete the file when closed, def. no del. }

    workspace	: Array [1..160] of char ; 
  END ;	{ RmsFileDesc Record }


  SearchTypes	= (EQ,GT,GE,RFA,NEX,REC) ; { for GET use KeyData(EQ'=',GT'>',
                    GE'>='), RFA, next seq. rec(NEX) or Rec. # (org=REL) }
  ThreeWord	= ARRAY [1..3] OF Integer ;	{ for RFA's, big file huh }
  RecOps	= (GET,FIND,PUT,UPDATE) ;
  RetRecord = RECORD
    { - USE with PRMRET, INPUT - to GET and FIND - INPUT/OUTPUT ref. to PRM }
    KeyNum	: Threeword ;	{ INPUT- IDX Key # or RFA, search defines }
    Search	: SearchTypes ;	{ INPUT - spec. search opr }
    RecSize	: integer ;	{ INPUT - sz rec. to GET, (sz of rec. buffer)
                                  OUTPUT- sz rec. returned to user rec. buf }
    RFAout	: ThreeWord ;	{ OUTPUT- valid if search <> RFA }
    KeySize	: integer ;	{ INPUT - size of key data, <= full key size }
    KeyData	: KeyDef ;	{ INPUT - IDX or REL, key string or rec. # }
  END ;	{ RetRecord RECORD Definition }

  StoRecord = RECORD
      { USE with PRMSTO, Input to PUT and UPDATE - INPUT/OUTPUT ref. to PRM }
      RecSize	: integer ;	{ INPUT - spec. part or all or rec. buffer 
                                  data to be stored, <= full rec. sz }
      RFAOut	: ThreeWord ;	{ OUTPUT - rfa where record was stored }
      Key	: KeyDef ;	{ INPUT - REL ONLY, spec. rec. # for store }
    END ;	{ StoRecord Record }

    KType = (StrKey,IntKey) ;	{ string or unsigned integer key type }
  IdxKeyDesc = RECORD	{ used with prmkey to define key of indexed file }
                        { use prior to PrmCre of an indexed file type }
      KeyNum	: Integer ;	{ key of ref. #, def. asc. order, start 0 }
      KeyPos	: Integer ;	{ byte position of key in rec., start byte 0 }
      KeySiz	: Integer ;	{ size of the key defining, max. = 255 }
      KeyTyp	: KType ;	{ string or unsigned integer, def.=string }
      KeyDup	: char ;	{ 'Y' to allow duplicate keys, def. no dup }
      KeyChg	: char ;	{ 'Y' for key changes, alt. only, def no chg }
      KeyNul	: char ;	{ null key value, alt. string keys only }
    END ;	{ IdxKeyDesc }



 {***********************************************************************
                     END PRM CONST and TYPE
 *********************************************************************** }



VAR
  FBuf		: RmsFileDesc ;		{ create buffer }
  RBuf		: RecDef ;		{ record buffer }
  SBuf		: Storecord ;		{ storage desc. buffer }
  KBuf		: IdxKeyDesc ;		{ describe indexed file key }
  PrmStatus 	: RmsStatus ;


{***********************************************************************
 *                 START PRM PROCEDURE CALLS                           *
 *********************************************************************** }
  
  
{ close the file }
PROCEDURE PRMClo ( VAR Filebuf : RmsFileDesc ;	{ ref. to file to close }
                   VAR Status  : RmsStatus ) ;	{ STS and STV }
                   EXTERNAL ;

PROCEDURE PrmCre ( VAR CreBuf : RmsFileDesc ;
                   VAR Status : RmsStatus ) ;
                   EXTERNAL ;

{ Define a single key of and indexed file, use in conj. with PrmCre }
{ Define keys in ascending order starting with key 0 definition }
PROCEDURE PRMKey (VAR Filebuf : RmsFileDesc ;
                  VAR KeyBuf : IdxKeyDesc ;
                  VAR Status  : RmsStatus ) ;	{ status of Sts and Stv }
                   EXTERNAL ;

{ Store a record in the specified file }
PROCEDURE PRMSto ( Operation   : RecOps ;	{ define PUT or UPDATE }
                   VAR FileBuf : RmsFileDesc ;	{ ref. to file for store }
                   VAR StoData : StoRecord ;	{ store variables }
                   VAR RecBuf  : RecDef ;	{ rec. buf connected to use }
                   VAR Status  : RmsStatus);	{ STS and STV }
                   EXTERNAL ;

{ Define a routine to GET and DISPOSE heap space, execute first in root seg }
PROCEDURE RmsIni ; EXTERNAL ;

{***********************************************************************
 *                   END PRM PROCEDURE CALLS                           *
 *********************************************************************** }
  
  

BEGIN
  RmsIni ;

 { define all the keys of the file }
  WITH KBuf DO
    BEGIN
      KeyNum := 0 ;
      KeyPos := 0 ;
      KeySiz := 5 ;
    END ;
  PrmKey ( FBuf, KBuf, PrmStatus ) ;
  WITH KBuf DO
    BEGIN
      KeyNum := 1 ;
      KeyPos := 3 ;
      KeySiz := 5 ;
    END ;
  PrmKey ( FBuf, KBuf, PrmStatus ) ;
  WITH KBuf DO
    BEGIN
      KeyNum := 2 ;
      KeyPos := 4 ;
      KeySiz := 3 ;
    END ;
  PrmKey ( FBuf, KBuf, PrmStatus ) ;
  WITH KBuf DO
    BEGIN
      KeyNum := 3 ;
      KeyPos := 8 ;
      KeySiz := 2 ;
    END ;
  PrmKey ( FBuf, KBuf, PrmStatus ) ;
 { keys have been defined }

{ set-up the file parameters }
  WITH FBuf DO
    BEGIN
      Org := IDX ;
      FileName := 'cretst.IDX                    ' ;
      LogChan := 4 ;	
      RecordSize := 30 ;
      Allocation[1] := 10 ;
      Allocation[2] := 0 ;
      BucketSize := 2 ;
      Contiguous := 'Y' ;
    END ;	{ WITH FBuf } 
  PrmCre ( FBuf, PrmStatus ) ;
  writeln ( 'File created, sts=',prmstatus[1], '   stv=',prmstatus[2] ) ;

  { store a record }
  RBuf.Dat1 := 'file data ' ;
  RBuf.Dat2 := 64 ;
  SBuf.RecSize := 30 ;
  SBuf.Key.rnum[1] := 1 ;	{ store in record number 1 }
  SBuf.Key.rnum[2] := 0 ;
  PrmSto ( PUT, FBuf, SBuf, RBuf, PrmStatus ) ;
  writeln ( 'Store data, sts=',prmstatus[1], '   stv=',prmstatus[2] ) ;

  PrmClo ( FBuf, PrmStatus ) ;
  writeln ( 'File closed, sts=',prmstatus[1], '   stv=',prmstatus[2] ) ;
END.

