[vms/committed]: Add functions to get vms time

Tristan Gingold gingold@adacore.com
Thu May 27 13:43:00 GMT 2010


Hi,

this patch adds a few function to get current time in VMS format and to convert a time from UNIX to VMS.
This will be used by vms-lib.c

Tristan.

bfd/
2010-05-27  Tristan Gingold  <gingold@adacore.com>

	* vms-misc.c: Define __NEW_STARLET.  Remove trailing spaces.
	(VMS_TIME_FACTOR, VMS_TIME_OFFSET): New macros.
	(vms_time_to_time_t): Use them instead of local const.
	(vms_time_t_to_vms_time): New function.
	(vms_get_time): Likewise.
	(vms_raw_get_time): Likewise.
	* vms.h	(vms_time_t_to_vms_time): New declaration.
	(vms_get_time): Likewise.
	(vms_raw_get_time): Likewise.

Index: vms-misc.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-misc.c,v
retrieving revision 1.34
diff -c -r1.34 vms-misc.c
*** vms-misc.c	25 May 2010 10:14:15 -0000	1.34
--- vms-misc.c	27 May 2010 13:33:35 -0000
***************
*** 33,43 ****
  #include "safe-ctype.h"
  
  #ifdef VMS
! #if defined(__GNUC__) && !defined(globalref)
! #define globalref extern
! #endif
  #include <rms.h>
  #include <unixlib.h>
  #include <starlet.h>
  #define RME$C_SETRFM 0x00000001
  #include <unistd.h>
--- 33,42 ----
  #include "safe-ctype.h"
  
  #ifdef VMS
! #define __NEW_STARLET
  #include <rms.h>
  #include <unixlib.h>
+ #include <gen64def.h>
  #include <starlet.h>
  #define RME$C_SETRFM 0x00000001
  #include <unistd.h>
***************
*** 497,515 ****
      fout++;
    else
      fout = filename;
!       
    /* Strip UNIX path.  */
    fptr = strrchr (fout, '/');
    if (fptr != NULL)
      fout = fptr + 1;
!   
    fname = strdup (fout);
  
    /* Strip suffix.  */
    fptr = strrchr (fname, '.');
    if (fptr != 0)
      *fptr = 0;
!   
    /* Convert to upper case and truncate at 31 characters.
       (VMS object file format restricts module name length to 31).  */
    fptr = fname;
--- 496,514 ----
      fout++;
    else
      fout = filename;
! 
    /* Strip UNIX path.  */
    fptr = strrchr (fout, '/');
    if (fptr != NULL)
      fout = fptr + 1;
! 
    fname = strdup (fout);
  
    /* Strip suffix.  */
    fptr = strrchr (fname, '.');
    if (fptr != 0)
      *fptr = 0;
! 
    /* Convert to upper case and truncate at 31 characters.
       (VMS object file format restricts module name length to 31).  */
    fptr = fname;
***************
*** 526,561 ****
    return fname;
  }
  
! /* Convert a raw VMS time to a unix time.  */
  
  time_t
  vms_time_to_time_t (unsigned int hi, unsigned int lo)
  {
-   const unsigned int off = 3506716800U;
-   const unsigned int factor = 10000000;
    unsigned int tmp;
    unsigned int rlo;
    int i;
  
    /* First convert to seconds.  */
!   tmp = hi % factor;
!   hi = hi / factor;
    rlo = 0;
    for (i = 0; i < 4; i++)
      {
        tmp = (tmp << 8) | (lo >> 24);
        lo <<= 8;
  
!       rlo = (rlo << 8) | (tmp / factor);
!       tmp %= factor;
      }
    lo = rlo;
  
    /* Return 0 in case of overflow.  */
!   if (lo > off && hi > 1)
      return 0;
  
!   return lo - off;
  }
  
  /* Convert a raw (stored in a buffer) VMS time to a unix time.  */
--- 525,633 ----
    return fname;
  }
  
! /* Compared to usual UNIX time_t, VMS time has less limits:
!    -  64 bit (63 bits in fact as the MSB must be 0)
!    -  100ns granularity
!    -  epoch is Nov 17, 1858.
!    Here has the constants and the routines used to convert VMS from/to UNIX time.
!    The conversion routines don't assume 64 bits arithmetic.  */
! 
! /* UNIX time granularity for VMS, ie 1s / 100ns.  */
! #define VMS_TIME_FACTOR 10000000
! 
! /* Number of seconds since VMS epoch of the UNIX epoch.  */
! #define VMS_TIME_OFFSET 3506716800U
! 
! /* Convert a VMS time to a unix time.  */
  
  time_t
  vms_time_to_time_t (unsigned int hi, unsigned int lo)
  {
    unsigned int tmp;
    unsigned int rlo;
    int i;
  
    /* First convert to seconds.  */
!   tmp = hi % VMS_TIME_FACTOR;
!   hi = hi / VMS_TIME_FACTOR;
    rlo = 0;
    for (i = 0; i < 4; i++)
      {
        tmp = (tmp << 8) | (lo >> 24);
        lo <<= 8;
  
!       rlo = (rlo << 8) | (tmp / VMS_TIME_FACTOR);
!       tmp %= VMS_TIME_FACTOR;
      }
    lo = rlo;
  
    /* Return 0 in case of overflow.  */
!   if (lo > VMS_TIME_OFFSET && hi > 1)
!     return 0;
! 
!   /* Return 0 in case of underflow.  */
!   if (lo < VMS_TIME_OFFSET)
      return 0;
  
!   return lo - VMS_TIME_OFFSET;
! }
! 
! /* Convert a time_t to a VMS time.  */
! 
! void
! vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo)
! {
!   unsigned short val[4];
!   unsigned short tmp[4];
!   unsigned int carry;
!   int i;
! 
!   /* Put into val.  */
!   val[0] = ut & 0xffff;
!   val[1] = (ut >> 16) & 0xffff;
!   if (sizeof (ut) > 4)
!     {
!       val[2] = (ut >> 32) & 0xffff;
!       val[3] = (ut >> 48) & 0xffff;
!     }
!   else
!     {
!       val[2] = 0;
!       val[3] = 0;
!     }
! 
!   /* Add offset.  */
!   tmp[0] = VMS_TIME_OFFSET & 0xffff;
!   tmp[1] = VMS_TIME_OFFSET >> 16;
!   tmp[2] = 0;
!   tmp[3] = 0;
!   carry = 0;
!   for (i = 0; i < 4; i++)
!     {
!       carry += tmp[i] + val[i];
!       val[i] = carry & 0xffff;
!       carry = carry >> 16;
!     }
! 
!   /* Multiply by factor, well first by 10000 and then by 1000.  */
!   carry = 0;
!   for (i = 0; i < 4; i++)
!     {
!       carry += val[i] * 10000;
!       val[i] = carry & 0xffff;
!       carry = carry >> 16;
!     }
!   carry = 0;
!   for (i = 0; i < 4; i++)
!     {
!       carry += val[i] * 1000;
!       val[i] = carry & 0xffff;
!       carry = carry >> 16;
!     }
! 
!   /* Write the result.  */
!   *lo = val[0] | (val[1] << 16);
!   *hi = val[2] | (val[3] << 16);
  }
  
  /* Convert a raw (stored in a buffer) VMS time to a unix time.  */
***************
*** 568,570 ****
--- 640,671 ----
  
    return vms_time_to_time_t (hi, lo);
  }
+ 
+ void
+ vms_get_time (unsigned int *hi, unsigned int *lo)
+ {
+ #ifdef VMS
+   struct _generic_64 t;
+ 
+   sys$gettim (&t);
+   *lo = t.gen64$q_quadword;
+   *hi = t.gen64$q_quadword >> 32;
+ #else
+   time_t t;
+ 
+   time (&t);
+   vms_time_t_to_vms_time (t, hi, lo);
+ #endif
+ }
+ 
+ /* Get the current time into a raw buffer BUF.  */
+ 
+ void
+ vms_raw_get_time (unsigned char *buf)
+ {
+   unsigned int hi, lo;
+ 
+   vms_get_time (&hi, &lo);
+   bfd_putl32 (lo, buf + 0);
+   bfd_putl32 (hi, buf + 4);
+ }
Index: vms.h
===================================================================
RCS file: /cvs/src/src/bfd/vms.h,v
retrieving revision 1.20
diff -c -r1.20 vms.h
*** vms.h	25 May 2010 10:14:15 -0000	1.20
--- vms.h	27 May 2010 13:33:35 -0000
***************
*** 115,120 ****
--- 115,123 ----
  extern unsigned char *get_vms_time_string (void);
  extern time_t vms_time_to_time_t (unsigned int hi, unsigned int lo);
  extern time_t vms_rawtime_to_time_t (unsigned char *);
+ extern void vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo);
+ extern void vms_get_time (unsigned int *hi, unsigned int *lo);
+ extern void vms_raw_get_time (unsigned char *buf);
  
  extern char * _bfd_vms_save_sized_string (unsigned char *, int);
  extern char * _bfd_vms_save_counted_string (unsigned char *);



More information about the Binutils mailing list