/*****************************************************************************/
/*
                                 eNAMeL.h

Don't know what the 'e's actually represent, but this header is used to gloss
over :^) the issue of older versions of VMS and DECC not having a long NAM
structure or definitions used to support ODS-5.  For the same reason an
extended FIB structure definition must be provided.  For such environments this
header file provides the necessary infrastructure, allowing extended file
specification compliant code to be compiled and linked on pre-v7.2 systems. 
This should then be able to be executed on both the pre-v7.2 systems and others
having v7.2ff installed (which is a nice trick if it doesn't bring you
unstuck too often).

Of course runtime decision structures based on the VMS version, device ACP
type, etc., must be used if pre-v7.2 systems are to avoid using the NAML
structure with RMS (which would of course result in runtime errors).

No such constraint apparently exists with using the extended FIB structure as
it contains no sanity check item that I can see identifying either it's role as
a FIB or it's size as a FIB!  (These must just get longer over time ;^)

Programs using this approach must use the ENAMEL_RMS_NAML macro to initialize
the NAML structure.  This will also work for VMS versions earlier than those
that support the NAML structure and would not have the cc$rms_naml structure
available.  That is use,

  struct NAML  a_naml;
  ENAMEL_RMS_NAML(a_naml)

instead of,

  struct NAML  a_naml = cc$rms_naml;

Programs using this header file can check whether the native header NAML was
used or the ENAMEL.H header NAML by checking for the existance of an
ENAMEL_NAML macro.  In a similar fashion, whether the 'enamel_fibdef' structure 
needs to be used or the native 'fibdef' structure, by checking for the
existance of the ENAMEL_FIBDEF macro.

The ENAMEL_NAML_SANITY_CHECK and ENAMEL_FIBDEF_SANITY_CHECK macros provide a
crude sanity check against any real stupid problems with the ENAMEL.H NAML
structure (such as compilation member alignment issues, etc.) and should be
incorporated somewhere at the start of runtime for this purpose.


VERSION HISTORY
---------------
21-DEC-2003  MGD  minor conditional mods to support IA64
13-AUG-2002  MGD  change detection of FIB$C_LENGTH (DECC V6.5?)
30-MAR-2002  MGD  force this FIBDEF to be used if FIBDEF not otherwise defined
23-DEC-1999  MGD  initial
*/
/*****************************************************************************/

#ifndef ENAMEL_H_LOADED
#define ENAMEL_H_LOADED 1

#ifndef __VAX

#include <atrdef.h>
#include <fibdef.h>
#include <namdef.h>

/*********************/
/* ATRDEF DEFINITION */
/*********************/

#ifndef __NEW_STARLET

/* apparently not all compiler environments have ATRDEF defined */
#ifndef ATRDEF

#undef _atrdef

#ifndef __VAX
#   pragma member_alignment __save
#   pragma member_alignment
#endif

typedef struct _atrdef
{
   unsigned short int atr$w_size;
   unsigned short int atr$w_type;
   void *atr$l_addr;
} ATRDEF;
#endif /* ATRDEF */

#ifndef __VAX
#   pragma member_alignment __restore
#endif

#endif /* __NEW_STARLET */

/*******************/
/* NAML DEFINITION */
/*******************/

/* if NAML has not been defined (i.e. Alpha pre-V7.2) conjure one up! */
#ifndef NAML

/* length of NAML block */
#define NAML$C_BLN 248
/* RMS code for NAML block */
#define NAML$C_BID   4

#pragma member_alignment __save

/* this works for DECC 6.2 at least */
struct namldef
{
#pragma __nomember_alignment
   unsigned char  naml$b_bid;
   unsigned char  naml$b_bln;
   unsigned char  naml$b_rss;
   unsigned char  naml$b_rsl;
   char  *naml$l_rsa;
   unsigned char  naml$b_nop;
   unsigned char  naml$b_rfs;
   unsigned char  naml$b_ess;
   unsigned char  naml$b_esl;
   char  *naml$l_esa;
   struct namldef  *naml$l_rlf_naml;
   char  naml$t_dvi [16];
   unsigned short int  naml$w_fid [3];
   unsigned short int  naml$w_did [3];
   unsigned int  naml$l_wcc;
   unsigned int  naml$l_fnb;
   unsigned char  naml$b_node;
   unsigned char  naml$b_dev;
   unsigned char  naml$b_dir;
   unsigned char  naml$b_name;
   unsigned char  naml$b_type;
   unsigned char  naml$b_ver;
   unsigned char  naml$b_nmc;
   char  namldef$$_fill_6 [1];
   char  *naml$l_node;
   char  *naml$l_dev;
   char  *naml$l_dir;
   char  *naml$l_name;
   char  *naml$l_type;
   char  *naml$l_ver;
   unsigned short int  naml$w_first_wild_dir;
   unsigned short int  naml$w_long_dir_levels;
   unsigned int  namldef$$_fill_7 [1];
   unsigned int  naml$l_long_defname_size;
   char  *naml$l_long_defname;
   unsigned int  naml$l_long_filename_size;
   char  *naml$l_long_filename;
   unsigned int  naml$l_long_node_size;
   char  *naml$l_long_node;
   unsigned int  naml$l_long_dev_size;
   char  *naml$l_long_dev;
   unsigned int  naml$l_long_dir_size;
   char  *naml$l_long_dir;
   unsigned int  naml$l_long_name_size;
   char  *naml$l_long_name;
   unsigned int  naml$l_long_type_size;
   char  *naml$l_long_type;
   unsigned int  naml$l_long_ver_size;
   char  *naml$l_long_ver;
#pragma __nomember_alignment __quadword
   unsigned int  naml$l_long_expand_size;
#pragma __nomember_alignment
   char  *naml$l_long_expand;
   unsigned  int naml$l_long_expand_alloc;
   int  naml$l_reserved_mbz_9;
#pragma __nomember_alignment __quadword
   unsigned int  naml$l_long_result_size;
#pragma __nomember_alignment
   char  *naml$l_long_result;
   unsigned int  naml$l_long_result_alloc;
   int  naml$l_reserved_mbz_8;
#pragma __nomember_alignment __quadword
   unsigned int  naml$l_filesys_name_size;
#pragma __nomember_alignment
   char  *naml$l_filesys_name;
   unsigned int  naml$l_filesys_name_alloc;
   unsigned int  naml$l_output_flags;
   unsigned int  naml$l_input_flags;
   int  naml$l_reserved_mbz_7;
   unsigned int  naml$q_user_context[2];
   int  naml$l_reserved_mbz_6;
   int  naml$l_reserved_mbz_5;
   int  naml$l_reserved_mbz_4;
   int  naml$l_reserved_mbz_3;
   int  naml$l_reserved_mbz_2;
   int  naml$l_reserved_mbz_1;
};
 
#define NAML namldef
#define ENAMEL_NAML namldef

#pragma member_alignment __restore

#define ENAMEL_NAML_USED "WASD NAML"

#else /* ifndef NAML */

#define ENAMEL_NAML_USED "VMS NAML"

#endif /* ifndef NAML */

/* block initialize macro */
#define ENAMEL_RMS_NAML(naml) \
{ \
   memset (&naml, 0, NAML$C_BLN); \
   naml.naml$b_bln = NAML$C_BLN; \
   naml.naml$b_bid = NAML$C_BID; \
}

/******************/
/* FIB DEFINITION */
/******************/

#pragma member_alignment __save
#pragma __nomember_alignment

#define ENAMEL_FIB$C_LENGTH 96
#define ENAMEL_PRE72_FIB$C_LENGTH 92

#ifndef __NEW_STARLET

/* apparently not all compiler environments have FIBDEF defined */
#ifndef FIB$C_LENGTH
#  define FIB$C_LENGTH 0
#endif /* FIB$C_LENGTH */

#endif /* __NEW_STARLET */

/* if the FIB looks pre-7.2 then use this local definition */
#if FIB$C_LENGTH <= ENAMEL_PRE72_FIB$C_LENGTH

#undef fibdef
#undef fib$l_acctl
#undef fib$w_fid
#undef fib$w_did
#undef fib$l_wcc
#undef fib$w_nmctl
#undef fib$w_exctl
#undef fib$l_exsz
#undef fib$l_exvbn
#undef fib$b_alopts
#undef fib$b_alalign
#undef fib$w_alloc
#undef fib$w_verlimit
#undef fib$b_agent_mode
#undef fib$b_ru_facility
#undef fib$l_aclctx
#undef fib$l_acl_status
#undef fib$l_status
#undef fib$l_alt_access
#undef fib$r_funcdepend
#undef fib$w_file_hdrseq_incr
#undef fib$w_dir_hdrseq_incr
#undef fib$w_file_dataseq_incr
#undef fib$w_dir_dataseq_incr
#undef fib$l_caching_options
#undef fib$w_sd_fid
 
struct enamel_fibdef
{
   unsigned int  fib$l_acctl;
   unsigned short int  fib$w_fid [3];
   unsigned short int  fib$w_did [3];
   unsigned int  fib$l_wcc;
   unsigned short int  fib$w_nmctl;
   unsigned short int  fib$w_exctl;
   unsigned int  fib$l_exsz;
   unsigned int  fib$l_exvbn;
   unsigned char  fib$b_alopts;
   unsigned char  fib$b_alalign;
   unsigned short int  fib$w_alloc [5];
   unsigned short int  fib$w_verlimit;
   unsigned char  fib$b_agent_mode;
   unsigned char  fib$b_ru_facility;
   unsigned int  fib$l_aclctx;
   unsigned int  fib$l_acl_status;
   unsigned int  fib$l_status;
   unsigned int  fib$l_alt_access;
   unsigned int  fib$r_funcdepend [2];
   unsigned short int  fib$w_file_hdrseq_incr;
   unsigned short int  fib$w_dir_hdrseq_incr;
   unsigned short int  fib$w_file_dataseq_incr;
   unsigned short int  fib$w_dir_dataseq_incr;
   unsigned int  fib$l_caching_options;
   unsigned short int  fib$w_sd_fid [3];
   short int  fibdef$$_reserved_1;
   /* the following is from VMS v7.2ff */
   unsigned char  fib$b_name_format_in;
   unsigned char  fib$b_name_format_out;
   unsigned char  fib$b_ascname_format;
   unsigned char  fib$b_reserved_2;
};
 
#define fibdef enamel_fibdef
#define FIBDEF enamel_fibdef
#define ENAMEL_FIBDEF enamel_fibdef

/* will need these too */
#define FIB$C_ISO_LATIN 1
#define FIB$M_NAMES_8BIT 0x1

#define ENAMEL_FIB_USED "WASD FIB"

#else /* FIB$C_LENGTH <= ENAMEL_PRE72_FIB$C_LENGTH */

#define ENAMEL_FIB_USED "VMS FIB"

#endif /* FIB$C_LENGTH <= ENAMEL_PRE72_FIB$C_LENGTH */

#pragma member_alignment __restore

/*****************/
/* SANITY CHECKS */
/*****************/

/* just a crude sanity check when using ENAMEL.H structures */
#ifdef ENAMEL_NAML
#   define ENAMEL_NAML_SANITY_CHECK \
      { if (sizeof(struct NAML) != NAML$C_BLN) \
           exit (SS$_BUGCHECK); }
#else
#   define ENAMEL_NAML_SANITY_CHECK
#endif
#ifdef ENAMEL_FIBDEF
#   define ENAMEL_FIBDEF_SANITY_CHECK \
      { if (sizeof(struct ENAMEL_FIBDEF) != ENAMEL_FIB$C_LENGTH) \
           exit (SS$_BUGCHECK); } 
#else
#   define ENAMEL_FIBDEF_SANITY_CHECK
#endif

#else /* ifndef __VAX */

#define ENAMEL_FIB_USED "VMS FIB"
#define ENAMEL_NAML_USED "no NAML"

#endif /* ifndef __VAX */

#ifndef __NEW_STARLET
#ifndef ATRDEF
#  define ATRDEF struct atrdef
#endif
#ifndef FIBDEF
#  define FIBDEF struct fibdef
#endif
#endif

#endif /* ENAMEL_H_LOADED */

/****************************************************************************/

