home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / ods2 / src / vmstime.c < prev    next >
C/C++ Source or Header  |  1998-09-11  |  20KB  |  755 lines

  1. /*
  2.  
  3.        VMSTIME.C  v1.2
  4.  
  5.        Author: Paul Nankervis
  6.  
  7.         V1.2 - cleanup to stop compiler warnings
  8.  
  9.        Please send bug reports or requests for enhancement
  10.        or improvement via email to:     PaulNank@au1.ibm.com
  11.  
  12.  
  13.        This module contains versions of the VMS time routines
  14.        sys$numtim(), sys$asctim() and friends... They are
  15.        intended to be compatible with the routines of the same
  16.        name on a VMS system (so descriptors feature regularly!)
  17.  
  18.        This code relies on being able to manipluate day numbers
  19.        and times using 32 bit arithmetic to crack a VMS quadword
  20.        byte by byte. If your C compiler doesn't have 32 bit int
  21.        fields give up now! On a 64 bit systems this code could
  22.        be modified to do 64 bit operations directly....
  23.  
  24.        One advantage of doing arihmetic byte by byte is that
  25.        the code does not depend on what 'endian' the target
  26.        machine is - it will always treat bytes in the same order!
  27.        (Hopefully VMS time bytes will always be in the same order!)
  28.  
  29.        A couple of stupid questions to go on with:-
  30.            o OK, I give up! What is the difference between a zero
  31.              date and a zero delta time?
  32.            o Anyone notice that the use of 16 bit words in
  33.              sys$numtim restricts delta times to 65535 days?
  34.  
  35.                                        Paul Nankervis
  36.  
  37. */
  38.  
  39.  
  40. #include <stdio.h>
  41. #include <memory.h>
  42. #include "vmstime.h"            /* Our header file! */
  43. #include <time.h>               /* C header for $GETTIM to find time */
  44.  
  45.  
  46.  
  47. #ifndef SS$_NORMAL
  48. #define SS$_NORMAL 1
  49. #define SS$_IVTIME 388
  50. #define LIB$_ONEDELTIM 1410020
  51. #endif
  52.  
  53.  
  54. #define TIMEBASE 100000         /* 10 millisecond units in quadword */
  55. #define TIMESIZE 8640000        /* Factor between dates & times */
  56.  
  57. #define QUAD_CENTURY_DAYS 146097
  58. /*   (400*365) + (400/4) - (400/100) + (400/400)   */
  59. #define CENTURY_DAYS    36524
  60. /*   (100*365) + (100/4) - (100/100)    */
  61. #define QUAD_YEAR_DAYS  1461
  62. /*   (4*365) + (4/4)    */
  63. #define YEAR_DAYS       365
  64. /*   365        */
  65. #define OFFSET_DAYS     94187
  66. /*   ((1858_1601)*365) + ((1858_1601)/4) - ((1858_1601)/100)
  67.    + ((1858_1601)/400) + 320
  68.         OFFSET FROM 1/1/1601 TO 17/11/1858  */
  69. #define BASE_YEAR       1601
  70.  
  71.  
  72.  
  73. /* combine_date_time() is an internal routine to put date and time into a
  74.    quadword - basically the opposite of lib_day() .... */
  75.  
  76. unsigned combine_date_time(int days,struct TIME *timadr,int day_time)
  77. {
  78.     if (day_time >= TIMESIZE) {
  79.         return SS$_IVTIME;
  80.     } else {
  81.  
  82.         /* Put days into quad timbuf... */
  83.  
  84.         register unsigned count,time;
  85.         register unsigned char *ptr;
  86.         count = 8;
  87.         ptr = timadr->time;
  88.         time = days;
  89.         do {
  90.             *ptr++ = time;
  91.             time = (time >> 8);
  92.         } while (--count > 0);
  93.  
  94.         /* Factor in the time... */
  95.  
  96.         count = 8;
  97.         ptr = timadr->time;
  98.         time = day_time;
  99.         do {
  100.             time += *ptr * TIMESIZE;
  101.             *ptr++ = time;
  102.             time = (time >> 8);
  103.         } while (--count > 0);
  104.  
  105.         /* Factor by time base... */
  106.  
  107.         count = 8;
  108.         ptr = timadr->time;
  109.         time = 0;
  110.         do {
  111.             time += *ptr * TIMEBASE;
  112.             *ptr++ = time;
  113.             time = (time >> 8);
  114.         } while (--count > 0);
  115.  
  116.         return SS$_NORMAL;
  117.     }
  118. }
  119.  
  120.  
  121.  
  122. /* sys_gettim() implemented here by getting UNIX time in seconds since
  123.    1-Jan-1970 using time() and munging into a quadword... Some run time
  124.    systems don't seem to do this properly!!! Note that time() has a
  125.    resolution of only one second. */
  126.  
  127. unsigned sys_gettim(struct TIME *timadr)
  128. {
  129.     time_t curtim = time(NULL);
  130.     return combine_date_time(40587 + curtim / 86400,timadr,
  131.                              (curtim % 86400) * 100);
  132. }
  133.  
  134.  
  135. /* lib_cvt_vectim() takes individual time fields in seven word buffer and
  136.    munges into a quadword... */
  137.  
  138. unsigned short month_end[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
  139.  
  140. unsigned lib_cvt_vectim(unsigned short timbuf[7],struct TIME *timadr)
  141. {
  142.     int delta = 0;
  143.     register unsigned sts,days,day_time;
  144.     sts = SS$_NORMAL;
  145.  
  146.     /* lib_cvt_vectim packs the seven date/time components into a quadword... */
  147.  
  148.     if (timbuf[0] == 0 && timbuf[1] == 0) {
  149.         delta = 1;
  150.         days = timbuf[2];
  151.     } else {
  152.         register int leap = 0,year = timbuf[0],month = timbuf[1];
  153.         if (month >= 2) {
  154.             if ((year % 4) == 0) {
  155.                 if ((year % 100) == 0) {
  156.                     if ((year % 400) == 0) {
  157.                         leap = 1;
  158.                     }
  159.                 } else {
  160.                     leap = 1;
  161.                 }
  162.             }
  163.         }
  164.         days = timbuf[2];
  165.         if (year >= 1858 && year <= 9999 && month >= 1 &&
  166.             month <= 12 && days >= 1) {
  167.             days += month_end[month - 1];
  168.             if (month > 2) days += leap;
  169.             if (days <= month_end[month] + leap) {
  170.                 year -= BASE_YEAR;
  171.                 days += year * 365 + year / 4 - year / 100 + year / 400
  172.                      - OFFSET_DAYS - 1;
  173.             } else {
  174.                 sts = SS$_IVTIME;
  175.             }
  176.         } else {
  177.             sts = SS$_IVTIME;
  178.         }
  179.     }
  180.     if (timbuf[3] > 23 || timbuf[4] > 59 ||
  181.         timbuf[5] > 59 || timbuf[6] > 99) {
  182.         sts = SS$_IVTIME;
  183.     }
  184.     if (sts & 1) {
  185.         day_time = timbuf[3] * 360000 + timbuf[4] * 6000 +
  186.             timbuf[5] * 100 + timbuf[6];
  187.         sts = combine_date_time(days,timadr,day_time);
  188.         if (delta) {
  189.  
  190.             /* We have to 2's complement delta times - sigh!! */
  191.  
  192.             register unsigned count,time;
  193.             register unsigned char *ptr;
  194.             count = 8;
  195.             ptr = timadr->time;
  196.             time = 1;
  197.             do {
  198.                 time = time + ((~*ptr) & 0xFF);
  199.                 *ptr++ = time;
  200.                 time = (time >> 8);
  201.             } while (--count > 0);
  202.         }
  203.     }
  204.     return sts;
  205. }
  206.  
  207.  
  208. /* lib_day() is a routine to crack quadword into day number and time */
  209.  
  210. unsigned lib_day(int *days,struct TIME *timadr,int *day_time)
  211. {
  212.     register unsigned date,time,count;
  213.     register unsigned char *dstptr,*srcptr;
  214.     struct TIME wrktim;
  215.     int delta;
  216.  
  217.     /* If no time specified get current using gettim() */
  218.  
  219.     if (timadr == NULL) {
  220.         register unsigned sts;
  221.         sts = sys_gettim(&wrktim);
  222.         if ((sts & 1) == 0) {
  223.             return sts;
  224.         }
  225.         delta = 0;
  226.         srcptr = wrktim.time + 7;
  227.     } else {
  228.  
  229.         /* Check specified time for delta... */
  230.  
  231.         srcptr = timadr->time + 7;
  232.         if ((delta = (*srcptr & 0x80))) {
  233.  
  234.             /* We have to 2's complement delta times - sigh!! */
  235.  
  236.             count = 8;
  237.             srcptr = timadr->time;
  238.             dstptr = wrktim.time;
  239.             time = 1;
  240.             do {
  241.                 time = time + ((~*srcptr++) & 0xFF);
  242.                 *dstptr++ = time;
  243.                 time = (time >> 8);
  244.             } while (--count > 0);
  245.             srcptr = wrktim.time + 7;
  246.         }
  247.     }
  248.  
  249.  
  250.     /* Throw away the unrequired time precision */
  251.  
  252.     count = 8;
  253.     dstptr = wrktim.time + 7;
  254.     time = 0;
  255.     do {
  256.         time = (time << 8) | *srcptr--;
  257.         *dstptr-- = time / TIMEBASE;
  258.         time %= TIMEBASE;
  259.     } while (--count > 0);
  260.  
  261.  
  262.     /* Seperate the date and time */
  263.  
  264.     date = time = 0;
  265.     srcptr = wrktim.time + 7;
  266.     count = 8;
  267.     do {
  268.         time = (time << 8) | *srcptr--;
  269.         date = (date << 8) | (time / TIMESIZE);
  270.         time %= TIMESIZE;
  271.     } while (--count > 0);
  272.  
  273.     /* Return results... */
  274.  
  275.     if (delta) {
  276.         *days = -(int) date;
  277.         if (day_time != NULL) *day_time = -(int) time;
  278.     } else {
  279.         *days = date;
  280.         if (day_time != NULL) *day_time = time;
  281.     }
  282.  
  283.     return SS$_NORMAL;
  284. }
  285.  
  286.  
  287.  
  288. /* sys_numtim() takes quadword and breaks it into a seven word time buffer */
  289.  
  290. unsigned char month_days[] = {31,29,31,30,31,30,31,31,30,31,30,31};
  291.  
  292. unsigned sys_numtim(unsigned short timbuf[7],struct TIME *timadr)
  293. {
  294.     register int date,time;
  295.  
  296.     /* Use lib_day to crack time into date/time... */
  297.  
  298.     {
  299.         int days,day_time;
  300.         register unsigned sts;
  301.         sts = lib_day(&days,timadr,&day_time);
  302.         if ((sts & 1) == 0) {
  303.             return sts;
  304.         }
  305.         date = days;
  306.         time = day_time;
  307.     }
  308.  
  309.     /* Delta or date... */
  310.  
  311.     if (date < 0 || time < 0) {
  312.         timbuf[2] = -date;      /* Days */
  313.         timbuf[1] = 0;          /* Month */
  314.         timbuf[0] = 0;          /* Year */
  315.         time = -time;
  316.  
  317.     } else {
  318.  
  319.         /* Date... */
  320.  
  321.         register int year,month;
  322.         date += OFFSET_DAYS;
  323.         year = BASE_YEAR + (date / QUAD_CENTURY_DAYS) * 400;
  324.         date %= QUAD_CENTURY_DAYS;
  325.  
  326.         /* Kludge century division - last century in quad is longer!! */
  327.  
  328.         if ((month = date / CENTURY_DAYS) == 4) month = 3;
  329.         date -= month * CENTURY_DAYS;
  330.         year += month * 100;
  331.  
  332.         /* Use the same technique to find out the quad year and year -
  333.            last year in quad is longer!! */
  334.  
  335.         year += (date / QUAD_YEAR_DAYS) * 4;
  336.         date %= QUAD_YEAR_DAYS;
  337.  
  338.         if ((month = date / YEAR_DAYS) == 4) month = 3;
  339.         date -= month * YEAR_DAYS;
  340.         year += month;
  341.  
  342.         /* Adjust for years which have no Feb 29th */
  343.  
  344.         if (date++ > 58) {
  345.             if (month != 3) {
  346.                 date++;
  347.             } else {
  348.                 if ((year % 100) == 0 && (year % 400) != 0) date++;
  349.             }
  350.         }
  351.         /* Figure out what month it is... */
  352.  
  353.         {
  354.             unsigned char *mthptr = month_days;
  355.             month = 1;
  356.             while (date > *mthptr) {
  357.                 date -= *mthptr++;
  358.                 month++;
  359.             }
  360.         }
  361.  
  362.         /* Return date results... */
  363.  
  364.         timbuf[2] = date;       /* Days */
  365.         timbuf[1] = month;      /* Month */
  366.         timbuf[0] = year;       /* Year */
  367.     }
  368.  
  369.     /* Return time... */
  370.  
  371.     timbuf[6] = time % 100;     /* Hundredths */
  372.     time /= 100;
  373.     timbuf[5] = time % 60;      /* Seconds */
  374.     time /= 60;
  375.     timbuf[4] = time % 60;      /* Minutes */
  376.     timbuf[3] = time / 60;      /* Hours */
  377.  
  378.     return SS$_NORMAL;
  379. }
  380.  
  381.  
  382.  
  383. /* sys_bintim() takes ascii time and convert it to a quadword */
  384.  
  385. char month_names[] = "-JAN-FEB-MAR-APR-MAY-JUN-JUL-AUG-SEP-OCT-NOV-DEC-";
  386. char time_sep[] = "::.";
  387.  
  388. unsigned sys_bintim(struct dsc$descriptor *timbuf,struct TIME *timadr)
  389. {
  390.     register int length = timbuf->dsc$w_length;
  391.     register char *chrptr = timbuf->dsc$a_pointer;
  392.     unsigned short wrktim[7];
  393.     int num,tf;
  394.  
  395.  
  396.     /* Skip leading spaces... */
  397.  
  398.     while (length > 0 && *chrptr == ' ') {
  399.         length--;
  400.         chrptr++;
  401.     }
  402.  
  403.     /* Get the day number... */
  404.  
  405.     num = -1;
  406.     if (length > 0 && *chrptr >= '0' && *chrptr <= '9') {
  407.         num = 0;
  408.         do {
  409.             num = num * 10 + (*chrptr++ - '0');
  410.         } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9');
  411.     }
  412.     /* Check for month separator "-" - if none delta time... */
  413.  
  414.     if (length > 0 && *chrptr == '-') {
  415.         chrptr++;
  416.  
  417.         /* Get current time for defaults... */
  418.  
  419.         sys_numtim(wrktim,NULL);
  420.         if (num >= 0) wrktim[2] = num;
  421.         num = 0;
  422.         if (--length >= 3 && *chrptr != '-') {
  423.             char *mn = month_names + 1;
  424.             num = 1;
  425.             while (num <= 12) {
  426.                 if (memcmp(chrptr,mn,3) == 0) break;
  427.                 mn += 4;
  428.                 num++;
  429.             }
  430.             chrptr += 3;
  431.             length -= 3;
  432.             wrktim[1] = num;
  433.         }
  434.         /* Now look for year... */
  435.  
  436.         if (length > 0 && *chrptr == '-') {
  437.             length--;
  438.             chrptr++;
  439.             if (length > 0 && *chrptr >= '0' && *chrptr <= '9') {
  440.                 num = 0;
  441.                 do {
  442.                     num = num * 10 + (*chrptr++ - '0');
  443.                 } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9');
  444.                 wrktim[0] = num;
  445.             }
  446.         }
  447.     } else {
  448.  
  449.         /* Delta time then... */
  450.  
  451.         wrktim[0] = wrktim[1] = 0;
  452.         wrktim[2] = num;
  453.         wrktim[3] = wrktim[4] = wrktim[5] = wrktim[6] = 0;
  454.     }
  455.  
  456.     /* Skip any spaces between date and time... */
  457.  
  458.     while (length > 0 && *chrptr == ' ') {
  459.         length--;
  460.         chrptr++;
  461.     }
  462.  
  463.     /* Now wrap up time fields... */
  464.  
  465.     for (tf = 0; tf < 3; tf++) {
  466.         if (length > 0 && *chrptr >= '0' && *chrptr <= '9') {
  467.             num = 0;
  468.             do {
  469.                 num = num * 10 + (*chrptr++ - '0');
  470.             } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9');
  471.             wrktim[3 + tf] = num;
  472.             if (num > 59) wrktim[1] = 13;
  473.         }
  474.         if (length > 0 && *chrptr == time_sep[tf]) {
  475.             length--;
  476.             chrptr++;
  477.         } else {
  478.             break;
  479.         }
  480.     }
  481.  
  482.     /* Hundredths of seconds need special handling... */
  483.  
  484.     if (length > 0 && *chrptr >= '0' && *chrptr <= '9') {
  485.         tf = 10;
  486.         num = 0;
  487.         do {
  488.             num = num + tf * (*chrptr++ - '0');
  489.             tf = tf / 10;
  490.         } while (--length > 0 && *chrptr >= '0' && *chrptr <= '9');
  491.         wrktim[6] = num;
  492.     }
  493.     /* Now skip any trailing spaces... */
  494.  
  495.     while (length > 0 && *chrptr == ' ') {
  496.         length--;
  497.         chrptr++;
  498.     }
  499.  
  500.     /* If anything left then we have a problem... */
  501.  
  502.     if (length == 0) {
  503.         return lib_cvt_vectim(wrktim,timadr);
  504.     } else {
  505.         return SS$_IVTIME;
  506.     }
  507. }
  508.  
  509.  
  510. /* sys_asctim() converts quadword to ascii... */
  511.  
  512. unsigned sys_asctim(unsigned short *timlen,struct dsc$descriptor *timbuf,
  513.                     struct TIME *timadr,unsigned cvtflg)
  514. {
  515.     register int count,timval;
  516.     unsigned short wrktim[7];
  517.     register int length = timbuf->dsc$w_length;
  518.     register char *chrptr = timbuf->dsc$a_pointer;
  519.  
  520.     /* First use sys_numtim to get the date/time fields... */
  521.  
  522.     {
  523.         register unsigned sts;
  524.         sts = sys_numtim(wrktim,timadr);
  525.         if ((sts & 1) == 0) {
  526.             return sts;
  527.         }
  528.     }
  529.  
  530.     /* See if we want delta days or date... */
  531.  
  532.     if (cvtflg == 0) {
  533.  
  534.         /* Check if date or delta time... */
  535.  
  536.         if (*wrktim) {
  537.  
  538.             /* Put in days and month... */
  539.  
  540.             if (length > 0) {
  541.                 if ((timval = wrktim[2]) / 10 == 0) {
  542.                     *chrptr++ = ' ';
  543.                 } else {
  544.                     *chrptr++ = '0' + timval / 10;
  545.                 }
  546.                 length--;
  547.             }
  548.             if (length > 0) {
  549.                 *chrptr++ = '0' + (timval % 10);
  550.                 length--;
  551.             }
  552.             if ((count = length) > 5) count = 5;
  553.             memcpy(chrptr,month_names + (wrktim[1] * 4 - 4),count);
  554.             length -= count;
  555.             chrptr += count;
  556.             timval = *wrktim;
  557.         } else {
  558.  
  559.             /* Get delta days... */
  560.  
  561.             timval = wrktim[2];
  562.         }
  563.  
  564.         /* Common code for year number and delta days!! */
  565.  
  566.         count = 10000;
  567.         if (timval < count) {
  568.             count = 1000;
  569.             while (length > 0 && timval < count && count > 1) {
  570.                 length--;
  571.                 *chrptr++ = ' ';
  572.                 count /= 10;
  573.             }
  574.         }
  575.         while (length > 0 && count > 0) {
  576.             length--;
  577.             *chrptr++ = '0' + (timval / count);
  578.             timval = timval % count;
  579.             count /= 10;
  580.         }
  581.  
  582.         /* Space between date and time... */
  583.  
  584.         if (length > 0) {
  585.             *chrptr++ = ' ';
  586.             length--;
  587.         }
  588.     }
  589.     /* Do time... :-) */
  590.  
  591.     count = 3;
  592.     do {
  593.         timval = wrktim[count];
  594.         if (length >= 1) *chrptr++ = '0' + (timval / 10);
  595.         if (length >= 2) {
  596.             *chrptr++ = '0' + (timval % 10);
  597.             length -= 2;
  598.         } else {
  599.             length = 0;
  600.         }
  601.         if (count < 6 && length > 0) {
  602.             length--;
  603.             if (count == 5) {
  604.                 *chrptr++ = '.';
  605.             } else {
  606.                 *chrptr++ = ':';
  607.             }
  608.         }
  609.     } while (++count < 7);
  610.  
  611.     /* We've done it - time to return length... */
  612.  
  613.     if (timlen != NULL) *timlen = timbuf->dsc$w_length - length;
  614.     return SS$_NORMAL;
  615. }
  616.  
  617.  
  618. /* lib_day_of_week() computes day of week from quadword... */
  619.  
  620. unsigned lib_day_of_week(struct TIME *timadr,unsigned *weekday)
  621. {
  622.     int days;
  623.     register unsigned sts;
  624.  
  625.     /* Use lib_day to crack quadword... */
  626.  
  627.     sts = lib_day(&days,timadr,NULL);
  628.     if (sts & 1) {
  629.         *weekday = ((days + 2) % 7) + 1;
  630.     }
  631.     return sts;
  632. }
  633.  
  634.  
  635. /* addx & subx COULD use 32 bit arithmetic to do a word at a time. But
  636.    this only works on hardware which has the same endian as the VAX!
  637.    (Intel works fine!! :-) ) So this version works byte by byte which
  638.    should work on VMS dates regardless of system endian - but they
  639.    will NOT perform arithmetic correctly for other data types on
  640.    systems with opposite endian!!! */
  641.  
  642. unsigned lib_addx(void *addant,void *addee,void *result,int *lenadd)
  643. {
  644.     register int count;
  645.     register unsigned carry = 0;
  646.     register unsigned char *ant = (unsigned char *) addant;
  647.     register unsigned char *ee = (unsigned char *) addee;
  648.     register unsigned char *res = (unsigned char *) result;
  649.     if (lenadd == NULL) {
  650.         count = 8;
  651.     } else {
  652.         count = *lenadd * 4;
  653.     }
  654.  
  655.     while (count-- > 0) {
  656.         carry = *ant++ + (carry + *ee++);
  657.         *res++ = carry;
  658.         carry = carry >> 8;
  659.     }
  660.     return SS$_NORMAL;
  661. }
  662.  
  663.  
  664. unsigned lib_subx(void *subant,void *subee,void *result,int *lenadd)
  665. {
  666.     register int count;
  667.     register unsigned carry = 0;
  668.     register unsigned char *ant = (unsigned char *) subant;
  669.     register unsigned char *ee = (unsigned char *) subee;
  670.     register unsigned char *res = (unsigned char *) result;
  671.     if (lenadd == NULL) {
  672.         count = 8;
  673.     } else {
  674.         count = *lenadd * 4;
  675.     }
  676.  
  677.     while (count-- > 0) {
  678.         carry = *ant++ - (carry + *ee++);
  679.         *res++ = carry;
  680.         carry = (carry >> 8) & 1;
  681.  
  682.     }
  683.     return SS$_NORMAL;
  684. }
  685.  
  686.  
  687.  
  688. unsigned lib_add_times(struct TIME *time1,struct TIME *time2,
  689.                        struct TIME *result)
  690. {
  691.     if (time1->time[7] & 0x80) {
  692.         if (time2->time[7] & 0x80) {
  693.             return lib_addx(time1,time2,result,NULL);
  694.         } else {
  695.             return lib_subx(time2,time1,result,NULL);
  696.         }
  697.     } else {
  698.         if (time2->time[7] & 0x80) {
  699.             return lib_subx(time1,time2,result,NULL);
  700.         } else {
  701.             return LIB$_ONEDELTIM;
  702.         }
  703.     }
  704. }
  705.  
  706.  
  707.  
  708. unsigned lib_sub_times(struct TIME *time1,struct TIME *time2,
  709.                        struct TIME *result)
  710. {
  711.     if ((time1->time[7] & 0x80) != (time2->time[7] & 0x80)) {
  712.         return lib_addx(time1,time2,result,NULL);
  713.     } else {
  714.         register int cmp,count = 7;
  715.         do {
  716.             if ((cmp = (time1->time[count] - time2->time[count]))) break;
  717.         } while (--count >= 0);
  718.         if (cmp < 0) {
  719.             return lib_subx(time1,time2,result,NULL);
  720.         } else {
  721.             return lib_subx(time2,time1,result,NULL);
  722.         }
  723.     }
  724. }
  725.  
  726.  
  727.  
  728. unsigned lib_mult_delta_time(int *multiple,struct TIME *timadr)
  729. {
  730.     register unsigned count = 8,carry = 0;
  731.     register int factor = *multiple;
  732.     register unsigned char *ptr = timadr->time;
  733.  
  734.     /* Check for delta time... */
  735.  
  736.     if (timadr->time[7] & 0x80) {
  737.  
  738.         /* Use absolute factor... */
  739.  
  740.         if (factor < 0) factor = -factor;
  741.  
  742.         /* Multiply delta time... */
  743.  
  744.         do {
  745.             carry += *ptr * factor;
  746.             *ptr++ = carry;
  747.             carry = (carry >> 8);
  748.         } while (--count > 0);
  749.  
  750.         return SS$_NORMAL;
  751.     } else {
  752.         return SS$_IVTIME;
  753.     }
  754. }
  755.