home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCSid = "$Id: util.c,v 1.33 1995/12/07 21:41:12 drd Exp $";
- #endif
-
- /* GNUPLOT - util.c */
- /*
- * Copyright (C) 1986 - 1993 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- *
- * AUTHORS
- *
- * Original Software:
- * Thomas Williams, Colin Kelley.
- *
- * Gnuplot 2.0 additions:
- * Russell Lang, Dave Kotz, John Campbell.
- *
- * Gnuplot 3.0 additions:
- * Gershon Elber and many others.
- *
- */
-
- #include <ctype.h>
- #include <math.h> /* get prototype for sqrt */
- #include "plot.h"
- #include "setshow.h" /* for month names etc */
-
-
- TBOOLEAN screen_ok;
- /* TRUE if command just typed; becomes FALSE whenever we
- send some other output to screen. If FALSE, the command line
- will be echoed to the screen before the ^ error message. */
-
-
- static char *num_to_str __P((double r));
- static void parse_esc __P((char *instr));
- static char * read_int __P((char *s, int nr, int *d));
-
- /*
- * chr_in_str() compares the characters in the string of token number t_num
- * with c, and returns TRUE if a match was found.
- */
- #ifdef ANSI_C
- int chr_in_str(int t_num, char c)
- #else
- int chr_in_str(t_num, c)
- int t_num;
- char c;
- #endif
- {
- register int i;
-
- if (!token[t_num].is_token)
- return(FALSE); /* must be a value--can't be equal */
- for (i = 0; i < token[t_num].length; i++) {
- if (input_line[token[t_num].start_index+i] == c)
- return(TRUE);
- }
- return FALSE;
- }
-
-
- /*
- * equals() compares string value of token number t_num with str[], and
- * returns TRUE if they are identical.
- */
- int equals(t_num, str)
- int t_num;
- char *str;
- {
- register int i;
-
- if (!token[t_num].is_token)
- return(FALSE); /* must be a value--can't be equal */
- for (i = 0; i < token[t_num].length; i++) {
- if (input_line[token[t_num].start_index+i] != str[i])
- return(FALSE);
- }
- /* now return TRUE if at end of str[], FALSE if not */
- return(str[i] == '\0');
- }
-
-
-
- /*
- * almost_equals() compares string value of token number t_num with str[], and
- * returns TRUE if they are identical up to the first $ in str[].
- */
- int almost_equals(t_num, str)
- int t_num;
- char *str;
- {
- register int i;
- register int after = 0;
- register start = token[t_num].start_index;
- register length = token[t_num].length;
-
- if (!token[t_num].is_token)
- return(FALSE); /* must be a value--can't be equal */
- for (i = 0; i < length + after; i++) {
- if (str[i] != input_line[start + i]) {
- if (str[i] != '$')
- return(FALSE);
- else {
- after = 1;
- start--; /* back up token ptr */
- }
- }
- }
-
- /* i now beyond end of token string */
-
- return(after || str[i] == '$' || str[i] == '\0');
- }
-
-
-
- int isstring(t_num)
- int t_num;
- {
-
- return(token[t_num].is_token &&
- (input_line[token[t_num].start_index] == '\'' ||
- input_line[token[t_num].start_index] == '\"'));
- }
-
-
- int isanumber(t_num)
- int t_num;
- {
- return(!token[t_num].is_token);
- }
-
-
- int isletter(t_num)
- int t_num;
- {
- return(token[t_num].is_token &&
- ((isalpha(input_line[token[t_num].start_index]))||
- (input_line[token[t_num].start_index] == '_')));
- }
-
-
- /*
- * is_definition() returns TRUE if the next tokens are of the form
- * identifier =
- * -or-
- * identifier ( identifer {,identifier} ) =
- */
- int is_definition(t_num)
- int t_num;
- {
- /* variable? */
- if(isletter(t_num) && equals(t_num+1,"="))
- return 1;
-
- /* function? */
- /* look for dummy variables */
- if(isletter(t_num) && equals(t_num+1,"(") && isletter(t_num+2)) {
- t_num += 3; /* point past first dummy */
- while(equals(t_num,",")) {
- if(!isletter(++t_num))
- return 0;
- t_num += 1;
- }
- return(equals(t_num,")") && equals(t_num+1,"="));
- }
-
- /* neither */
- return 0;
- }
-
-
-
- /*
- * copy_str() copies the string in token number t_num into str, appending
- * a null. No more than max chars are copied (including \0).
- */
- void copy_str(str, t_num, max)
- char str[];
- int t_num;
- int max;
- {
- register int i = 0;
- register int start = token[t_num].start_index;
- register int count;
-
- if ((count = token[t_num].length) >= max) {
- count = max-1;
- #ifdef DEBUG_STR
- fprintf(stderr, "str buffer overflow in copy_str");
- #endif
- }
- do {
- str[i++] = input_line[start++];
- } while (i != count);
- str[i] = '\0';
- }
-
- /* length of token string */
- int token_len(t_num)
- int t_num;
- {
- return (token[t_num].length);
- }
-
- /*
- * quote_str() does the same thing as copy_str, except it ignores the
- * quotes at both ends. This seems redundant, but is done for
- * efficency.
- */
- void quote_str(str, t_num, max)
- char str[];
- int t_num;
- int max;
- {
- register int i = 0;
- register int start = token[t_num].start_index + 1;
- register int count;
-
- if ((count = token[t_num].length - 2) >= max) {
- count = max-1;
- #ifdef DEBUG_STR
- fprintf(stderr, "str buffer overflow in quote_str");
- #endif
- }
- if (count>0) {
- do {
- str[i++] = input_line[start++];
- } while (i != count);
- }
- str[i] = '\0';
- /* convert \t and \nnn (octal) to char if in double quotes */
- if ( input_line[token[t_num].start_index] == '"' )
- parse_esc(str);
- }
-
-
- /*
- * capture() copies into str[] the part of input_line[] which lies between
- * the begining of token[start] and end of token[end].
- */
- void capture(str,start,end,max)
- char str[];
- int start,end;
- int max;
- {
- register int i,e;
-
- e = token[end].start_index + token[end].length;
- if(e-token[start].start_index>=max) {
- e=token[start].start_index+max-1;
- #ifdef DEBUG_STR
- fprintf(stderr, "str buffer overflow in capture");
- #endif
- }
-
- for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
- *str++ = input_line[i];
- *str = '\0';
- }
-
-
- /*
- * m_capture() is similar to capture(), but it mallocs storage for the
- * string.
- */
- void m_capture(str,start,end)
- char **str;
- int start,end;
- {
- register int i,e;
- register char *s;
-
- if (*str) /* previous pointer to malloc'd memory there */
- free(*str);
- e = token[end].start_index + token[end].length;
- *str = alloc((unsigned long)(e - token[start].start_index + 1), "string");
- s = *str;
- for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
- *s++ = input_line[i];
- *s = '\0';
- }
-
-
- /*
- * m_quote_capture() is similar to m_capture(), but it removes
- quotes from either end if the string.
- */
- void m_quote_capture(str,start,end)
- char **str;
- int start,end;
- {
- register int i,e;
- register char *s;
-
- if (*str) /* previous pointer to malloc'd memory there */
- free(*str);
- e = token[end].start_index + token[end].length-1;
- *str = alloc((unsigned long)(e - token[start].start_index + 1), "string");
- s = *str;
- for (i = token[start].start_index + 1; i < e && input_line[i] != '\0'; i++)
- *s++ = input_line[i];
- *s = '\0';
- }
-
-
- void convert(val_ptr, t_num)
- struct value *val_ptr;
- int t_num;
- {
- *val_ptr = token[t_num].l_val;
- }
-
- static char *num_to_str(r)
- double r;
- {
- static i = 0;
- static char s[4][25];
- int j = i++;
-
- if ( i > 3 ) i = 0;
-
- sprintf( s[j], "%.15g", r );
- if ( strchr( s[j], '.' ) == NULL &&
- strchr( s[j], 'e' ) == NULL &&
- strchr( s[j], 'E' ) == NULL )
- strcat( s[j], ".0" );
-
- return s[j];
- }
-
- void disp_value(fp,val)
- FILE *fp;
- struct value *val;
- {
- switch(val->type) {
- case INTGR:
- fprintf(fp,"%d",val->v.int_val);
- break;
- case CMPLX:
- if (val->v.cmplx_val.imag != 0.0 )
- fprintf(fp,"{%s, %s}",
- num_to_str(val->v.cmplx_val.real),
- num_to_str(val->v.cmplx_val.imag));
- else
- fprintf(fp,"%s",
- num_to_str(val->v.cmplx_val.real));
- break;
- default:
- int_error("unknown type in disp_value()",NO_CARET);
- }
- }
-
-
- double
- real(val) /* returns the real part of val */
- struct value *val;
- {
- switch(val->type) {
- case INTGR:
- return((double) val->v.int_val);
- case CMPLX:
- return(val->v.cmplx_val.real);
- }
- int_error("unknown type in real()",NO_CARET);
- /* NOTREACHED */
- return((double)0.0);
- }
-
-
- double
- imag(val) /* returns the imag part of val */
- struct value *val;
- {
- switch(val->type) {
- case INTGR:
- return(0.0);
- case CMPLX:
- return(val->v.cmplx_val.imag);
- }
- int_error("unknown type in imag()",NO_CARET);
- /* NOTREACHED */
- return((double)0.0);
- }
-
-
-
- double
- magnitude(val) /* returns the magnitude of val */
- struct value *val;
- {
- switch(val->type) {
- case INTGR:
- return((double) abs(val->v.int_val));
- case CMPLX:
- return(sqrt(val->v.cmplx_val.real*
- val->v.cmplx_val.real +
- val->v.cmplx_val.imag*
- val->v.cmplx_val.imag));
- }
- int_error("unknown type in magnitude()",NO_CARET);
- /* NOTREACHED */
- return((double)0.0);
- }
-
-
-
- double
- angle(val) /* returns the angle of val */
- struct value *val;
- {
- switch(val->type) {
- case INTGR:
- return((val->v.int_val >= 0) ? 0.0 : Pi);
- case CMPLX:
- if (val->v.cmplx_val.imag == 0.0) {
- if (val->v.cmplx_val.real >= 0.0)
- return(0.0);
- else
- return(Pi);
- }
- return(atan2(val->v.cmplx_val.imag,
- val->v.cmplx_val.real));
- }
- int_error("unknown type in angle()",NO_CARET);
- /* NOTREACHED */
- return((double)0.0);
- }
-
-
- struct value *
- Gcomplex(a,realpart,imagpart)
- struct value *a;
- double realpart, imagpart;
- {
- a->type = CMPLX;
- a->v.cmplx_val.real = realpart;
- a->v.cmplx_val.imag = imagpart;
- return(a);
- }
-
-
- struct value *
- Ginteger(a,i)
- struct value *a;
- int i;
- {
- a->type = INTGR;
- a->v.int_val = i;
- return(a);
- }
-
-
- #if !defined(vms) && !defined(HAVE_STRERROR)
- /* substitute for systems that don't have ANSI function strerror */
-
- extern int sys_nerr;
- extern char *sys_errlist[];
-
- char *strerror(no)
- int no;
- {
- static char res_str[30];
-
- if(no>sys_nerr) {
- sprintf(res_str, "unknown errno %d", no);
- return res_str;
- } else {
- return sys_errlist[no];
- }
- }
- #endif
-
-
- void os_error(str,t_num)
- char str[];
- int t_num;
- {
- #ifdef vms
- static status[2] = {1, 0}; /* 1 is count of error msgs */
- #endif
-
- register int i;
-
- /* reprint line if screen has been written to */
-
- if (t_num != NO_CARET) { /* put caret under error */
- if (!screen_ok)
- fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- for (i = 0; i < token[t_num].start_index; i++) {
- (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
- }
- (void) putc('^',stderr);
- (void) putc('\n',stderr);
- }
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- fprintf(stderr,"%s\n",str);
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- if (!interactive)
- if (infile_name != NULL)
- fprintf(stderr,"\"%s\", line %d: ", infile_name, inline_num);
- else
- fprintf(stderr,"line %d: ", inline_num);
-
-
- #ifdef vms
- status[1] = vaxc$errno;
- sys$putmsg(status);
- (void) putc('\n',stderr);
- #else /* vms */
- fprintf(stderr,"(%s)\n\n", strerror(errno));
- #endif /* vms */
-
- longjmp(env, TRUE); /* bail out to command line */
- }
-
-
- void int_error(str,t_num)
- char str[];
- int t_num;
- {
- register int i;
-
- /* reprint line if screen has been written to */
-
- if (t_num != NO_CARET) { /* put caret under error */
- if (!screen_ok)
- fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- for (i = 0; i < token[t_num].start_index; i++) {
- (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
- }
- (void) putc('^',stderr);
- (void) putc('\n',stderr);
- }
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- if (!interactive)
- if (infile_name != NULL)
- fprintf(stderr,"\"%s\", line %d: ", infile_name, inline_num);
- else
- fprintf(stderr,"line %d: ", inline_num);
- fprintf(stderr,"%s\n\n", str);
-
- longjmp(env, TRUE); /* bail out to command line */
- }
-
- void int_warn(str,t_num)
- char str[];
- int t_num;
- {
- register int i;
-
- /* Warn without bailing out to command line. Not a user error */
-
- /* reprint line if screen has been written to */
-
- if (t_num != NO_CARET) { /* put caret under error */
- if (!screen_ok)
- fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- for (i = 0; i < token[t_num].start_index; i++) {
- (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
- }
- (void) putc('^',stderr);
- (void) putc('\n',stderr);
- }
-
- for (i = 0; i < sizeof(PROMPT) - 1; i++)
- (void) putc(' ',stderr);
- if (!interactive)
- if (infile_name != NULL)
- fprintf(stderr,"\"%s\", line %d: ", infile_name, inline_num);
- else
- fprintf(stderr,"line %d: ", inline_num);
- fprintf(stderr,"warning: %s\n", str);
-
- } /* int_warn */
-
- /* Lower-case the given string (DFK) */
- /* Done in place. */
- void
- lower_case(s)
- char *s;
- {
- register char *p = s;
-
- while (*p != '\0') {
- if (isupper(*p))
- *p = tolower(*p);
- p++;
- }
- }
-
- /* Squash spaces in the given string (DFK) */
- /* That is, reduce all multiple white-space chars to single spaces */
- /* Done in place. */
- void
- squash_spaces(s)
- char *s;
- {
- register char *r = s; /* reading point */
- register char *w = s; /* writing point */
- TBOOLEAN space = FALSE; /* TRUE if we've already copied a space */
-
- for (w = r = s; *r != '\0'; r++) {
- if (isspace(*r)) {
- /* white space; only copy if we haven't just copied a space */
- if (!space) {
- space = TRUE;
- *w++ = ' ';
- } /* else ignore multiple spaces */
- } else {
- /* non-space character; copy it and clear flag */
- *w++ = *r;
- space = FALSE;
- }
- }
- *w = '\0'; /* null terminate string */
- }
-
- static int mndday[12] = { 31,28,31,30,31,30,31,31,30,31,30,31};
-
- /* days in year */
- int
- gdysize(yr)
- int yr;
- {
-
- if (!(yr%4)) {
- if ((!(yr%100)) && yr%400)
- return(365);
- return(366);
- }
- return(365);
- }
-
-
- /* new strptime() and gmtime() to allow time to be read as 24 hour,
- * and spaces in the format string. time is converted to seconds from
- * year 2000.... */
-
- char *
- gstrptime(s,fmt,tm)
- char *s;
- char *fmt;
- struct tm *tm;
- {
- int yday, date;
-
- date = yday = 0;
- tm->tm_mday = 0;
- tm->tm_mon = tm->tm_year = tm->tm_yday = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
-
- while ( *fmt != '\0' ) {
- while(*s == *fmt) {s++; fmt++;}
- if ( *fmt != '%' )
- break;
- fmt++;
- if ( *fmt == 'd' ) { /* read a day of month */
- s = read_int(s,2,&tm->tm_mday);
- date++;
- } else if ( *fmt == 'm' ) {
- s = read_int(s,2,&tm->tm_mon);
- date++;
- tm->tm_mon--;
- } else if ( *fmt == 'y' ) {
- s = read_int(s,2,&tm->tm_year);
- date++;
- tm->tm_year += 1900;
- } else if ( *fmt == 'Y' ) {
- s = read_int(s,4,&tm->tm_year);
- date++;
- /* tm->tm_year -= 1900; */
- /* HOE tm->tm_year %= 100; */
- } else if ( *fmt == 'j' ) {
- s = read_int(s,3,&tm->tm_yday);
- tm->tm_yday--;
- date++;
- yday++;
- } else if ( *fmt == 'H' ) {
- s = read_int(s,2,&tm->tm_hour);
- } else if ( *fmt == 'M' ) {
- s = read_int(s,2,&tm->tm_min);
- } else if ( *fmt == 'S' ) {
- s = read_int(s,2,&tm->tm_sec);
- }
- fmt++;
- }
- /* if (!yday && date) { */
- if (date) {
- /*
- tm->tm_yday = 0;
- for(i=0;i<tm->tm_mon;i++) {
- tm->tm_yday += mndday[i] + (i==1 && (gdysize(tm->tm_year)>365));
- }
- tm->tm_yday += tm->tm_mday-1;
- */
- if (yday) {
- if ( tm->tm_yday < 0 || tm->tm_yday > gdysize(tm->tm_year)) {
- int_error("illegal day of year",NO_CARET);
- return(NULL);
- }
- } else {
- if ( tm->tm_mon < 0 || tm->tm_mon > 11 ) {
- int_error("illegal month",NO_CARET);
- return(NULL);
- }
- if ( tm->tm_mday < 1 || tm->tm_mday > mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year)>365)) ) {
- int_error("illegal day of month",NO_CARET);
- return(NULL);
- }
- }
- }
- if ( tm->tm_hour < 0 || tm->tm_hour > 24 ) {
- int_error("illegal hour",NO_CARET);
- return(NULL);
- }
- if ( tm->tm_min < 0 || tm->tm_min > 60 ) {
- int_error("illegal minute",NO_CARET);
- return(NULL);
- }
- if ( tm->tm_sec < 0 || tm->tm_sec > 60 ) {
- int_error("illegal second",NO_CARET);
- return(NULL);
- }
- return(s);
- }
-
- static char *
- read_int(s,nr,d)
- char *s;
- int nr, *d;
- {
- char num[8];
- int i;
-
- i = 0;
- while(i<nr) {
- if( *s >= '0' && *s <= '9' ) {
- num[i++] = *s++;
- } else {
- break;
- }
- }
- num[i] = '\0';
- sscanf(num,"%d",d);
- return(s);
- }
-
-
- int
- gstrftime(s,bsz,fmt,clock)
- char *s;
- int bsz;
- char *fmt;
- double clock;
- {
- int xstrftime();
- int days;
- time_t cl;
- struct tm tm;
- struct tm *xtm;
-
- ggmtime(&tm,clock);
- /* weekday, 0 = sunday */
- cl = 0;
- xtm = gmtime(&cl);
- /* antall dager */
- days = (int) (clock+SEC_OFFS_SYS)/DAY_SEC;
- /* weekrest */
- days %= 7;
- if ( days < 0 ) days += 7;
- tm.tm_wday = (xtm->tm_wday+days)%7;
- #if 0
- if ((tm.tm_zone = (char *) malloc(strlen(xtm->tm_zone)+1)))
- strcpy(tm.tm_zone,xtm->tm_zone);
- /* printf("zone: %s - %s\n",tm.tm_zone,xtm->tm_zone); */
- #endif
-
- return(xstrftime(s,bsz,fmt,&tm));
- }
-
- int
- xstrftime(str,bsz,fmt,tm)
- char *str;
- int bsz;
- char *fmt;
- struct tm *tm;
- {
- int l;
- char *p, *s;
-
- p = fmt;
- s = str;
- memset(s,'\0',bsz+1);
- l=0;
- while (*p != '\0') {
- if (*p != '%') {
- if ( l >= bsz ) return(0);
- *s++ = *p++;
- l++;
- } else {
- p++;
- if ( *p == '%' ) {
- if ( l >= bsz ) return(0);
- *s = '%';
- } else if ( *p == 'a' ) {
- if ((l+strlen(abbrev_day_names[tm->tm_wday])) > bsz ) return(0);
- sprintf(s,"%s",abbrev_day_names[tm->tm_wday]);
- } else if ( *p == 'A' ) {
- if(l+strlen(full_day_names[tm->tm_wday]) > bsz) return(0);
- sprintf(s,"%s",full_day_names[tm->tm_wday]);
- } else if ( *p == 'b' || *p == 'h' ) {
- if(l+strlen(abbrev_month_names[tm->tm_mon])> bsz) return(0);
- sprintf(s,"%s",abbrev_month_names[tm->tm_mon]);
- } else if ( *p == 'B' ) {
- if(l+strlen(full_month_names[tm->tm_mon]) > bsz) return(0);
- sprintf(s,"%s",full_month_names[tm->tm_mon]);
- } else if ( *p == 'c' ) {
- if (!xstrftime(s,bsz-l,"%x %X",tm)) {
- return(0);
- }
- #if 0
- } else if ( *p == 'C' ) {
- if (!xstrftime(s,bsz-l,dtc->ldate_format,tm)) {
- return(0);
- }
- #endif
- } else if ( *p == 'd' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_mday);
- } else if ( *p == 'D' ) {
- if (!xstrftime(s,bsz-l,"%m/%d/%y",tm)) {
- return(0);
- }
- } else if ( *p == 'e' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%2d",tm->tm_mday);
- } else if ( *p == 'H' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_hour);
- } else if ( *p == 'I' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_hour%12);
- } else if ( *p == 'j' ) {
- if ( bsz - l < 3 ) return(0);
- sprintf(s,"%03d",tm->tm_yday+1);
- } else if ( *p == 'k' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%2d",tm->tm_hour);
- } else if ( *p == 'l' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%2d",tm->tm_hour%12);
- } else if ( *p == 'm' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_mon+1);
- } else if ( *p == 'M' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_min);
- } else if ( *p == 'n' ) {
- if ( bsz >= l ) return(0);
- *s = '\n';
- } else if ( *p == 'p' ) {
- if(l+strlen((tm->tm_hour<12)?"am":"pm") > bsz) return(0);
- sprintf(s,"%s",(tm->tm_hour<12)?"am":"pm");
- } else if ( *p == 'r' ) {
- if (!xstrftime(s,bsz-l,"%I:%M:%S %p",tm)) {
- return(0);
- }
- } else if ( *p == 'R' ) {
- if (!xstrftime(s,bsz-l,"%H:%M",tm)) {
- return(0);
- }
- } else if ( *p == 'S' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_sec);
- } else if ( *p == 't' ) {
- if ( bsz >= l ) return(0);
- *s = '\t';
- } else if ( *p == 'T' ) {
- if (!xstrftime(s,bsz-l,"%H:%M:%S",tm)) {
- return(0);
- }
- } else if ( *p == 'W' ) { /* mon 1 day of week */
- int week, bw;
-
- if ( bsz - l < 2 ) return(0);
- if ( tm->tm_yday <= tm->tm_wday ) {
- week = 1;
- if ( (tm->tm_mday - tm->tm_yday) > 4 ) {
- week = 52;
- }
- if ( tm->tm_yday == tm->tm_wday && tm->tm_wday == 0 ) week = 52;
- } else {
- bw = tm->tm_yday - tm->tm_wday; /* sun prev week */
- if ( tm->tm_wday > 0 ) bw += 7; /* sun end of week */
- week = (int) bw/7;
- if ( (bw%7) > 2 ) { /* jan 1 is before friday */
- week++;
- }
- }
- sprintf(s,"%02d",week);
- } else if ( *p == 'U' ) { /* sun 1 day of week */
- int week, bw;
-
- if ( bsz - l < 2 ) return(0);
- if ( tm->tm_yday <= tm->tm_wday ) {
- week = 1;
- if ( (tm->tm_mday - tm->tm_yday) > 4 ) {
- week = 52;
- }
- } else {
- bw = tm->tm_yday - tm->tm_wday-1; /* sat prev week */
- if ( tm->tm_wday >= 0 ) bw += 7; /* sat end of week */
- week = (int) bw/7;
- if ( (bw%7) > 1 ) { /* jan 1 is before friday */
- week++;
- }
- }
- sprintf(s,"%02d",week);
- } else if ( *p == 'w' ) { /* day of week, sun=0 */
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_wday);
- #if 0
- } else if ( *p == 'x' ) { /* locales date format */
- if (!xstrftime(s,bsz-l,dtc->sdate_format,tm)) {
- return(0);
- }
- } else if ( *p == 'X' ) { /* locales time format */
- if (!xstrftime(s,bsz-l,dtc->time_format,tm)) {
- return(0);
- }
- #endif
- } else if ( *p == 'y' ) {
- if ( bsz - l < 2 ) return(0);
- sprintf(s,"%02d",tm->tm_year%100);
- } else if ( *p == 'Y' ) {
- if ( bsz - l < 4 ) return(0);
- sprintf(s,"%04d",tm->tm_year);
- #if 0
- } else if ( *p == 'Z' ) {
- if ( bsz - l < strlen(tm->tm_zone) ) return(0);
- sprintf(s,"%s",tm->tm_zone);
- #endif
- }
- p++;
- while ( *s != '\0' ) {
- s++;
- l++;
- }
- }
- }
- return(l);
- }
-
- /* time_t */
- double
- gtimegm(tm)
- struct tm *tm;
- {
- register int i;
- /* returns sec from year ZERO_YEAR, defined in plot.h */
- double dsec;
-
- dsec = 0;
- if ( tm->tm_year < ZERO_YEAR ) {
- for(i=tm->tm_year;i<ZERO_YEAR;i++) {
- dsec -= (double) gdysize(i);
- }
- } else {
- for(i=ZERO_YEAR;i<tm->tm_year;i++) {
- dsec += (double) gdysize(i);
- }
- }
- if ( tm->tm_mday > 0 ) {
- for (i=0;i<tm->tm_mon;i++) {
- dsec += (double) mndday[i] + (i==1 && (gdysize(tm->tm_year)>365));
- }
- dsec += (double) tm->tm_mday-1;
- } else {
- dsec += (double) tm->tm_yday;
- }
- dsec *= (double) 24;
-
- dsec += tm->tm_hour;
- dsec *= 60.0;
- dsec += tm->tm_min;
- dsec *= 60.0;
- dsec += tm->tm_sec;
-
- return(dsec);
- }
-
- int
- ggmtime(tm,clock)
- struct tm *tm;
- /* time_t clock; */
- double clock;
- {
- /* clock is relative to ZERO_YEAR, jan 1, 00:00:00,defined in plot.h */
- int i, days;
-
- tm->tm_year = ZERO_YEAR;
- tm->tm_mday = tm->tm_yday = tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
- if ( clock < 0 ) {
- while ( clock < 0 ) {
- tm->tm_year --;
- clock += gdysize(tm->tm_year)*DAY_SEC; /* 24*3600 */
- }
- } else {
- while ( clock >= (gdysize(tm->tm_year)*DAY_SEC) ) {
- clock -= gdysize(tm->tm_year)*DAY_SEC;
- tm->tm_year ++;
- }
- }
- tm->tm_yday = (int)clock/DAY_SEC;
- clock -= tm->tm_yday*DAY_SEC;
- tm->tm_hour = (int)clock/3600;
- clock -= tm->tm_hour*3600;
- tm->tm_min = (int)clock/60;
- clock -= tm->tm_min*60;
- tm->tm_sec = (int)clock;
- days = tm->tm_yday;
- while ( days >= (i = mndday[tm->tm_mon] + (tm->tm_mon==1 && (gdysize(tm->tm_year)>365)))) {
- days -= i;
- tm->tm_mon ++;
- }
- tm->tm_mday = days+1;
-
- return(0);
- }
-
- static void
- parse_esc(instr)
- char *instr;
- {
- char *s=instr, *t=instr;
-
- /* the string will always get shorter, so we can do the
- * conversion in situ
- */
-
- while (*s != '\0' ) {
- if ( *s == '\\' ) {
- s++;
- if ( *s == '\\' ) {
- *t++ = '\\';
- s++;
- } else if ( *s == 'n' ) {
- *t++ = '\n';
- s++;
- } else if ( *s == 'r' ) {
- *t++ = '\r';
- s++;
- } else if ( *s == 't' ) {
- *t++ = '\t';
- s++;
- } else if ( *s >= '0' && *s <= '7' ) {
- int i,n;
- if ( sscanf(s,"%o%n",&i, &n) > 0 ) {
- *t++ = i;
- s+=n;
- } else {
- /* int_error("illegal octal number ", c_token); */
- *t++ = '\\';
- *t++ = *s++;
- }
- }
- } else {
- *t++ = *s++;
- }
- }
- *t = '\0';
- }
-