Literal* Literal:: MakeRelTime( time_t t1, time_t t2 ) { Value val; if( t1<0 ) time( &t1 ); if( t2<0 ) time( &t2 ); val.SetRelativeTimeValue( t1 - t2 ); return( MakeLiteral( val ) ); }
Literal* Literal:: MakeReal(string number_string) { Value val; double real; char *end; real = strtod(number_string.c_str(), &end); if (end == number_string.c_str() && real == 0.0) { val.SetErrorValue(); } else { val.SetRealValue(real); } return MakeLiteral(val); }
Literal* Literal:: MakeRelTime( time_t secs ) { Value val; struct tm lt; if( secs<0 ) { time(&secs ); getLocalTime( &secs, < ); val.SetRelativeTimeValue((time_t) (lt.tm_hour*3600 + lt.tm_min*60 + lt.tm_sec)); } else { val.SetRelativeTimeValue((time_t) secs); } return( MakeLiteral( val ) ); }
Literal* Literal:: MakeAbsTime( abstime_t *tim ) { Value val; abstime_t abst; if (tim == NULL) { // => current time/offset time_t now; time( &now ); abst.secs = now; abst.offset = timezone_offset( now, false ); } else { //make a literal out of the passed value abst = *tim; } val.SetAbsoluteTimeValue( abst); return( MakeLiteral( val ) ); }
static int Draw(Char *cp, int nocomb) /* draw char at cp, expand tabs, ctl chars */ { int w, i, lv, lh; Char c, attr; attr = *cp & ~CHAR; c = *cp & CHAR; w = NLSClassify(c, nocomb); switch (w) { case NLSCLASS_NL: Vdraw('\0', 0); /* assure end of line */ vcursor_h = 0; /* reset cursor pos */ vcursor_v++; break; case NLSCLASS_TAB: do { Vdraw(' ', 1); } while ((vcursor_h & 07) != 0); break; case NLSCLASS_CTRL: Vdraw('^' | attr, 1); if (c == CTL_ESC('\177')) { Vdraw('?' | attr, 1); } else { #ifdef IS_ASCII /* uncontrolify it; works only for iso8859-1 like sets */ Vdraw(c | 0100 | attr, 1); #else Vdraw(_toebcdic[_toascii[c]|0100] | attr, 1); #endif } break; case NLSCLASS_ILLEGAL: Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; case NLSCLASS_ILLEGAL2: case NLSCLASS_ILLEGAL3: case NLSCLASS_ILLEGAL4: Vdraw('\\' | attr, 1); Vdraw('U' | attr, 1); Vdraw('+' | attr, 1); for (i = 8 * NLSCLASS_ILLEGAL_SIZE(w) - 4; i >= 0; i -= 4) Vdraw("0123456789ABCDEF"[(c >> i) & 15] | attr, 1); break; case 0: lv = vcursor_v; lh = vcursor_h; for (;;) { lh--; if (lh < 0) { lv--; if (lv < 0) break; lh = Strlen(Vdisplay[lv]) - 1; } if (Vdisplay[lv][lh] != CHAR_DBWIDTH) break; } if (lv < 0) { Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; } Vdisplay[lv][lh] = MakeLiteral(cp, 1, Vdisplay[lv][lh]); break; default: Vdraw(*cp, w); break; }
/* Creates a relative time literal, from the string timestr, *parsing it as [[[days+]hh:]mm:]ss * Ex - 1+00:02:00 */ Literal* Literal:: MakeRelTime(string timeStr) { Value val; double rsecs; int len = timeStr.length(); double secs = 0; int mins = 0; int hrs = 0; int days = 0; bool negative = false; int i=len-1; prevNonSpaceChar(timeStr,i); // checking for 'sec' parameter & collecting it if present (ss.sss) if((i>=0) &&((timeStr[i] == 's') || (timeStr[i] == 'S') || (isdigit(timeStr[i])))) { if((timeStr[i] == 's') || (timeStr[i] == 'S')) { i--; } prevNonSpaceChar(timeStr,i); string revSecStr; while((i>=0) &&(isdigit(timeStr[i]))) { revSecStr += timeStr[i--]; } if((i>=0) &&(timeStr[i] == '.')) { revSecStr += timeStr[i--]; while((i>=0) && (isdigit(timeStr[i]))) { revSecStr += timeStr[i--]; } } secs = revDouble(revSecStr); } prevNonSpaceChar(timeStr,i); // checking for 'min' parameter if((i>=0) &&((timeStr[i] == 'm') || (timeStr[i] == 'M') || (timeStr[i] == ':'))) { i--; string revMinStr; prevNonSpaceChar(timeStr,i); while((i>=0) &&(isdigit(timeStr[i]))) { revMinStr += timeStr[i--]; } mins = revInt(revMinStr); } prevNonSpaceChar(timeStr,i); // checking for 'hrs' parameter if((i>=0) &&((timeStr[i] == 'h') || (timeStr[i] == 'H') || (timeStr[i] == ':'))) { i--; string revHrStr; prevNonSpaceChar(timeStr,i); while((i>=0) &&(isdigit(timeStr[i]))) { revHrStr += timeStr[i--]; } hrs = revInt(revHrStr); } prevNonSpaceChar(timeStr,i); // checking for 'days' parameter if((i>=0) &&((timeStr[i] == 'd') || (timeStr[i] == 'D') || (timeStr[i] == '+'))) { i--; string revDayStr; prevNonSpaceChar(timeStr,i); while((i>=0) &&(isdigit(timeStr[i]))) { revDayStr += timeStr[i--]; } days = revInt(revDayStr); } prevNonSpaceChar(timeStr,i); // checking for '-' operator if((i>=0) &&(timeStr[i] == '-')) { negative = true; i--; } prevNonSpaceChar(timeStr,i); if((i>=0) && (!(isspace(timeStr[i])))) { // should not conatin any non-space char beyond -,d,h,m,s val.SetErrorValue( ); return(MakeLiteral( val )); } rsecs = ( negative ? -1 : +1 ) * ( days*86400 + hrs*3600 + mins*60 + secs ); val.SetRelativeTimeValue(rsecs); return( MakeLiteral( val ) ); }
/* Creates an absolute time literal, from the string timestr, *parsing it as the regular expression: D* dddd [D* dd [D* dd [D* dd [D* dd [D* dd D*]]]]] [-dd:dd | +dd:dd | z | Z] D => non-digit, d=> digit Ex - 2003-01-25T09:00:00-06:00 */ Literal* Literal:: MakeAbsTime(string timeStr ) { abstime_t abst; Value val; bool offset = false; // to check if the argument conatins a timezone offset parameter struct tm abstm; memset(&abstm, 0, sizeof(abstm)); int tzhr = 0; // corresponds to 1st "dd" in -|+dd:dd int tzmin = 0; // corresponds to 2nd "dd" in -|+dd:dd int len = timeStr.length(); int i=len-1; prevNonSpaceChar(timeStr,i); if((timeStr[i] == 'z') || (timeStr[i] == 'Z')) { // z|Z corresponds to a timezone offset of 0 offset = true; timeStr.erase(i,1); // remove the offset section from the string tzhr = 0; tzmin = 0; } else if (timeStr[len-5] == '+' || timeStr[len-5] == '-') { offset = extractTimeZone(timeStr, tzhr, tzmin); } else if ((timeStr[len-6] == '+' || timeStr[len-6] == '-') && timeStr[len-3] == ':') { timeStr.erase(len-3, 1); offset = extractTimeZone(timeStr, tzhr, tzmin); } i=0; len = timeStr.length(); nextDigitChar(timeStr,i); if(i > len-4) { // string has to contain dddd (year) val.SetErrorValue( ); return(MakeLiteral( val )); } abstm.tm_year = atoi(timeStr.substr(i,4).c_str()) - 1900; i += 4; nextDigitChar(timeStr,i); if(i<=len-2) { abstm.tm_mon = atoi(timeStr.substr(i,2).c_str()) - 1; i += 2; } nextDigitChar(timeStr,i); if(i<=len-2) { abstm.tm_mday = atoi(timeStr.substr(i,2).c_str()); i += 2; } nextDigitChar(timeStr,i); if(i<=len-2) { abstm.tm_hour += atoi(timeStr.substr(i,2).c_str()); i += 2; } nextDigitChar(timeStr,i); if(i<=len-2) { abstm.tm_min += atoi(timeStr.substr(i,2).c_str()); i += 2; } nextDigitChar(timeStr,i); if(i<=len-2) { abstm.tm_sec = atoi(timeStr.substr(i,2).c_str()); i += 2; } nextDigitChar(timeStr,i); if((i<=len-1) && (isdigit(timeStr[i]))) { // there should be no more digit characters once the required val.SetErrorValue( ); // parameteres are parsed return(MakeLiteral( val )); } abst.secs = mktime(&abstm); if(abst.secs == -1) { // the time should be one, which can be supported by the time_t type val.SetErrorValue( ); return(MakeLiteral( val )); } // mktime() creates the time assuming we specified something in // local time. We want the time as if we were in Greenwich (we'll // call gmTime later to extract it, not localtime()), so we adjust // by our timezone. abst.secs += timezone_offset( abst.secs, true ); if(offset) { abst.offset = (tzhr*3600) + (tzmin*60); } else { // if offset is not specified, the offset of the current locality is taken abst.offset = findOffset(abst.secs); //abst.secs -= abst.offset; } // If the time string we converted had a timezone offset (either // explicit or implicit), we need to adjust the resulting time_t // so that our final value is UTC. abst.secs -= abst.offset; if(abst.offset == -1) { // corresponds to illegal offset val.SetErrorValue( ); return(MakeLiteral( val ) ); } else { val.SetAbsoluteTimeValue(abst); } return( MakeLiteral( val ) ); }
/* draw char at cp, expand tabs, ctl chars */ static int Draw(Char *cp, int nocomb, int drawPrompt) { int w, i, lv, lh; Char c, attr; #ifdef WIDE_STRINGS if (!drawPrompt) { /* draw command-line */ attr = 0; c = *cp; } else { /* draw prompt */ /* prompt with attributes(UNDER,BOLD,STANDOUT) */ if (*cp & (UNDER | BOLD | STANDOUT)) { /* *cp >= STANDOUT */ /* example) * We can't distinguish whether (*cp=)0x02ffffff is * U+02FFFFFF or U+00FFFFFF|STANDOUT. * We handle as U+00FFFFFF|STANDOUT, only when drawing prompt. */ attr = (*cp & ATTRIBUTES); /* ~(UNDER | BOLD | STANDOUT) = 0xf1ffffff */ c = *cp & ~(UNDER | BOLD | STANDOUT); /* if c is ctrl code, we handle *cp as havnig no attributes */ if ((c < 0x20 && c >= 0) || c == 0x7f) { attr = 0; c = *cp; } } else { /* prompt without attributes */ attr = 0; c = *cp; } } #else attr = *cp & ~CHAR; c = *cp & CHAR; #endif w = NLSClassify(c, nocomb, drawPrompt); switch (w) { case NLSCLASS_NL: Vdraw('\0', 0); /* assure end of line */ vcursor_h = 0; /* reset cursor pos */ vcursor_v++; break; case NLSCLASS_TAB: do { Vdraw(' ', 1); } while ((vcursor_h & 07) != 0); break; case NLSCLASS_CTRL: Vdraw('^' | attr, 1); if (c == CTL_ESC('\177')) { Vdraw('?' | attr, 1); } else { #ifdef IS_ASCII /* uncontrolify it; works only for iso8859-1 like sets */ Vdraw(c | 0100 | attr, 1); #else Vdraw(_toebcdic[_toascii[c]|0100] | attr, 1); #endif } break; case NLSCLASS_ILLEGAL: Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; case NLSCLASS_ILLEGAL2: case NLSCLASS_ILLEGAL3: case NLSCLASS_ILLEGAL4: case NLSCLASS_ILLEGAL5: Vdraw('\\', 1); Vdraw('U', 1); Vdraw('+', 1); for (i = 16 + 4 * (-w-5); i >= 0; i -= 4) Vdraw("0123456789ABCDEF"[(c >> i) & 15] | attr, 1); break; case 0: lv = vcursor_v; lh = vcursor_h; for (;;) { lh--; if (lh < 0) { lv--; if (lv < 0) break; lh = Strlen(Vdisplay[lv]) - 1; } if (Vdisplay[lv][lh] != CHAR_DBWIDTH) break; } if (lv < 0) { Vdraw('\\' | attr, 1); Vdraw((((c >> 6) & 7) + '0') | attr, 1); Vdraw((((c >> 3) & 7) + '0') | attr, 1); Vdraw(((c & 7) + '0') | attr, 1); break; } Vdisplay[lv][lh] = MakeLiteral(cp, 1, Vdisplay[lv][lh]); break; default: Vdraw(*cp, w); break; }