/***** Autogenerated from runstring.in; changes will be overwritten *****/ #line 1 "./runtimebase.in" /***** * runtimebase.in * Andy Hammerlindl 2009/07/28 * * Common declarations needed for all code-generating .in files. * *****/ #line 1 "./runstring.in" /***** * runstring.in * * Runtime functions for string operations. * *****/ #line 1 "./runtimebase.in" #include "stack.h" #include "types.h" #include "builtin.h" #include "entry.h" #include "errormsg.h" #include "array.h" #include "triple.h" #include "callable.h" #include "opsymbols.h" using vm::stack; using vm::error; using vm::array; using vm::read; using vm::callable; using types::formal; using types::function; using camp::triple; #define PRIMITIVE(name,Name,asyName) using types::prim##Name; #include #undef PRIMITIVE void unused(void *); namespace run { typedef double real; array *copyArray(array *a); array *copyArray2(array *a); array *copyArray3(array *a); double *copyTripleArray2Components(array *a, size_t &N, GCPlacement placement=NoGC); triple *copyTripleArray2C(array *a, size_t &N, GCPlacement placement=NoGC); } function *realRealFunction(); #define CURRENTPEN processData().currentpen #line 10 "runstring.in" #include #include #include #include #include #include #include "array.h" using namespace camp; using namespace vm; using namespace settings; typedef array stringarray; typedef array stringarray2; using types::stringArray; using types::stringArray2; namespace types { extern const char *names[]; } namespace run { extern string emptystring; } static const string defaulttimeformat=string("%a %b %d %T %Z %Y"); #ifdef HAVE_STRFTIME static const size_t nTime=256; static char Time[nTime]; #endif void checkformat(const char *ptr, bool intformat) { while(*ptr != '\0') { if(*ptr != '%') /* While we have regular characters, print them. */ ptr++; else { /* We've got a format specifier. */ ptr++; while(*ptr && strchr ("-+ #0'I", *ptr)) /* Move past flags. */ ptr++; if(*ptr == '*') ptr++; else while(isdigit(*ptr)) /* Handle explicit numeric value. */ ptr++; if(*ptr == '.') { ptr++; /* Go past the period. */ if(*ptr == '*') { ptr++; } else while(isdigit(*ptr)) /* Handle explicit numeric value. */ ptr++; } while(*ptr && strchr ("hlL", *ptr)) ptr++; if(*ptr == '%') {++ptr; continue;} else if(*ptr != '\0') { if(intformat) { switch(*ptr) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c': break; default: ostringstream buf; buf << "Invalid format '" << *ptr << "' for type " << types::names[types::ty_Int]; error(buf); break; } } else { switch(*ptr) { case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': break; default: ostringstream buf; buf << "Invalid format '" << *ptr << "' for type " << types::names[types::ty_real]; error(buf); break; } } } break; // Only one argument is allowed. } /* End of else statement */ } } // Autogenerated routines: #ifndef NOSYM #include "runstring.symbols.h" #endif namespace run { // String operations #line 116 "./runstring.in" void emptyString(stack *Stack) { #line 117 "./runstring.in" {Stack->push(emptystring); return;} } #line 122 "./runstring.in" // Int length(string *s); void gen_runstring1(stack *Stack) { string * s=vm::pop(Stack); #line 123 "./runstring.in" {Stack->push((Int) s->length()); return;} } #line 127 "./runstring.in" // Int find(string *s, string t, Int pos=0); void gen_runstring2(stack *Stack) { Int pos=vm::pop(Stack,0); string t=vm::pop(Stack); string * s=vm::pop(Stack); #line 128 "./runstring.in" size_t n=s->find(t,pos); {Stack->push(n == string::npos ? (Int) -1 : (Int) n); return;} } #line 133 "./runstring.in" // Int rfind(string *s, string t, Int pos=-1); void gen_runstring3(stack *Stack) { Int pos=vm::pop(Stack,-1); string t=vm::pop(Stack); string * s=vm::pop(Stack); #line 134 "./runstring.in" size_t n=s->rfind(t,pos); {Stack->push(n == string::npos ? (Int) -1 : (Int) n); return;} } #line 139 "./runstring.in" // string reverse(string s); void gen_runstring4(stack *Stack) { string s=vm::pop(Stack); #line 140 "./runstring.in" reverse(s.begin(),s.end()); {Stack->push(s); return;} } #line 145 "./runstring.in" // string insert(string s, Int pos, string t); void gen_runstring5(stack *Stack) { string t=vm::pop(Stack); Int pos=vm::pop(Stack); string s=vm::pop(Stack); #line 146 "./runstring.in" if ((size_t) pos < s.length()) {Stack->push(s.insert(pos,t)); return;} {Stack->push(s); return;} } #line 152 "./runstring.in" // string substr(string* s, Int pos, Int n=-1); void gen_runstring6(stack *Stack) { Int n=vm::pop(Stack,-1); Int pos=vm::pop(Stack); string* s=vm::pop(Stack); #line 153 "./runstring.in" if ((size_t) pos < s->length()) {Stack->push(s->substr(pos,n)); return;} {Stack->push(emptystring); return;} } #line 159 "./runstring.in" // string erase(string s, Int pos, Int n); void gen_runstring7(stack *Stack) { Int n=vm::pop(Stack); Int pos=vm::pop(Stack); string s=vm::pop(Stack); #line 160 "./runstring.in" if ((size_t) pos < s.length()) {Stack->push(s.erase(pos,n)); return;} {Stack->push(s); return;} } #line 166 "./runstring.in" // string downcase(string s); void gen_runstring8(stack *Stack) { string s=vm::pop(Stack); #line 167 "./runstring.in" std::transform(s.begin(),s.end(),s.begin(),tolower); {Stack->push(s); return;} } #line 172 "./runstring.in" // string upcase(string s); void gen_runstring9(stack *Stack) { string s=vm::pop(Stack); #line 173 "./runstring.in" std::transform(s.begin(),s.end(),s.begin(),toupper); {Stack->push(s); return;} } // returns a string constructed by translating all occurrences of the string // from in an array of string pairs {from,to} to the string to in string s. #line 180 "./runstring.in" // string replace(string *S, stringarray2 *translate); void gen_runstring10(stack *Stack) { stringarray2 * translate=vm::pop(Stack); string * S=vm::pop(Stack); #line 181 "./runstring.in" size_t size=checkArray(translate); for(size_t i=0; i < size; i++) { array *a=read(translate,i); checkArray(a); } size_t pos=0; ostringstream buf; size_t Len=S->length(); while(pos < Len) { for(size_t i=0; i < size;) { array *a=read(translate,i); size_t size2=checkArray(a); if(size2 != 2) error("translation table entry must be an array of length 2"); string* from=read(a,0); size_t len=from->length(); if(len == 0 || S->compare(pos,len,*from,0,len) != 0) {i++; continue;} buf << read(a,1); pos += len; if(pos == Len) {Stack->push(buf.str()); return;} i=0; } buf << S->substr(pos,1); ++pos; } {Stack->push(buf.str()); return;} } #line 211 "./runstring.in" // string format(string *format, Int x, string locale=emptystring); void gen_runstring11(stack *Stack) { string locale=vm::pop(Stack,emptystring); Int x=vm::pop(Stack); string * format=vm::pop(Stack); #line 212 "./runstring.in" ostringstream out; const char *p0=format->c_str(); checkformat(p0,true); const char *p=p0; const char *start=NULL; while(*p != 0) { char curr=*p; if(curr == '%') { p++; if(*p != '%') {start=p-1; break;} } out << *(p++); } if(!start) {Stack->push(out.str()); return;} // Allow at most 1 argument while(*p != 0) { if(*p == '*' || *p == '$') {Stack->push(out.str()); return;} if(isupper(*p) || islower(*p)) {p++; break;} p++; } string f=format->substr(start-p0,p-start); f.insert(p-start-1,"ll"); const char *oldlocale=NULL; if(!locale.empty()) { oldlocale=setlocale(LC_ALL,NULL); if(oldlocale) oldlocale=StrdupNoGC(oldlocale); setlocale(LC_ALL,locale.c_str()); } Int size=snprintf(NULL,0,f.c_str(),x)+1; if(size < 1) size=255; // Workaround for non-C99 compliant systems. char *buf=new char[size]; snprintf(buf,size,f.c_str(),x); out << string(buf); out << p; delete[] buf; if(oldlocale) { setlocale(LC_ALL,oldlocale); delete[] oldlocale; } {Stack->push(out.str()); return;} } #line 266 "./runstring.in" // string format(string *format, bool forcemath=false, string separator, real x, string locale=emptystring); void gen_runstring12(stack *Stack) { string locale=vm::pop(Stack,emptystring); real x=vm::pop(Stack); string separator=vm::pop(Stack); bool forcemath=vm::pop(Stack,false); string * format=vm::pop(Stack); #line 268 "./runstring.in" if(*format == "%") {Stack->push(""); return;} // Temporary workaround for github Issue #29. bool tex=getSetting("tex") != "none"; bool texify=forcemath; ostringstream out; const char *p0=format->c_str(); checkformat(p0,false); const char *phantom="\\phantom{+}"; const char *p=p0; const char *start=NULL; char prev=0; while(*p != 0) { char curr=*p; if(tex && curr == '$' && prev != '\\') texify=true; prev=curr; if(curr == '%') { p++; if(*p != '%') {start=p-1; break;} } out << *(p++); } if(!start) {Stack->push(out.str()); return;} // Allow at most 1 argument while(*p != 0) { if(*p == '*' || *p == '$') {Stack->push(out.str()); return;} if(isupper(*p) || islower(*p)) {p++; break;} p++; } const char *tail=p; string f=format->substr(start-p0,tail-start); const char *oldlocale=NULL; if(!locale.empty()) { oldlocale=setlocale(LC_ALL,NULL); if(oldlocale) oldlocale=StrdupNoGC(oldlocale); setlocale(LC_ALL,locale.c_str()); } Int size=snprintf(NULL,0,f.c_str(),x)+1; if(size < 1) size=255; // Workaround for non-C99 compliant systems. char *buf=new char[size]; snprintf(buf,size,f.c_str(),x); bool trailingzero=f.find("#") < string::npos; bool plus=f.find("+") < string::npos; bool space=f.find(" ") < string::npos; char *q=buf; // beginning of formatted number if(*q == ' ' && texify) { out << phantom; q++; } const char decimal=*(localeconv()->decimal_point); // Remove any spurious sign if(*q == '-' || *q == '+') { p=q+1; bool zero=true; while(*p != 0) { if(!isdigit(*p) && *p != decimal) break; if(isdigit(*p) && *p != '0') {zero=false; break;} p++; } if(zero) { q++; if((plus || space) && texify) out << phantom; } } const char *r=p=q; bool dp=false; while(*r != 0 && (isspace(*r) || isdigit(*r) || *r == decimal \ || *r == '+' || *r == '-')) { if(*r == decimal) dp=true; r++; } if(dp) { // Remove trailing zeros and/or decimal point r--; unsigned n=0; while(r > q && *r == '0') {r--; n++;} if(*r == decimal) {r--; n++;} while(q <= r) out << *(q++); if(!trailingzero) q += n; } bool zero=(r == p && *r == '0') && !trailingzero; // Translate "E+/E-/e+/e-" exponential notation to TeX while(*q != 0) { if(texify && (*q == 'E' || *q == 'e') && (*(q+1) == '+' || *(q+1) == '-')) { if(!zero) out << separator << "10^{"; bool plus=(*(q+1) == '+'); q++; if(plus) q++; if(*q == '-') out << *(q++); while(*q == '0' && (zero || isdigit(*(q+1)))) q++; while(isdigit(*q)) out << *(q++); if(!zero) out << "}"; break; } out << *(q++); } while(*tail != 0) out << *(tail++); delete[] buf; if(oldlocale) { setlocale(LC_ALL,oldlocale); delete[] oldlocale; } {Stack->push(out.str()); return;} } #line 395 "./runstring.in" // Int hex(string s); void gen_runstring13(stack *Stack) { string s=vm::pop(Stack); #line 396 "./runstring.in" istringstream is(s); is.setf(std::ios::hex,std::ios::basefield); Int value; if(is && is >> value && ((is >> std::ws).eof())) {Stack->push(value); return;} ostringstream buf; buf << "invalid hexadecimal cast from string \"" << s << "\""; error(buf); } #line 406 "./runstring.in" // Int ascii(string s); void gen_runstring14(stack *Stack) { string s=vm::pop(Stack); #line 407 "./runstring.in" {Stack->push(s.empty() ? -1 : (unsigned char) s[0]); return;} } #line 411 "./runstring.in" // string string(Int x); void gen_runstring15(stack *Stack) { Int x=vm::pop(Stack); #line 412 "./runstring.in" ostringstream buf; buf << x; {Stack->push(buf.str()); return;} } #line 418 "./runstring.in" // string string(real x, Int digits=DBL_DIG); void gen_runstring16(stack *Stack) { Int digits=vm::pop(Stack,DBL_DIG); real x=vm::pop(Stack); #line 419 "./runstring.in" ostringstream buf; buf.precision(digits); buf << x; {Stack->push(buf.str()); return;} } #line 426 "./runstring.in" // string time(string format=defaulttimeformat); void gen_runstring17(stack *Stack) { string format=vm::pop(Stack,defaulttimeformat); #line 427 "./runstring.in" #ifdef HAVE_STRFTIME const time_t bintime=time(NULL); if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push(""); return;} {Stack->push(Time); return;} #else {Stack->push(format); return;} #endif } #line 437 "./runstring.in" // string time(Int seconds, string format=defaulttimeformat); void gen_runstring18(stack *Stack) { string format=vm::pop(Stack,defaulttimeformat); Int seconds=vm::pop(Stack); #line 438 "./runstring.in" #ifdef HAVE_STRFTIME const time_t bintime=seconds; if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push(""); return;} {Stack->push(Time); return;} #else // Avoid unused variable warning messages unused(&seconds); {Stack->push(format); return;} #endif } #line 450 "./runstring.in" // Int seconds(string t=emptystring, string format=emptystring); void gen_runstring19(stack *Stack) { string format=vm::pop(Stack,emptystring); string t=vm::pop(Stack,emptystring); #line 451 "./runstring.in" if (t == "") { auto clock = std::chrono::system_clock::now(); {Stack->push(static_cast( std::chrono::duration_cast( clock.time_since_epoch() ).count() )); return;} } std::tm tmObj = {}; istringstream instream(t); instream.imbue(std::locale("")); instream >> std::get_time(&tmObj,format.c_str()); if(instream.fail()) { {Stack->push(-1); return;} } {Stack->push(static_cast(std::mktime(&tmObj))); return;} } } // namespace run namespace trans { void gen_runstring_venv(venv &ve) { #line 115 "./runstring.in" REGISTER_BLTIN(run::emptyString,"emptyString"); #line 122 "./runstring.in" addFunc(ve, run::gen_runstring1, primInt(), SYM(length), formal(primString(), SYM(s), false, false)); #line 127 "./runstring.in" addFunc(ve, run::gen_runstring2, primInt(), SYM(find), formal(primString(), SYM(s), false, false), formal(primString(), SYM(t), false, false), formal(primInt(), SYM(pos), true, false)); #line 133 "./runstring.in" addFunc(ve, run::gen_runstring3, primInt(), SYM(rfind), formal(primString(), SYM(s), false, false), formal(primString(), SYM(t), false, false), formal(primInt(), SYM(pos), true, false)); #line 139 "./runstring.in" addFunc(ve, run::gen_runstring4, primString(), SYM(reverse), formal(primString(), SYM(s), false, false)); #line 145 "./runstring.in" addFunc(ve, run::gen_runstring5, primString(), SYM(insert), formal(primString(), SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primString(), SYM(t), false, false)); #line 152 "./runstring.in" addFunc(ve, run::gen_runstring6, primString(), SYM(substr), formal(primString(), SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primInt(), SYM(n), true, false)); #line 159 "./runstring.in" addFunc(ve, run::gen_runstring7, primString(), SYM(erase), formal(primString(), SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primInt(), SYM(n), false, false)); #line 166 "./runstring.in" addFunc(ve, run::gen_runstring8, primString(), SYM(downcase), formal(primString(), SYM(s), false, false)); #line 172 "./runstring.in" addFunc(ve, run::gen_runstring9, primString(), SYM(upcase), formal(primString(), SYM(s), false, false)); #line 178 "./runstring.in" addFunc(ve, run::gen_runstring10, primString(), SYM(replace), formal(primString(), SYM(s), false, false), formal(stringArray2(), SYM(translate), false, false)); #line 211 "./runstring.in" addFunc(ve, run::gen_runstring11, primString(), SYM(format), formal(primString(), SYM(format), false, false), formal(primInt(), SYM(x), false, false), formal(primString(), SYM(locale), true, false)); #line 266 "./runstring.in" addFunc(ve, run::gen_runstring12, primString(), SYM(format), formal(primString(), SYM(format), false, false), formal(primBoolean(), SYM(forcemath), true, false), formal(primString(), SYM(separator), false, false), formal(primReal(), SYM(x), false, false), formal(primString(), SYM(locale), true, false)); #line 395 "./runstring.in" addFunc(ve, run::gen_runstring13, primInt(), SYM(hex), formal(primString(), SYM(s), false, false)); #line 406 "./runstring.in" addFunc(ve, run::gen_runstring14, primInt(), SYM(ascii), formal(primString(), SYM(s), false, false)); #line 411 "./runstring.in" addFunc(ve, run::gen_runstring15, primString(), SYM(string), formal(primInt(), SYM(x), false, false)); #line 418 "./runstring.in" addFunc(ve, run::gen_runstring16, primString(), SYM(string), formal(primReal(), SYM(x), false, false), formal(primInt(), SYM(digits), true, false)); #line 426 "./runstring.in" addFunc(ve, run::gen_runstring17, primString(), SYM(time), formal(primString(), SYM(format), true, false)); #line 437 "./runstring.in" addFunc(ve, run::gen_runstring18, primString(), SYM(time), formal(primInt(), SYM(seconds), false, false), formal(primString(), SYM(format), true, false)); #line 450 "./runstring.in" addFunc(ve, run::gen_runstring19, primInt(), SYM(seconds), formal(primString(), SYM(t), true, false), formal(primString(), SYM(format), true, false)); } } // namespace trans