Ejemplo n.º 1
0
static void strftime_cmd (void)
{
   /* Rather then using some sort of portable version of strftime, which would
    * miss the locale-specific features, just call the system routine.  However,
    * it cannot be called blindly because some versions (e.g., the the one from
    * c.snippets.org) do no input checking, and use code such as
    *
    *   static char *day[] = {"Sunday", "Monday", ..., "Saturday"};
    *   [...]
    *   switch (*f++)
    *     {
    *      case 'A' :
    *        r = day[t->tm_wday];
    *        break;
    *    [...]
    *
    * and lead to a SEGV if t->tm_wday is not in the range [0:6].
    */
   struct tm tms;
   char buf[4096];
   int status;
   char *fmt;

   if (SLang_Num_Function_Args == 1)
     {
	time_t t = time(NULL);
	if (-1 == call_localtime (t, &tms))
	  return;
	if (-1 == validate_tm (&tms))
	  return;
     }
   else if (-1 == pop_tm_struct (&tms))
     return;

   if (-1 == SLang_pop_slstring (&fmt))
     return;

   /* Ugh.  The man page says:
    *
    *  The strftime() function returns the number of characters placed in  the
    *  array  s,  not  including  the  terminating NUL character, provided the
    *  string, including the terminating NUL, fits.  Otherwise, it returns  0,
    *  and  the contents of the array is undefined.  (Thus at least since libc
    *  4.4.4; very old versions of libc, such as libc 4.4.1, would return  max
    *  if the array was too small.)
    *
    *  Note  that  the  return value 0 does not necessarily indicate an error;
    *  for example, in many locales %p yields an empty string.
    *
    * Was this too designed by committee?
    */
   status = strftime (buf, sizeof(buf), fmt, &tms);
   if (status == 0)
     buf[0] = 0;
   buf[sizeof(buf)-1] = 0;
   (void) SLang_push_string (buf);
   SLang_free_slstring (fmt);
}
Ejemplo n.º 2
0
static int pop_tm_struct (struct tm *tms)
{
   /* The memset is necessary because GLIBC has extra fields that may be
    * meaningful.  In fact, without it strftime will generate access errors
    */
   memset ((char *) tms, 0, sizeof (*tms));
   if (-1 == SLang_pop_cstruct (tms, TM_Struct))
     return -1;

   return validate_tm (tms);
}
Ejemplo n.º 3
0
/****************************************************************
 *   RD_Cnv_tm_to_DTString
 *     Copies tm struct values into a date string. Returns 
 *     size_t length copied. Returns 0 if invalid tm struct.
*****************************************************************/
size_t RD_Cnv_tm_to_DTString(struct tm *tmptr,char * dest)
{
    char theyear[5];
    char themonth[3];
    char theday[3];
    char thehr[3];
    char themin[3];
    char thesec[3];
    char plusminus[3];
    char minus[2] = "-";
    char colon_sep[4] = ":";
    char T_sep[2] = "T";
    char offsethr[3];
    char offsetmin[3];
    double offsetfromutc;
    int offhr = 0;
    int offmin = 0;
    int val;
    int leap = 0;
     
    if (!validate_tm(tmptr))
    {
        dest[0]=0;
        return 0;
    }
    offsetfromutc = get_local_offset();
    if (offsetfromutc > 0)
        strlcpy(plusminus,"%2b",3);
    else
        strlcpy(plusminus,"-",1);
    offhr = (int) (offsetfromutc / 3600);
    double hold_min;
    double divby = 3600;
    hold_min = fmod(offsetfromutc,divby);
    offmin = (int) (hold_min / 60);
    sprintf(offsethr,"%02d",abs(offhr));
    sprintf(offsetmin,"%02d",abs(offmin));
    val = tmptr->tm_year + 1900;
    sprintf(theyear,"%d",val);
    val = tmptr->tm_mon + 1;
    sprintf(themonth,"%02d",val);
    sprintf(theday,"%02d",tmptr->tm_mday);
    sprintf(thehr,"%02d",tmptr->tm_hour);
    sprintf(themin,"%02d",tmptr->tm_min);
    sprintf(thesec,"%02d",tmptr->tm_sec);
    strlcpy(dest,theyear,4);
    strcat(dest, minus);
    strcat(dest,themonth);
    strcat(dest, minus);
    strcat(dest,theday);
    strcat(dest,T_sep);
    strcat(dest,thehr);
    strcat(dest,colon_sep);
    strcat(dest,themin);
    strcat(dest,colon_sep);
    strcat(dest,thesec);
    strcat(dest,plusminus);
    strcat(dest,offsethr);
    strcat(dest,colon_sep);
    strcat(dest,offsetmin);
return strlen(dest);
}