⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.c

📁 一个简单的解析器
💻 C
📖 第 1 页 / 共 3 页
字号:
                      else
                          mdays[1] = 28;

                      while (--tt.tm_mon >= 0)
                            {
                            tmp += mdays[tt.tm_mon];

                            if  (tmp > 0)
                                {
                                tt.tm_mday = tmp;
                                goto End;
                                }
                            }

                      tt.tm_mon = 12;
                      tt.tm_year--;
                      }

       case 218:        /* mm 月份 */
       case 226:        /* qq 季度 */
            if  (df == 226)
                tt.tm_mon += 3*n;
            else
                tt.tm_mon += n;

            tmp = floor((double)(tt.tm_mon)/(double)12);
            tt.tm_year += tmp;
            tt.tm_mon  -= 12*tmp;

            if  (tt.tm_mon == 1)
                if  ( IsLeapYear(tt.tm_year) )
                    mdays[1] = 29;

            if  ( tt.tm_mday > mdays[tt.tm_mon] )
                tt.tm_mday = mdays[tt.tm_mon];

            break;

       case 242:        /* yy 年份 */
            tt.tm_year += n;

            if  (tt.tm_mon == 1 && tt.tm_mday == 29)
                if  ( !IsLeapYear(tt.tm_year) )
                    tt.tm_mday--;

            break;

       default:
            return (-1);
       }

End:
/* 日期时间串 */
IntToStr(tt.tm_year, 4, cp);
IntToStr(tt.tm_mon+1,2, cp+5);
IntToStr(tt.tm_mday, 2, cp+8);
IntToStr(tt.tm_hour, 2, cp+11);
IntToStr(tt.tm_min,  2, cp+14);
IntToStr(tt.tm_sec,  2, cp+17);

/* 分隔符 */
*(cp+4) = *(cp+7) = DATE_COMPART;
*(cp+10) = DATE_TIME_COMPART;
*(cp+13) = *(cp+16) = TIME_COMPART;
*(cp+19) = '\0';

return (0);
}

/*************************************************************************
 Function: DateDiff(D1, D2, P)
 Purpose : 按格式串 P 的要求返回 D2 和 D1 的差值,D1 大于 D2 时差值为负。
 Modify  : 堆栈
 Remark  : 出错时返回 -1,否则返回 0
           D1 和 D2 应为标准日期时间串 (YYYY/MM/DD hh:mm:ss,分隔符任意)
           函数未对 D1 和 D2 进行值范围检查,由用户保证其正确性。
 *************************************************************************/
int DateDiff(PACK *pp)
{
char        *cp;
int         df = 0;
struct tm   t1, t2;
int         year, month;
long        day, hour, minute, second;
int         mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
FIELD       *mysp;

/* 调整返回堆栈指针并取得参数位置 */
pp->sp -= 2;
mysp = (pp->sp) - 1;

/* 置结果类型 */
mysp->type = NUMBER;

/* 计算开始日期 */
cp = mysp->str;

t1.tm_year = StrToInt(&cp);
t1.tm_mon  = StrToInt(&cp) - 1;
t1.tm_mday = StrToInt(&cp);
t1.tm_hour = StrToInt(&cp);
t1.tm_min  = StrToInt(&cp);
t1.tm_sec  = StrToInt(&cp);

/* 计算结束日期 */
cp = (mysp+1)->str;

t2.tm_year = StrToInt(&cp);
t2.tm_mon  = StrToInt(&cp) - 1;
t2.tm_mday = StrToInt(&cp);
t2.tm_hour = StrToInt(&cp);
t2.tm_min  = StrToInt(&cp);
t2.tm_sec  = StrToInt(&cp);

/* 格式 */
cp = (mysp+2)->str;
while (*cp != '\0')
      df += (int)*cp++;

/* 计算年、季、月 */
year = t2.tm_year - t1.tm_year;

switch (df)
       {
       case 242:        /* yy 年份 */
            mysp->num = year;
            return (0);

       case 226:        /* qq 季度 */
            mysp->num = 4*year + floor(t2.tm_mon/3) - floor(t1.tm_mon/3);
            return (0);

       case 218:        /* mm 月份 */
            mysp->num = 12*year + t2.tm_mon - t1.tm_mon;
            return (0);
       }

/* 计算结束日期的年日 */
if  ( IsLeapYear(t2.tm_year) )
    mdays[1] = 29;
else
    mdays[1] = 28;

t2.tm_yday = t2.tm_mday;
for (month = 0; month < t2.tm_mon; month++)
    t2.tm_yday += mdays[month];

/* 计算开始日期的年日 */
if  ( IsLeapYear(t1.tm_year) )
    mdays[1] = 29;
else
    mdays[1] = 28;

t1.tm_yday = t1.tm_mday;
for (month = 0; month < t1.tm_mon; month++)
    t1.tm_yday += mdays[month];

/* 计算日数 */
day = t2.tm_yday - t1.tm_yday;

if  (t1.tm_year != t2.tm_year)
    {
    if  (t1.tm_year < t2.tm_year)
        for (year = t1.tm_year; year < t2.tm_year; year++)
            if  ( IsLeapYear(year) )
                day += 366;
            else
                day += 365;
    else
        for (year = t2.tm_year; year < t1.tm_year; year++)
            if  ( IsLeapYear(year) )
                day -= 366;
            else
                day -= 365;
    }

/* 计算时、分、秒数 */
hour   = 24*day + t2.tm_hour - t1.tm_hour;
minute = 60*hour + t2.tm_min - t1.tm_min;
second = 60*minute + t2.tm_sec - t1.tm_sec;

switch (df)
       {
       case 230:        /* ss 秒数 */
            mysp->num = second;
            return (0);

       case 211:        /* mf 带小数的分钟 */
            mysp->num = (double)second/(double)60;
            return (0);

       case 206:        /* hf 带小数的小时 */
            mysp->num = (double)second/(double)3600;
            return (0);

       case 200:        /* dd 月份中的日 */
       case 221:        /* dy 年份中的日 */
            mysp->num = day;
            return (0);

       case 208:        /* hh 小时 */
            mysp->num = hour;
            return (0);

       case 214:        /* mi 分钟 */
            mysp->num = minute;
            return (0);

       default:
            return (-1);
       }
}

/*************************************************************************
 Function: DatePart(D, P)
 Purpose : 按格式串 P 的要求返回 D 相应部份的数值
 Modify  : 堆栈
 Remark  : 出错时返回 -1,否则返回 0
           D 应为标准日期时间串 (YYYY/MM/DD hh:mm:ss,分隔符任意)
           函数未对 D 进行值范围检查,由用户保证其正确性。
 *************************************************************************/
int DatePart(PACK *pp)
{
char        *cp;
int         df = 0;
int         year, month, day, i;
int         mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
FIELD       *mysp;

/* 调整返回堆栈指针并取得参数位置 */
(pp->sp)--;
mysp = (pp->sp) - 1;

/* 格式 */
cp = (mysp+1)->str;
while (*cp != '\0')
      df += (int)*cp++;

/* 日期串 */
cp = mysp->str;

/* 置结果类型 */
mysp->type = NUMBER;

switch (df)
       {
       case 242:        /* yy 年份 */
            break;

       case 226:        /* qq 季度 */
            while (isdigit(*cp++));
            ((pp->sp)++)->num = (StrToInt(&cp) - 1)/3 + 1;
            return (0);

       case 218:        /* mm 月份 */
            while (isdigit(*cp++));
            break;

       case 200:        /* dd 月份中的日 */
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            break;

       case 221:        /* dy 年份中的日 */
       case 219:        /* dw 星期几 */
            year = StrToInt(&cp);
            month = StrToInt(&cp) - 1;
            day = StrToInt(&cp);

            if  ( IsLeapYear(year) )
                mdays[1] = 29;

            for (i=0; i<month; i++)
                day += mdays[i];

            /* 年份中的日 */
            if  (df == 221)
                {
                mysp->num = day;
                return (0);
                }

            /* 星期几 */
            if  (year < 1980)
                return (-1);

            for (i = 1980; i < year; i++)
                if  ( IsLeapYear(i) )
                    day += 366;
                else
                    day += 365;

            mysp->num = (day + 1)%7;
            return (0);

       case 208:        /* hh 小时 */
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            break;

       case 214:        /* mi 分钟 */
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            break;

       case 230:        /* ss 秒数 */
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            while (isdigit(*cp++));
            break;

       default:
            return (-1);
       }

mysp->num = StrToInt(&cp);
return (0);
}

/*************************************************************************
 Function: StrToTime(D)
 Purpose : 将日期串 D 转换为 time_t 格式
 Modify  : 堆栈
 Remark  : 出错时返回 -1,否则返回 0
 *************************************************************************/
int StrToTime(PACK *pp)
{
char        *cp;
struct tm   tt;
FIELD       *mysp;

/* 调整返回堆栈指针并取得参数位置 */
mysp = (pp->sp) - 1;

/* 置结果类型 */
mysp->type = NUMBER;

/* 计算日期 */
cp = mysp->str;

tt.tm_year = StrToInt(&cp);
tt.tm_mon  = StrToInt(&cp) - 1;
tt.tm_mday = StrToInt(&cp);
tt.tm_hour = StrToInt(&cp);
tt.tm_min  = StrToInt(&cp);
tt.tm_sec  = StrToInt(&cp);

/* 计算 time_t */
mysp->num = TmToTime(&tt);

return (0);
}

/*************************************************************************
 Function: TimeToStr(t)
 Purpose : 将 time_t 格式的 t 转换为日期串
 Modify  : 堆栈
 Remark  : 出错时返回 -1,否则返回 0
 *************************************************************************/
int TimeToStr(PACK *pp)
{
time_t      t;
char        *cp;
struct tm   tt;
FIELD       *mysp;

/* 调整返回堆栈指针并取得参数位置 */
mysp = (pp->sp) - 1;

t = (time_t)(mysp->num);

cp = mysp->str;
mysp->type = STRING;

/* 计算 tm 结构 */
TimeToTm(t, &tt);

/* 日期时间串 */
IntToStr(tt.tm_year, 4, cp);
IntToStr(tt.tm_mon+1,2, cp+5);
IntToStr(tt.tm_mday, 2, cp+8);
IntToStr(tt.tm_hour, 2, cp+11);
IntToStr(tt.tm_min,  2, cp+14);
IntToStr(tt.tm_sec,  2, cp+17);

/* 分隔符 */
*(cp+4) = *(cp+7) = DATE_COMPART;
*(cp+10) = DATE_TIME_COMPART;
*(cp+13) = *(cp+16) = TIME_COMPART;
*(cp+19) = '\0';

return (0);
}

/*************************************************************************
 Function: AddrToStr(u)
 Purpose : 将 UINT4 IP 地址转换成园点地址串
 Modify  : 堆栈
 Remark  :
 *************************************************************************/
int AddrToStr(PACK *pp)
{
UINT4   ipaddr;
int	    i;
int     addr_byte[4];
FIELD   *mysp;

/* 调整返回堆栈指针并取得参数位置 */
mysp = (pp->sp) - 1;

ipaddr = (UINT4)(mysp->num);
mysp->type = STRING;

/* 从低到高每次取 8 个二进制位即一个字节 */
for (i = 0; i < 4; i++)
	addr_byte[i] = (ipaddr >> (i*8)) & (UINT4)0x000000FF;

/* 从高到低将四个字节的值打印出来并以园点分隔 */
sprintf(mysp->str, "%u.%u.%u.%u",
            addr_byte[3], addr_byte[2], addr_byte[1], addr_byte[0]);

return (0);
}

/*************************************************************************
 Function: StrToAddr(S)
 Purpose : 将园点地址串转换成 UINT4 IP 地址
 Modify  : 堆栈
 Remark  : 出错时返回 -1,否则返回 0
 *************************************************************************/
int StrToAddr(PACK *pp)
{
char	*cp;
int	    i, cur_byte;
UINT4	ipaddr;
FIELD   *mysp;

/* 调整返回堆栈指针并取得参数位置 */
mysp = (pp->sp) - 1;

cp = mysp->str;

/* 置 IP 地址初值为 0 */
ipaddr = (UINT4)0;

for (i = 0; i < 4; i++)
    {
	cur_byte = StrToInt(&cp);

    /* 数值应在 0 至 255 之间 */
	if  (cur_byte < 0 || cur_byte > 255)
		return(-1);

    /* 原地址值左移 8 位当前字节值置入低 8 位 */
	ipaddr = (ipaddr << 8) | (UINT4)cur_byte;
    }

/* 返回地址值 */
mysp->num = ipaddr;
mysp->type = NUMBER;

return (0);
}

/* End of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -