/* Convert string into seconds from year 2000 */ void f_strptime(union argument *arg) { struct value fmt, val; struct tm time_tm; double result; (void) arg; /* Avoid compiler warnings */ pop(&val); pop(&fmt); if ( fmt.type != STRING || val.type != STRING ) int_error(NO_CARET, "Both parameters to strptime must be strings"); if ( !fmt.v.string_val || !val.v.string_val ) int_error(NO_CARET, "Internal error: string not allocated"); /* string -> time_tm */ gstrptime(val.v.string_val, fmt.v.string_val, &time_tm); /* time_tm -> result */ result = gtimegm(&time_tm); FPRINTF((stderr," strptime result = %g seconds \n", result)); gpfree_string(&val); gpfree_string(&fmt); push(Gcomplex(&val, result, 0.0)); }
static size_t xstrftime( char *str, /* output buffer */ size_t bsz, /* space available */ const char *fmt, struct tm *tm, double usec, double fulltime) { size_t l = 0; /* chars written so far */ int incr = 0; /* chars just written */ char *s = str; TBOOLEAN sign_printed = FALSE; memset(str, '\0', bsz); while (*fmt != '\0') { if (*fmt != '%') { if (l >= bsz-1) return 0; *s++ = *fmt++; l++; } else { /* set up format modifiers */ int w = 0; int z = 0; int p = 0; if (*++fmt == '0') { z = 1; ++fmt; } while (*fmt >= '0' && *fmt <= '9') { w = w * 10 + (*fmt - '0'); ++fmt; } if (*fmt == '.') { ++fmt; while (*fmt >= '0' && *fmt <= '9') { p = p * 10 + (*fmt - '0'); ++fmt; } if (p > 6) p = 6; } switch (*fmt++) { /* some shorthands : check that there is space in the * output string. */ #define CHECK_SPACE(n) do { \ if ((l+(n)) > bsz) return 0; \ } while (0) /* copy a fixed string, checking that there's room */ #define COPY_STRING(z) do { \ CHECK_SPACE(strlen(z)) ; \ strcpy(s, z); \ } while (0) /* format a string, using default spec if none given w * and z are width and zero-flag dw and dz are the * defaults for these In fact, CHECK_SPACE(w) is not a * sufficient test, since sprintf("%2d", 365) outputs * three characters */ #define FORMAT_STRING(dz, dw, x) do { \ if (w==0) { \ w=(dw); \ if (!z) \ z=(dz); \ } \ incr = snprintf(s, bsz-l-1, z ? "%0*d" : "%*d", w, (x)); \ CHECK_SPACE(incr); \ } while(0) case '%': CHECK_SPACE(1); *s = '%'; break; case 'a': COPY_STRING(abbrev_day_names[tm->tm_wday]); break; case 'A': COPY_STRING(full_day_names[tm->tm_wday]); break; case 'b': case 'h': COPY_STRING(abbrev_month_names[tm->tm_mon]); break; case 'B': COPY_STRING(full_month_names[tm->tm_mon]); break; case 'd': FORMAT_STRING(1, 2, tm->tm_mday); /* %02d */ break; case 'D': if (!xstrftime(s, bsz - l, "%m/%d/%y", tm, 0., fulltime)) return 0; break; case 'F': if (!xstrftime(s, bsz - l, "%Y-%m-%d", tm, 0., fulltime)) return 0; break; case 'H': FORMAT_STRING(1, 2, tm->tm_hour); /* %02d */ break; case 'I': FORMAT_STRING(1, 2, (tm->tm_hour + 11) % 12 + 1); /* %02d */ break; case 'j': FORMAT_STRING(1, 3, tm->tm_yday + 1); /* %03d */ break; /* not in linux strftime man page. Not really needed now */ case 'k': FORMAT_STRING(0, 2, tm->tm_hour); /* %2d */ break; case 'l': FORMAT_STRING(0, 2, (tm->tm_hour + 11) % 12 + 1); /* %2d */ break; case 'm': FORMAT_STRING(1, 2, tm->tm_mon + 1); /* %02d */ break; case 'M': FORMAT_STRING(1, 2, tm->tm_min); /* %02d */ break; case 'p': CHECK_SPACE(2); strcpy(s, (tm->tm_hour < 12) ? "am" : "pm"); break; case 'r': if (!xstrftime(s, bsz - l, "%I:%M:%S %p", tm, 0., fulltime)) return 0; break; case 'R': if (!xstrftime(s, bsz - l, "%H:%M", tm, 0., fulltime)) return 0; break; case 's': CHECK_SPACE(12); /* large enough for year 9999 */ sprintf(s, "%.0f", gtimegm(tm)); break; case 'S': FORMAT_STRING(1, 2, tm->tm_sec); /* %02d */ /* EAM FIXME - need to implement an actual format specifier */ if (p > 0) { double base = pow(10., (double)p); int msec = floor(0.5 + base * usec); char *f = &s[strlen(s)]; CHECK_SPACE(p+1); sprintf(f, ".%0*d", p, msec<(int)base?msec:(int)base-1); } break; case 'T': if (!xstrftime(s, bsz - l, "%H:%M:%S", tm, 0., fulltime)) return 0; break; case 't': /* Time (as opposed to Date) formats */ { int tminute, tsecond; switch (*fmt++) { case 'H': /* +/- fractional hours (not wrapped at 24h) */ if (p > 0) { incr = snprintf(s, bsz-l-1, "%*.*f", w, p, fulltime/3600.); CHECK_SPACE(incr); break; } /* Set flag in case minutes come next */ if (fulltime < 0) { CHECK_SPACE(1); /* the minus sign */ sign_printed = TRUE; *s++ = '-'; l++; } /* +/- integral hour truncated toward zero */ sprintf(s, "%0*d", w, (int)floor(fabs(fulltime/3600.))); break; case 'M': /* +/- fractional minutes (not wrapped at 60m) */ if (p > 0) { incr = snprintf(s, bsz-l-1, "%*.*f", w, p, sign_printed ? fabs(fulltime)/60. : fulltime/60.); CHECK_SPACE(incr); break; } /* +/- integral minute truncated toward zero */ tminute = floor(60. * (fabs(fulltime/3600.) - floor(fabs(fulltime/3600.)))); if (fulltime < 0) { if (!sign_printed) { sign_printed = TRUE; *s++ = '-'; l++; } } FORMAT_STRING(1, 2, tminute); /* %02d */ break; case 'S': /* +/- fractional seconds */ tsecond = floor(60. * (fabs(fulltime/60.) - floor(fabs(fulltime/60.)))); if (fulltime < 0) { if (usec > 0) usec = 1.0 - usec; if (!sign_printed) { *s++ = '-'; l++; } } FORMAT_STRING(1, 2, tsecond); /* %02d */ if (p > 0) { double base = pow(10., (double)p); int msec = floor(0.5 + base * usec); char *f = &s[strlen(s)]; CHECK_SPACE(p+1); sprintf(f, ".%0*d", p, msec<(int)base?msec:(int)base-1); } break; default: break; } break; } case 'W': /* mon 1 day of week */ { int week; 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 { /* sun prev week */ int bw = tm->tm_yday - tm->tm_wday; 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++; } FORMAT_STRING(1, 2, week); /* %02d */ break; } case 'U': /* sun 1 day of week */ { int week, bw; if (tm->tm_yday <= tm->tm_wday) { week = 1; if ((tm->tm_mday - tm->tm_yday) > 4) { week = 52; } } else { /* sat prev week */ bw = tm->tm_yday - tm->tm_wday - 1; 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++; } } FORMAT_STRING(1, 2, week); /* %02d */ break; } case 'w': /* day of week, sun=0 */ FORMAT_STRING(1, 2, tm->tm_wday); /* %02d */ break; case 'y': FORMAT_STRING(1, 2, tm->tm_year % 100); /* %02d */ break; case 'Y': FORMAT_STRING(1, 4, tm->tm_year); /* %04d */ break; } /* switch */ while (*s != '\0') { s++; l++; } #undef CHECK_SPACE #undef COPY_STRING #undef FORMAT_STRING } /* switch(fmt letter) */ } /* if(fmt letter not '%') */ return (l); }
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); }