size_t gstrftime(char *s, size_t bsz, const char *fmt, double l_clock) { struct tm tm; double usec; ggmtime(&tm, l_clock); usec = l_clock - (double)floor(l_clock); return xstrftime(s, bsz, fmt, &tm, usec, l_clock); }
size_t gstrftime(char *s, size_t bsz, const char *fmt, double l_clock) { struct tm tm; ggmtime(&tm, l_clock); #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); }
char * gstrptime(char *s, char *fmt, struct tm *tm, double *usec) { int yday = 0; TBOOLEAN sanity_check_date = FALSE; tm->tm_mday = 1; tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0; /* make relative times work (user-defined tic step) */ tm->tm_year = ZERO_YEAR; /* Fractional seconds will be returned separately, since * there is no slot for the fraction in struct tm. */ *usec = 0.0; /* we do not yet calculate wday or yday, so make them illegal * [but yday will be read by %j] */ tm->tm_yday = tm->tm_wday = -1; /* If the format requests explicit day, month, or year, then we will * do sanity checking to make sure the input makes sense. * For backward compatibility with gnuplot versions through 4.6.6 * hour, minute, seconds default to zero with no error return * if the corresponding field cannot be found or interpreted. */ if (strstr(fmt,"%d")) { tm->tm_mday = -1; sanity_check_date = TRUE; } if (strstr(fmt,"%y") || strstr(fmt,"%Y")) { tm->tm_year = -1; sanity_check_date = TRUE; } if (strstr(fmt,"%m") || strstr(fmt,"%B") || strstr(fmt,"%b")) { tm->tm_mon = -1; sanity_check_date = TRUE; } while (*fmt) { if (*fmt != '%') { if (*fmt == ' ') { /* space in format means zero or more spaces in input */ while (*s == ' ') ++s; ++fmt; continue; } else if (*fmt == *s) { ++s; ++fmt; continue; } else break; /* literal match has failed */ } /* we are processing a percent escape */ switch (*++fmt) { case 'b': /* abbreviated month name */ { int m; for (m = 0; m < 12; ++m) if (strncasecmp(s, abbrev_month_names[m], strlen(abbrev_month_names[m])) == 0) { s += strlen(abbrev_month_names[m]); goto found_abbrev_mon; } /* get here => not found */ int_warn(DATAFILE, "Bad abbreviated month name"); m = 0; found_abbrev_mon: tm->tm_mon = m; break; } case 'B': /* full month name */ { int m; for (m = 0; m < 12; ++m) if (strncasecmp(s, full_month_names[m], strlen(full_month_names[m])) == 0) { s += strlen(full_month_names[m]); goto found_full_mon; } /* get here => not found */ int_warn(DATAFILE, "Bad full month name"); m = 0; found_full_mon: tm->tm_mon = m; break; } case 'd': /* read a day of month */ s = read_int(s, 2, &tm->tm_mday); break; case 'm': /* month number */ s = read_int(s, 2, &tm->tm_mon); --tm->tm_mon; break; case 'y': /* year number */ s = read_int(s, 2, &tm->tm_year); /* In line with the current UNIX98 specification by * The Open Group and major Unix vendors, * two-digit years 69-99 refer to the 20th century, and * values in the range 00-68 refer to the 21st century. */ if (tm->tm_year <= 68) tm->tm_year += 100; tm->tm_year += 1900; break; case 'Y': s = read_int(s, 4, &tm->tm_year); break; case 'j': s = read_int(s, 3, &tm->tm_yday); tm->tm_yday--; sanity_check_date = TRUE; yday++; break; case 'H': s = read_int(s, 2, &tm->tm_hour); break; case 'M': s = read_int(s, 2, &tm->tm_min); break; case 'S': s = read_int(s, 2, &tm->tm_sec); if (*s == '.' || (decimalsign && *s == *decimalsign)) *usec = atof(s); break; case 's': /* read EPOCH data * EPOCH is the std. unix timeformat seconds since 01.01.1970 UTC */ { char *fraction = strchr(s, decimalsign ? *decimalsign : '.'); double ufraction = 0; double when = strtod (s, &s) - SEC_OFFS_SYS; ggmtime(tm, when); if (fraction && fraction < s) ufraction = atof(fraction); if (ufraction < 1.) /* Filter out e.g. 123.456e7 */ *usec = ufraction; break; } default: int_warn(DATAFILE, "Bad time format in string"); } fmt++; } FPRINTF((stderr, "read date-time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec)); /* now sanity check the date/time entered, normalising if necessary * read_int cannot read a -ve number, but can read %m=0 then decrement * it to -1 */ #define S (tm->tm_sec) #define M (tm->tm_min) #define H (tm->tm_hour) if (S >= 60) { M += S / 60; S %= 60; } if (M >= 60) { H += M / 60; M %= 60; } if (H >= 24) { if (yday) tm->tm_yday += H / 24; tm->tm_mday += H / 24; H %= 24; } #undef S #undef M #undef H FPRINTF((stderr, "normalised time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec)); if (sanity_check_date) { if (yday) { if (tm->tm_yday < 0) { // int_error(DATAFILE, "Illegal day of year"); return (NULL); } /* we just set month to jan, day to yday, and let the * normalising code do the work. */ tm->tm_mon = 0; /* yday is 0->365, day is 1->31 */ tm->tm_mday = tm->tm_yday + 1; } if (tm->tm_mon < 0) { // int_error(DATAFILE, "illegal month"); return (NULL); } if (tm->tm_mday < 1) { // int_error(DATAFILE, "illegal day of month"); return (NULL); } if (tm->tm_mon > 11) { tm->tm_year += tm->tm_mon / 12; tm->tm_mon %= 12; } { int days_in_month; while (tm->tm_mday > (days_in_month = (mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365))))) { if (++tm->tm_mon == 12) { ++tm->tm_year; tm->tm_mon = 0; } tm->tm_mday -= days_in_month; } } } return (s); }
static int command() { FILE *fp; int i; /* string holding name of save or load file */ char sv_file[MAX_LINE_LEN + 1]; for (i = 0; i < MAX_NUM_VAR; i++) c_dummy_var[i][0] = NUL; /* no dummy variables */ if (is_definition(c_token)) define(); else if (almost_equals(c_token, "h$elp") || equals(c_token, "?")) { c_token++; do_help(1); } else if (equals(c_token, "testtime")) { /* given a format and a time string, exercise the time code */ char format[160], string[160]; struct tm tm; double secs; if (isstring(++c_token)) { quote_str(format, c_token, 159); if (isstring(++c_token)) { quote_str(string, c_token++, 159); memset(&tm, 0, sizeof(tm)); gstrptime(string, format, &tm); secs = gtimegm(&tm); fprintf(stderr, "internal = %f - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n", secs, tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday); memset(&tm, 0, sizeof(tm)); ggmtime(&tm, secs); gstrftime(string, 159, format, secs); fprintf(stderr, "convert back \"%s\" - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n", string, tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday); } } } else if (almost_equals(c_token, "test")) { c_token++; test_term(); } else if (almost_equals(c_token, "scr$eendump")) { c_token++; #ifdef _Windows screen_dump(); #else fputs("screendump not implemented\n", stderr); #endif } else if (almost_equals(c_token, "pa$use")) { struct value a; int sleep_time, text = 0; char buf[MAX_LINE_LEN + 1]; c_token++; sleep_time = (int) real(const_express(&a)); buf[0] = NUL; if (!(END_OF_COMMAND)) { if (!isstring(c_token)) int_error("expecting string", c_token); else { quote_str(buf, c_token, MAX_LINE_LEN); ++c_token; #ifdef _Windows if (sleep_time >= 0) #else # ifdef OS2 if (strcmp(term->name, "pm") != 0 || sleep_time >= 0) # else # ifdef MTOS if (strcmp(term->name, "mtos") != 0 || sleep_time >= 0) # endif /* MTOS */ # endif /* OS2 */ #endif /* _Windows */ fputs(buf, stderr); text = 1; } } if (sleep_time < 0) { #ifdef _Windows if (!Pause(buf)) bail_to_command_line(); #else # ifdef OS2 if (strcmp(term->name, "pm") == 0 && sleep_time < 0) { int rc; if ((rc = PM_pause(buf)) == 0) bail_to_command_line(); else if (rc == 2) { fputs(buf, stderr); text = 1; (void) fgets(buf, MAX_LINE_LEN, stdin); } } # else /* !OS2 */ # ifdef _Macintosh if (strcmp(term->name, "macintosh") == 0 && sleep_time < 0) Pause(sleep_time); # else /* !_Macintosh */ # ifdef MTOS if (strcmp(term->name, "mtos") == 0) { int MTOS_pause(char *buf); int rc; if ((rc = MTOS_pause(buf)) == 0) bail_to_command_line(); else if (rc == 2) { fputs(buf, stderr); text = 1; (void) fgets(buf, MAX_LINE_LEN, stdin); } } else if (strcmp(term->name, "atari") == 0) { char *readline(char *); char *line = readline(""); if (line) free(line); } else (void) fgets(buf, MAX_LINE_LEN, stdin); # else /* !MTOS */ # ifdef ATARI if (strcmp(term->name, "atari") == 0) { char *readline(char *); char *line = readline(""); if (line) free(line); } else (void) fgets(buf, MAX_LINE_LEN, stdin); # else /* !ATARI */ (void) fgets(buf, MAX_LINE_LEN, stdin); /* Hold until CR hit. */ # endif /* !ATARI */ # endif /* !MTOS */ # endif /* !_Macintosh */ # endif /* !OS2 */ #endif } if (sleep_time > 0) GP_SLEEP(sleep_time); if (text != 0 && sleep_time >= 0) fputc('\n', stderr); screen_ok = FALSE; } else if (almost_equals(c_token, "pr$int")) { int need_space = 0; /* space printed between two expressions only */ screen_ok = FALSE; do { ++c_token; if (isstring(c_token)) { char s[MAX_LINE_LEN]; quote_str(s, c_token, MAX_LINE_LEN); fputs(s, stderr); need_space = 0; ++c_token; } else { struct value a; (void) const_express(&a); if (need_space) putc(' ', stderr); need_space = 1; disp_value(stderr, &a); } } while (!END_OF_COMMAND && equals(c_token, ",")); (void) putc('\n', stderr); } else if (almost_equals(c_token, "fit")) { ++c_token; do_fit(); } else if (almost_equals(c_token, "up$date")) { char tmps[80]; char tmps2[80]; /* Have to initialise tmps2, otherwise * update() cannot decide whether a valid * filename was given. lh */ tmps2[0] = NUL; if (!isstring(++c_token)) int_error("Parameter filename expected", c_token); quote_str(tmps, c_token++, 80); if (!(END_OF_COMMAND)) { if (!isstring(c_token)) int_error("New parameter filename expected", c_token); else quote_str(tmps2, c_token++, 80); } update(tmps, tmps2); } else if (almost_equals(c_token, "p$lot")) { plot_token = c_token++; SET_CURSOR_WAIT; plotrequest(); SET_CURSOR_ARROW; } else if (almost_equals(c_token, "sp$lot")) { plot_token = c_token++; SET_CURSOR_WAIT; plot3drequest(); SET_CURSOR_ARROW; } else if (almost_equals(c_token, "rep$lot")) { if (replot_line[0] == NUL) int_error("no previous plot", c_token); c_token++; SET_CURSOR_WAIT; replotrequest(); SET_CURSOR_ARROW; } else if (almost_equals(c_token, "se$t")) set_command(); else if (almost_equals(c_token, "res$et")) reset_command(); else if (almost_equals(c_token, "sh$ow")) show_command(); else if (almost_equals(c_token, "cl$ear")) { term_start_plot(); if (multiplot && term->fillbox) { unsigned int x1 = (unsigned int) (xoffset * term->xmax); unsigned int y1 = (unsigned int) (yoffset * term->ymax); unsigned int width = (unsigned int) (xsize * term->xmax); unsigned int height = (unsigned int) (ysize * term->ymax); (*term->fillbox) (0, x1, y1, width, height); } term_end_plot(); screen_ok = FALSE; c_token++; } else if (almost_equals(c_token, "she$ll")) { do_shell(); screen_ok = FALSE; c_token++; } else if (almost_equals(c_token, "sa$ve")) { if (almost_equals(++c_token, "f$unctions")) { if (!isstring(++c_token)) int_error("expecting filename", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); save_functions(fopen(sv_file, "w")); } } else if (almost_equals(c_token, "v$ariables")) { if (!isstring(++c_token)) int_error("expecting filename", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); save_variables(fopen(sv_file, "w")); } } else if (almost_equals(c_token, "s$et")) { if (!isstring(++c_token)) int_error("expecting filename", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); save_set(fopen(sv_file, "w")); } } else if (isstring(c_token)) { quote_str(sv_file, c_token, MAX_LINE_LEN); save_all(fopen(sv_file, "w")); } else { int_error("filename or keyword 'functions', 'variables', or 'set' expected", c_token); } c_token++; } else if (almost_equals(c_token, "l$oad")) { if (!isstring(++c_token)) int_error("expecting filename", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); /* load_file(fp=fopen(sv_file, "r"), sv_file, FALSE); OLD * DBT 10/6/98 handle stdin as special case * passes it on to load_file() so that it gets * pushed on the stack and recusion will work, etc */ fp = strcmp(sv_file, "-") ? fopen(sv_file, "r") : stdin; load_file(fp, sv_file, FALSE); /* input_line[] and token[] now destroyed! */ c_token = num_tokens = 0; } } else if (almost_equals(c_token, "ca$ll")) { if (!isstring(++c_token)) int_error("expecting filename", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); load_file(fopen(sv_file, "r"), sv_file, TRUE); /* Argument list follows filename */ /* input_line[] and token[] now destroyed! */ c_token = num_tokens = 0; } } else if (almost_equals(c_token, "if")) { double exprval; struct value t; if (!equals(++c_token, "(")) /* no expression */ int_error("expecting (expression)", c_token); exprval = real(const_express(&t)); if (exprval != 0.0) { /* fake the condition of a ';' between commands */ int eolpos = token[num_tokens - 1].start_index + token[num_tokens - 1].length; --c_token; token[c_token].length = 1; token[c_token].start_index = eolpos + 2; input_line[eolpos + 2] = ';'; input_line[eolpos + 3] = NUL; } else c_token = num_tokens = 0; } else if (almost_equals(c_token, "rer$ead")) { fp = lf_top(); if (fp != (FILE *) NULL) rewind(fp); c_token++; } else if (almost_equals(c_token, "cd")) { if (!isstring(++c_token)) int_error("expecting directory name", c_token); else { quote_str(sv_file, c_token, MAX_LINE_LEN); if (changedir(sv_file)) { int_error("Can't change to this directory", c_token); } c_token++; } } else if (almost_equals(c_token, "pwd")) { GP_GETCWD(sv_file, sizeof(sv_file)); fprintf(stderr, "%s\n", sv_file); c_token++; } else if (almost_equals(c_token, "ex$it") || almost_equals(c_token, "q$uit")) { /* graphics will be tidied up in main */ return (1); } else if (!equals(c_token, ";")) { /* null statement */ #ifdef OS2 if (_osmode == OS2_MODE) { if (token[c_token].is_token) { int rc; rc = ExecuteMacro(input_line + token[c_token].start_index, token[c_token].length); if (rc == 0) { c_token = num_tokens = 0; return (0); } } } #endif int_error("invalid command", c_token); } return (0); }
char * gstrptime(char *s, char *fmt, struct tm *tm) { int yday, date; date = yday = 0; tm->tm_mday = 1; tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0; /* make relative times work (user-defined tic step) */ tm->tm_year = ZERO_YEAR; /* we do not yet calculate wday or yday, so make them illegal * [but yday will be read by %j] */ tm->tm_yday = tm->tm_wday = -1; while (*fmt) { if (*fmt != '%') { if (*fmt == ' ') { /* space in format means zero or more spaces in input */ while (*s == ' ') ++s; ++fmt; continue; } else if (*fmt == *s) { ++s; ++fmt; continue; } else break; /* literal match has failed */ } /* we are processing a percent escape */ switch (*++fmt) { case 'b': /* abbreviated month name */ { int m; for (m = 0; m < 12; ++m) if (strncasecmp(s, abbrev_month_names[m], strlen(abbrev_month_names[m])) == 0) { s += strlen(abbrev_month_names[m]); goto found_abbrev_mon; } /* get here => not found */ int_warn(DATAFILE, "Bad abbreviated month name"); m = 0; found_abbrev_mon: tm->tm_mon = m; break; } case 'B': /* full month name */ { int m; for (m = 0; m < 12; ++m) if (strncasecmp(s, full_month_names[m], strlen(full_month_names[m])) == 0) { s += strlen(full_month_names[m]); goto found_full_mon; } /* get here => not found */ int_warn(DATAFILE, "Bad full month name"); m = 0; found_full_mon: tm->tm_mon = m; break; } case 'd': /* read a day of month */ s = read_int(s, 2, &tm->tm_mday); date++; break; case 'm': /* month number */ s = read_int(s, 2, &tm->tm_mon); date++; --tm->tm_mon; break; case 'y': /* year number */ s = read_int(s, 2, &tm->tm_year); /* In line with the current UNIX98 specification by * The Open Group and major Unix vendors, * two-digit years 69-99 refer to the 20th century, and * values in the range 00-68 refer to the 21st century. */ if (tm->tm_year <= 68) tm->tm_year += 100; date++; tm->tm_year += 1900; break; case 'Y': s = read_int(s, 4, &tm->tm_year); date++; break; case 'j': s = read_int(s, 3, &tm->tm_yday); tm->tm_yday--; date++; yday++; break; case 'H': s = read_int(s, 2, &tm->tm_hour); break; case 'M': s = read_int(s, 2, &tm->tm_min); break; case 'S': s = read_int(s, 2, &tm->tm_sec); break; /* read EPOCH data * EPOCH is the std. unixtimeformat seconds since 01.01.1970 UTC * actualy i would need a read_long (or what time_t is else) * aktualy this is not my idea i got if from * AlunDa Penguin Jones (21.11.97) * but changed %t to %s because of strftime * and fixed the localtime() into gmtime() * maybe we should use ggmtime() ? but who choose double ???? * Walter Harms <*****@*****.**> 26 Mar 2000 */ case 's': #if 0 /* HBB 20040213: comment this out, but keep it around for now */ { /* time_t when; */ int when; struct tm *tmwhen; s = read_int(s, 10, &when); tmwhen = gmtime((time_t*)&when); tmwhen->tm_year += 1900; *tm = *tmwhen; break; } #else /* HBB 20040213: New version of this. 64-bit proof and * more in line with the rest of this module than the * original one. */ { double when; /* offset from UNIX epoch (1970) to gnuplot epoch */ static const long epoch_offset = (long)((ZERO_YEAR - 1970) * 365.25) * DAY_SEC; when = strtod (s, &s) - epoch_offset; ggmtime(tm, when); break; } #endif default: int_warn(DATAFILE, "Bad time format in string"); } fmt++; } FPRINTF((stderr, "read date-time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec)); /* now check the date/time entered, normalising if necessary * read_int cannot read a -ve number, but can read %m=0 then decrement * it to -1 */ #define S (tm->tm_sec) #define M (tm->tm_min) #define H (tm->tm_hour) if (S >= 60) { M += S / 60; S %= 60; } if (M >= 60) { H += M / 60; M %= 60; } if (H >= 24) { if (yday) tm->tm_yday += H / 24; tm->tm_mday += H / 24; H %= 24; } #undef S #undef M #undef H FPRINTF((stderr, "normalised time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec)); if (date) { if (yday) { if (tm->tm_yday < 0) int_error(DATAFILE, "Illegal day of year"); /* we just set month to jan, day to yday, and let the * normalising code do the work. */ tm->tm_mon = 0; /* yday is 0->365, day is 1->31 */ tm->tm_mday = tm->tm_yday + 1; } if (tm->tm_mon < 0) { int_error(DATAFILE, "illegal month"); return (NULL); } if (tm->tm_mday < 1) { int_error(DATAFILE, "illegal day of month"); return (NULL); } if (tm->tm_mon > 11) { tm->tm_year += tm->tm_mon / 12; tm->tm_mon %= 12; } { int days_in_month; while (tm->tm_mday > (days_in_month = (mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365))))) { if (++tm->tm_mon == 12) { ++tm->tm_year; tm->tm_mon = 0; } tm->tm_mday -= days_in_month; } } } return (s); }