int Runaround(unsigned int m){ int len=(int)(log((double)m)/log(10.0))+1; int steps,digit; int i,iter; short *check; if(!checkRunaround(m)) return 0; check=(short*)calloc(len,sizeof(short)); steps = getdigit(m,len); iter = len; do{ if(check[iter-1]){ free(check); return 0; } else{ check[iter-1]=1; } i=steps%len; if(iter>(i%len)) iter-=(i%len); else{ iter=(iter+len)-(i%len); } steps=getdigit(m,iter); }while(steps!=getdigit(m,len)); for(i=0;i<len;i++) if(!check[i]) return 0; return 1; }
const char* scan_decimal(const char* str, unsigned long long* data, int* len, int* overflow, int base) { bool overflowFlag = false; int overflowDigits = 0; unsigned long long value = *data; const char* ptr = str; for (; *ptr; ptr++) { int digit = getdigit(*ptr); if (digit >= 0 && digit < base) { if (!overflowFlag) { unsigned long long newVal; if (__builtin_umulll_overflow(value, base, &newVal) || __builtin_uaddll_overflow(newVal, digit, &newVal)) { overflowFlag = true; } else { value = newVal; } } if (overflowFlag) { overflowDigits++; } } else { break; } } *data = value; if (len) *len += ptr - str - overflowDigits; if (overflow) *overflow = overflowDigits; return ptr; }
void printLink(LinkList L) { Node *p; long long k; p = L->next; if (!p) printf("0"); else { printf("%lli", p->num); p = p->next; } while (p) { k = getdigit(p->num); while (8 - k>0) { printf("0"); k = k + 1; } if (p->num) printf("%lli", p->num); p = p->next; } printf("\n"); }
unsigned long strtoul(const char *string, char **eptr, int base) { int accu, dig; if(base < 1 || base > 36) { if(string[0] == '0') { switch(string[1]) { case 'x': case 'X': return strtoul(string+2, eptr, 16); case 'b': case 'B': return strtoul(string+2, eptr, 2); default: return strtoul(string, eptr, 8); } } return strtoul(string, eptr, 10); } if(base == 16 && string[0] == '0' && (string[1] == 'x' || string[1] == 'X')) string += 2; if(base == 2 && string[0] == '0' && (string[1] == 'b' || string[1] == 'B')) string += 2; accu = 0; while( (dig = getdigit(*string, base)) != -1 ) { accu = accu * base + dig; string++; } if(eptr) *eptr = (char *) string; return accu; }
void bfs(int start, int end) { if(start == end) { minStep = 0; return; } pri p; p.val = start; p.step = 0; queue[rear++] = p; visited[start] = true; rear %= QSIZE; while(!(front == rear)) { pri pfront = queue[front++]; front %= QSIZE; int d; for(int i=0; i<4; i++) { d = getdigit(digit[i], pfront.val); // printf("get digit %d\n", d); for(int j=0; j<10; j++) { if(j != 0) { d += digit[i]; } if(prime[d] == true && visited[d] == false) { // printf("next %d\n", d); pri p; p.val = d; p.step = pfront.step + 1; visited[d] = true; queue[rear++] = p; rear %= QSIZE; if(d == end) { minStep = (MIN(minStep, p.step)); return; } } } } } }
void radix_sort (int64_t * vec, int64_t len) { ////////////////////////////////////////////////// //////////////IMPORANT: TO DO///////////////////// ////////////////////////////////////////////////// ////REMOVE ASSUMPTION THAT VEC LEN = 5//////////// ////////////////////////////////////////////////// //Bucket of values based on digit check int64_t ** bucket = calloc(10, sizeof(int64_t *)); //Count of values in each bucket int64_t * buckCnt = calloc(10, sizeof(int64_t *)); int64_t max = get_maximum(vec); int64_t digits = 1; while (max) { max /= 10; digits++; } for (int i = 0; i < digits; i++) { buckCnt = calloc(10, sizeof(int64_t *)); for (int m = 0; m <10; m++) bucket[m] = calloc(g_length, sizeof(int64_t)); for (int64_t j = 0; j < len; j++) { int curDigit = getdigit(vec[j], i); bucket[curDigit][buckCnt[curDigit]] = vec[j]; buckCnt[curDigit]++; } int64_t put = 0; for (int i = 0; i < 10; i++) { for (int64_t j = 0; j < buckCnt[i]; j++) { vec[put++] = bucket[i][j]; } } } for (int i = 0; i < digits; i++) free(bucket[i]); free(bucket); free(buckCnt); }
int htoi(char *str) { int i, c, x; int len = strlen(str); x = 0; for (i=0; iswhitespace(str[i]); i++); if (str[i]=='0' && (str[i+1]=='x' || str[i+1]=='X')) i += 2; while((c=getdigit(str[i++]))!=-1) { x *= 16; x += c; } return x; }
int getlex() { char c; char *p; g1: c=next(); if (c == 0) return 0; if (c <= ' ') goto g1; if (c=='=') {if(thechar=='=') {next(); return T_EQ; }} if (c=='!') {if(thechar=='=') {next(); return T_NE; }} if (c=='<') {if(thechar=='=') {next(); return T_LE; }} if (c=='>') {if(thechar=='=') {next(); return T_GE; }} if (c=='<') {if(thechar=='<') {next(); return T_LESSLESS; }} if (c=='>') {if(thechar=='>') {next(); return T_GREATGREAT;}} if (c=='+') {if(thechar=='+') {next(); return T_PLUSPLUS; }} if (c=='-') {if(thechar=='-') {next(); return T_MINUSMINUS;}} if (c=='+') {if(thechar=='=') {next(); return T_PLUSASS; }} if (c=='-') {if(thechar=='=') {next(); return T_MINUSASS; }} if (c=='&') {if(thechar=='=') {next(); return T_ANDASS; }} if (c=='|') {if(thechar=='=') {next(); return T_ORASS; }} if (c=='*') {if(thechar=='=') {next(); return T_MULASS; }} if (c=='/') {if(thechar=='=') {next(); return T_DIVASS; }} if (instr1("()[]{},;*:%-><=+!&|#", c)) return c ; if (c == '/') { if (thechar == '*') { g2: c=next(); if (c != '*') goto g2; if (thechar != '/') goto g2; c=next(); return getlex(); } else return '/'; } if (c == '"') {getstring(c); return T_STRING;} if (digit(c)) { getdigit(c); return T_CONST; } if (c==39) { lexval=next(); if (lexval==92) {lexval=next(); if (lexval=='n') lexval=10; if (lexval=='t') lexval= 9; if (lexval=='0') lexval= 0; } next(); return T_CONST; } if (letter(c)) { strcpy1(symboltemp, symbol); p=&symbol; *p=c; p++; while(letter(thechar)) {c=next(); *p=c; p++; } *p=0; if (eqstr(symbol,"signed" )) return T_SIGNED; if (eqstr(symbol,"unsigned")) return T_UNSIGNED; if (eqstr(symbol,"void" )) return T_VOID; if (eqstr(symbol,"int" )) return T_INT; if (eqstr(symbol,"char" )) return T_CHAR; if (eqstr(symbol,"asm" )) return T_ASM; if (eqstr(symbol,"__asm" )) return T_ASMBLOCK; if (eqstr(symbol,"__emit__")) return T_EMIT; if (eqstr(symbol,"return" )) return T_RETURN; if (eqstr(symbol,"if" )) return T_IF; if (eqstr(symbol,"else" )) return T_ELSE; if (eqstr(symbol,"while" )) return T_WHILE; if (eqstr(symbol,"do" )) return T_DO; if (eqstr(symbol,"goto" )) return T_GOTO; if (eqstr(symbol,"define" )) return T_DEFINE; if (eqstr(symbol,"include" )) return T_INCLUDE; if (convertdefine() ) {strcpy1(symbol, symboltemp); return T_CONST;} return T_NAME; } error1("Zeichen nicht erkannt"); }
int calc(char **s, char delimiter, ops lopz) { /* Asthe definition about this function, It's clear that * I should at least read in one more operand */ ops ropz = (ops)malloc(sizeof(*ropz)); /* if we get a left bracket, ha! compute what's inside bracket first */ if (getbracket(s) == '(') { /* a brackets is new begin */ ops start = (ops)malloc(sizeof(*start)); start->opnd = 0; start->oprt = '+'; calc(s, ')', start); /* getoprt will jump that ')' */ ropz->opnd = start->opnd; free(start); } else ropz->opnd = getdigit(s); /* If I get to the delimiter, I should stop and compute */ if ((ropz->oprt = getoprt(s)) == delimiter) { /* getoprt will jump over delimiter, include '\0', ')'*/ lopz->opnd = compute(lopz->opnd, ropz->opnd, lopz->oprt); /* since lopz used for computing, it's useless now, let lopz overwrite it */ /* set roprt be the least prior operator, even than '+', so that we can just roll back to what expression began */ lopz->oprt = '#'; free(ropz); return; } while (isprior(ropz->oprt, lopz->oprt)) { calc(s, delimiter, ropz); } /* what we have here? * lopz mush be greater than its left, * but now also greater than roprt, * so, we can compute now */ lopz->opnd = compute(lopz->opnd, ropz->opnd, lopz->oprt); lopz->oprt = ropz->oprt; free(ropz); return; // return a signal maybe? }
/* getradixnumber - read a number in a specified radix */ static int getradixnumber(CsCompiler *c,int radix) { char *p = c->t_token; int_t val = 0; int ch; /* get number */ while ((ch = getch(c)) != stream::EOS) { if (islower(ch)) ch = toupper(ch); if (!isradixdigit(ch,radix)) break; val = val * radix + getdigit(ch); *p++ = ch; } c->savedChar = ch; *p = '\0'; /* convert the string to a number */ c->t_value = val; return T_INTEGER; }
int main() { clock_t start, end; long long i, j = 0, k; long long digit[2][2] = { 0 }; char op, string_temp[9]; char top1, top2; char mystring[9], mystring_temp[9]; // FILE *ft; LinkList L1, L2, L, L_temp, L1_temp, L3_adj; InitList(&L1); InitList(&L2); InitList(&L); int flags = 1; long long nu1, nu2; long long ii = 0, cnt_n = 2; int flags_line = 1; for (ii = 0; ii < 2; ii++) { mystring[ii] = getchar(); } if (mystring[1] != '\n') { printf("op INput ERROR!\n"); return 0; } op = mystring[0]; if (op != '+' && op != '-' && op != '*' && op != '/') { printf("op INput ERROR!\n"); return 0; } while (cnt_n) { for (ii = 0; ii < 8; ii++) { mystring[ii] = getchar(); if (mystring[ii] == '\n') { cnt_n = cnt_n - 1; mystring[ii] = '\0'; break; } else if (mystring[ii]<48 || mystring[ii] >57) { printf("opNumber INput ERROR!\n"); return 0; } } mystring[ii] = '\0'; if (ii == 8) { digit[2 - cnt_n][0] = digit[2 - cnt_n][0] + 1; if (cnt_n == 2) L1 = CreateListHead(L1, mystring, 0, 0); else L2 = CreateListHead(L2, mystring, 0, 0); } else { digit[2 - cnt_n - 1][1] = ii; if (digit[2 - cnt_n - 1][1] + digit[2 - cnt_n - 1][0] * 8 == 0) { printf("opNumber INput ERROR!\n"); return 0; } if (ii) { if (cnt_n == 1) L1 = CreateListHead(L1, mystring, 0, 0); else L2 = CreateListHead(L2, mystring, 0, 0); } } // mystring[0]='\0'; } /*read from txt to test my input,so save it ft = fopen("C:\\Users\\v-xiafe\\Desktop\\ASE\\project (1)\\ConsoleApplication3\\Release\\test.txt", "r"); if (ft == NULL) { printf("File Name Error.\n"); return 0; } InitList(&L1); InitList(&L2); InitList(&L); int flags = 1; long long nu1, nu2; while (!digit[1][1]) { fgets(mystring, 9, ft); if (strstr(mystring, "+") == NULL && strstr(mystring, "-") == NULL && strstr(mystring, "*") == NULL && strstr(mystring, "/") == NULL) { while (mystring != NULL) { // puts(mystring); if (strstr(mystring, "\n") == NULL && strlen(mystring) == 9 - 1) { // strcpy(string_temp, mystring); if (flags == 1) { L1 = CreateListHead(L1, mystring, 0, 0); digit[0][0] = digit[0][0] + 1; } else { L2 = CreateListHead(L2, mystring, 0, 0); digit[1][0] = digit[1][0] + 1; } } else { if (flags == 1) { if (strlen(mystring) == 1) digit[0][1] = 0; else { L1 = CreateListHead(L1, mystring, 0, 0); digit[0][1] = strlen(mystring) - 1; } } flags = 2; } if (feof(ft)) break; else { fgets(mystring, 9, ft); if (feof(ft)) { digit[1][1] = strlen(mystring); if (digit[1][1] == 8) digit[1][1] = 0; else { L2 = CreateListHead(L2, mystring, 0, 0); } break; } } } if (feof(ft)) break; } else { op = mystring[0]; // putchar(op); putchar('\n'); } } fclose(ft); */ L1 = AlignList(L1, digit[0][1]); L2 = AlignList(L2, digit[1][1]); Node *p, *q, *r; p = L1->next; q = L2->next; if (8 * digit[0][0] + digit[0][1] == 1) { if (p->num == 0) { printf("opNumber1 INput ERROR!\n"); return 0; } } if (8 * digit[1][0] + digit[1][1] == 1) { if (q->num == 0) { printf("opNumber2 INput ERROR!\n"); return 0; } } if (op == '/') { // InitList(&L1_temp); // InitList(&L2_temp); // Node *p, *q, *p0; p = L1->next; q = L2->next; nu1 = p->num; if (p->next) { while (p->next) { nu1 = p->num; p = p->next; } nu1 = 100000000 * p->num + nu1; } while (q) { nu2 = q->num; q = q->next; } } // op = '*'; // Node *p,*r; LinkList L_re; InitList(&L_re); switch (op) { case '+': L_temp = add(L1, L2, L); printLink(L_temp); break; case '-': L_temp = sub(L2, L1, L); printLink(L_temp); break; case '*': start = clock(); L_temp = mul(L1, L2, L); end = clock(); p = L_temp->next; while (p) { r = p; L_re = CreateListHead(L_re, "00", p->num, 0); p = p->next; free(r); } printLink(L_re); printf("%d s\n", (end - start) / CLOCKS_PER_SEC); break; case '/': { long long n, cn_temp; // Node *p,*q; LinkList p0, L_subrev, L1_temp1, L3, L3_temp, L_zc; InitList(&L_subrev); InitList(&L3); InitList(&L3_temp); InitList(&L_zc); L1_temp1 = L1; // n = digit[0][0] * 4 + digit[0][1] - digit[1][0] * 4 - digit[1][1]; // int record[n][2]; // start = clock(); while (1) { n = digit[0][0] * 8 + digit[0][1] - digit[1][0] * 8 - digit[1][1]; // printf("%dwei\n", digit[0][0] * 4 + digit[0][1]); digit[0][0] = 0; digit[0][1] = 0; if (n<0) { // printLink(L3); // printLink(L1_temp1); break; } else { k = nu1 / (nu2 + 1); cn_temp = pow(10, getdigit(nu1) - getdigit(nu2)); // printf("%d",cn_temp); if (nu1 / cn_temp > nu2) n = n + 1; else { if (n == 0) { // printLink(L3); // printLink(L1_temp1); break; } } if (getdigit(k) > n) k = k / pow(10, getdigit(k) - n); L_temp = getL_temp(k, n, L1_temp1, L2, &L3); // printLink(L_temp); p = L_temp->next; q = L3->next; digit[0][1] = getdigit(p->num); Destory(L_subrev); Destory(L3_temp); nu1 = 0; while (p->next) { L_subrev = CreateListHead(L_subrev, "00", p->num, 0); // nu1 = p->num; digit[0][0] = digit[0][0] + 1; p = p->next; } L_subrev = CreateListHead(L_subrev, "00", p->num, 0); while (q) { L3_temp = CreateListHead(L3_temp, "00", q->num, 0); q = q->next; } L3 = L3_temp; p = L_temp->next; nu1 = p->num; if (p->next) { p = p->next; nu1 = 100000000 * nu1 + p->num; } // Destory(L1_temp1); // Destory(L1_temp); L1_temp1 = L_subrev; } // Destory(L_subrev); } // end = clock(); L_zc = sub(L1_temp1, L2, L_zc); p = L_zc->next; if (p->num == 0 && p->next == NULL) { p->num = 1; InitList(&L3_adj); L3_adj = add(L3, L_zc, L3_adj); printLink(L3_adj); printf("0\n"); } else { p = L3->next; while (p) { r = p; L_re = CreateListHead(L_re, "00", p->num, 0); p = p->next; free(r); } printLink(L_re); Destory(L_re); p = L1_temp1->next; while (p) { r = p; L_re = CreateListHead(L_re, "00", p->num, 0); p = p->next; free(r); } printLink(L_re); } // printf("%d s", (end - start) / CLOCKS_PER_SEC); } } return 0; }
//division LinkList getL_temp(long long k, long long n, LinkList L1, LinkList L2, LinkList *L3) { LinkList L, L_mul, L_sub, L3_temp, p0; Node *p; InitList(&L); InitList(&L_mul); InitList(&L_sub); InitList(&L3_temp); long long i, nu, n_temp = 0, l1, l2, l1_l3, l2_l3, l3; int flags_err; l3 = getdigit(k); if (l3 != n) { l1 = n % 8; l2 = n / 8; l1_l3 = l3 % 8; l2_l3 = l3 / 8; if (l1 >= l1_l3) { k = k*pow(10, l1 - l1_l3); n_temp = l2 - l2_l3; } if (l1<l1_l3) { while (getdigit(k) + l1 + 8 - l1_l3>9) { k = k * 6 / 7; // k = 2*pow(10, getdigit(k) - 1); } k = k*pow(10, l1 + 8 - l1_l3); n_temp = l2 - l2_l3 - 1; } } p = L; // printf("%d\n",k); if (k == 1919) { flags_err = 0; } while (k) { nu = k % 100000000; // L=CreateListHead(L, "00", nu, 0); p0 = (LinkList)malloc(sizeof(Node)); p0->next = p->next; p->next = p0; strcpy(p0->data, "00"); p0->num = nu; p0->en = 0; k = k / 100000000; p = p->next; } /* k = k*pow(10, n - l3); while (k) { nu = k % 10000; // L = CreateListHead(L, "00", nu, 0); k = k / 10000; } */ L_mul = mul(L, L2, L_mul); while (n_temp) { L_mul = CreateListHead(L_mul, "00", 0, 0); L = CreateListHead(L, "00", 0, 0); n_temp = n_temp - 1; } L_sub = sub(L1, L_mul, L_sub); *L3 = add(*L3, L, L3_temp); // printLink(L1); // printLink(L_mul); // printLink(L_sub); return L_sub; }
int my_double2str(char *buf, size_t bufsize, double realvalue) { int precision = -1; char *bufpt; char prefix; char xtype = xGENERIC; int idx, exp, e2; double rounder; char flag_exp; char flag_rtz; char flag_dp; char flag_alternateform = 0; char flag_altform2 = 0; int nsd; if(bufsize < 8) return -1; if( precision<0 ) precision = 20; /* Set default precision */ if( precision>bufsize/2-10 ) precision = bufsize/2-10; if( realvalue<0.0 ){ realvalue = -realvalue; prefix = '-'; }else{ prefix = 0; } if( xtype==xGENERIC && precision>0 ) precision--; for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} if( xtype==xFLOAT ) realvalue += rounder; /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; if(isnan(realvalue)) { strcpy(buf, "NaN"); return 0; } if( realvalue>0.0 ){ while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } if( exp>350 ){ if( prefix=='-' ){ strcpy(buf, "-Inf"); }else{ strcpy(buf, "Inf"); } return 0; } } bufpt = buf; /* ** If the field type is etGENERIC, then convert to either etEXP ** or etFLOAT, as appropriate. */ flag_exp = xtype==xEXP; if( xtype != xFLOAT ){ realvalue += rounder; if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } } if( xtype==xGENERIC ){ flag_rtz = !flag_alternateform; if( exp<-4 || exp>precision ){ xtype = xEXP; }else{ precision = precision - exp; xtype = xFLOAT; } }else{ flag_rtz = 0; } if( xtype==xEXP ){ e2 = 0; }else{ e2 = exp; } nsd = 0; flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; /* The sign in front of the number */ if( prefix ){ *(bufpt++) = prefix; } /* Digits prior to the decimal point */ if( e2<0 ){ *(bufpt++) = '0'; }else{ for(; e2>=0; e2--){ *(bufpt++) = getdigit(&realvalue,&nsd); } } /* The decimal point */ if( flag_dp ){ *(bufpt++) = '.'; } /* "0" digits after the decimal point but before the first ** significant digit of the number */ for(e2++; e2<0; precision--, e2++){ assert( precision>0 ); *(bufpt++) = '0'; } /* Significant digits after the decimal point */ while( (precision--)>0 ){ *(bufpt++) = getdigit(&realvalue,&nsd); } /* Remove trailing zeros and the "." if no digits follow the "." */ if( flag_rtz && flag_dp ){ while( bufpt[-1]=='0' ) *(--bufpt) = 0; assert( bufpt>buf ); if( bufpt[-1]=='.' ){ if( flag_altform2 ){ *(bufpt++) = '0'; }else{ *(--bufpt) = 0; } } } /* Add the "eNNN" suffix */ if( flag_exp || xtype==xEXP ){ *(bufpt++) = 'e'; if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; }else{ *(bufpt++) = '+'; } if( exp>=100 ){ *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ exp %= 100; } *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ } *bufpt = 0; return 0; }
static void putstring_with_esc(char *str) { char *p; while(*str) { p = str; for(;;) { if((unsigned char)*p >= 0x20){ p++; continue; } if(p-str > 0){ WrdWndPutStringN(str,p-str,TRUE); str = p; break; } if(*p == '\0') break; if(*p == '\n') { esc_nextline(); str = p + 1; break; } if(*p == '\r' && *(p+1) == '\n') { esc_nextline(); str = p + 2; break; } if(*p == '\t') { WrdWndPutStringN ( " ", 8, TRUE ); str = p + 1; break; } if(*p != 0x1b){ str = p + 1; break; } if(*p == 0x1b){ int res, n[1024], n_max = 0; char *oldp = p; p++; if(*p == '['){ p++; for(;;){ res = getdigit(p,&(n[n_max+1])); if(res>0){ n_max++; p += res; } if(*p != ';') break; else p++; } } else if(*p == 'D'){ esc_index(); p++; str = p; break; } else if(*p == 'E'){ esc_nextline(); p++; str = p; break; } else if(*p == 'M'){ esc_reverseindex(); p++; str = p; break; } else if(*p == '*'){ esc_clearscreen(); p++; str = p; break; } else { p = oldp; if(p-str > 0){ WrdWndPutStringN(str,p-str,TRUE); str = p; break; } } if(n_max == 2 && (*p == 'H' || *p == 'f')){ esc_directcursoraddressing(n[2],n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'A') || (n_max == 0 && *p == 'A')){ if(n_max == 0) n[1] = 1; esc_cursorup(n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'B') || (n_max == 0 && *p == 'B')){ if(n_max == 0) n[1] = 1; esc_cursordown(n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'C') || (n_max == 0 && *p == 'C')){ if(n_max == 0) n[1] = 1; esc_cursorforward(n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'D') || (n_max == 0 && *p == 'D')){ if(n_max == 0) n[1] = 1; esc_cursorbackward(n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'J') || (n_max == 0 && *p == 'J')){ if(n_max == 0 || n[1] == 0) esc_clearfromcursortoendofscreen(); else if(n[1] == 1) esc_clearfrombeginningofscreentocursor(); else if(n[1] == 2) esc_clearscreen(); p++; str = p; break; } if((n_max == 1 && *p == 'K') || (n_max == 0 && *p == 'K')){ if(n_max == 0 || n[1] == 0) esc_clearfromcursortoendofline(); else if(n[1] == 1) esc_clearfrombeginningoflinetocursor(); else if(n[1] == 2) esc_clearentirelinecontainingcursor(); p++; str = p; break; } if((n_max == 1 && *p == 'M') || (n_max == 0 && *p == 'M')){ if(n_max == 0) n[1] = 1; esc_deleteline(n[1]); p++; str = p; break; } if((n_max == 1 && *p == 'L') || (n_max == 0 && *p == 'L')){ if(n_max == 0) n[1] = 1; esc_insertline(n[1]); p++; str = p; break; } if(n_max == 0 && *p == 's'){ esc_savecursorposition(); p++; str = p; break; } if(n_max == 0 && *p == 'u'){ esc_setcursorposition(); p++; str = p; break; } if(!strncmp(p,">5l",3)){ esc_enablecursordisplay(); p += 3; str = p; break; } if(!strncmp(p,">5h",3)){ esc_disablecursordisplay(); p += 3; str = p; break; } if(!strncmp(p,">1h",3)){ /* Enabel bottom line */ p += 3; str = p; break; } if(!strncmp(p,">1l",3)){ /* Disabel bottom line */ p += 3; str = p; break; } if(!strncmp(p,">3h",3)){ /* Select 31 line mode */ p += 3; str = p; break; } if(!strncmp(p,">3l",3)){ /* Select 25 line mode */ p += 3; str = p; break; } if(*p == 'm'){ int i; for(i=1;i<=n_max;i++) esc_characterattribute(n[i]); p++; str = p; break; } p = oldp; WrdWndPutStringN(p,1,TRUE); p++; str = p; break; } } } }
/* ** The root program. All variations call this core. ** ** INPUTS: ** func This is a pointer to a function taking three arguments ** 1. A pointer to the list of characters to be output ** (Note, this list is NOT null terminated.) ** 2. An integer number of characters to be output. ** (Note: This number might be zero.) ** 3. A pointer to anything. Same as the "arg" parameter. ** ** arg This is the pointer to anything which will be passed as the ** third argument to "func". Use it for whatever you like. ** ** fmt This is the format string, as in the usual printf. ** ** ap This is a pointer to a list of arguments. Same as in ** vfprintf. ** ** OUTPUTS: ** The return value is the total number of characters sent to ** the function "func". Returns EOF on a error. ** ** Note that the order in which automatic variables are declared below ** seems to make a big difference in determining how fast this beast ** will run. */ static Int32 vxprintf(void (*func)(char*,Int32,void*), void *arg, const char *format, va_list ap){ register const char *fmt; /* The format string. */ register Int32 c; /* Next character in the format string */ register char *bufpt; /* Pointer to the conversion buffer */ register Int32 precision; /* Precision of the current field */ register Int32 length; /* Length of the field */ register Int32 idx; /* A general purpose loop counter */ Int32 count; /* Total number of characters output */ Int32 width; /* Width of the current field */ Int32 flag_leftjustify; /* True if "-" flag is present */ Int32 flag_plussign; /* True if "+" flag is present */ Int32 flag_blanksign; /* True if " " flag is present */ Int32 flag_alternateform; /* True if "#" flag is present */ Int32 flag_zeropad; /* True if field width constant starts with zero */ UInt32 longvalue; /* Value for integer types */ Float32 realvalue; /* Value for real types */ const info *infop; /* Pointer to the appropriate info structure */ char buf[BUFSIZE]; /* Conversion buffer */ char prefix; /* Prefix character. "+" or "-" or " " or 0. */ Int32 errorflag = 0; /* True if an error is encountered */ enum e_type xtype; /* Which of 3 different FP formats */ static char spaces[]=" "; #define SPACESIZE (sizeof(spaces)-1) Int32 exp; /* exponent of real numbers */ Float32 rounder; /* Used for rounding floating point values */ Int32 flag_dp; /* True if decimal point should be shown */ Int32 flag_rtz; /* True if trailing zeros should be removed */ fmt = format; /* Put in a register for speed */ count = length = 0; bufpt = 0; for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ register Int32 amt; bufpt = (char *)fmt; amt = 1; while( (c=*++fmt)!='%' && c!=0 ) amt++; (*func)(bufpt,amt,arg); count += amt; if( c==0 ) break; } if( (c=(*++fmt))==0 ){ errorflag = 1; (*func)("%",1,arg); count++; break; } /* Find out what flags are present */ flag_leftjustify = flag_plussign = flag_blanksign = flag_alternateform = flag_zeropad = 0; do{ switch( c ){ case '-': flag_leftjustify = 1; c = 0; break; case '+': flag_plussign = 1; c = 0; break; case ' ': flag_blanksign = 1; c = 0; break; case '#': flag_alternateform = 1; c = 0; break; case '0': flag_zeropad = 1; c = 0; break; default: break; } }while( c==0 && (c=*++fmt)!=0 ); /* Get the field width */ width = 0; if( c=='*' ){ width = va_arg(ap,Int32); if( width<0 ){ flag_leftjustify = 1; width = -width; } c = *++fmt; }else{ while( xisdigit(c) ){ width = width*10 + c - '0'; c = *++fmt; } } /* Get the precision */ if( c=='.' ){ precision = 0; c = *++fmt; if( c=='*' ){ precision = va_arg(ap,Int32); if( precision<0 ) precision = -precision; c = *++fmt; }else{ while( xisdigit(c) ){ precision = precision*10 + c - '0'; c = *++fmt; } } /* Limit the precision to prevent overflowing buf[] during conversion */ if( precision>BUFSIZE-40 ) precision = BUFSIZE-40; }else{ precision = -1; } /* Fetch the info entry for the field */ infop = 0; for(idx=0; idx<NINFO; idx++){ if( c==fmtinfo[idx].fmttype ){ infop = &fmtinfo[idx]; break; } } /* No info entry found. it must be an error. Check it out. */ if( infop==0 ){ xtype = IOERROR; }else{ xtype = infop->type; } /* ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. ** flag_plussign TRUE if a '+' is present. ** flag_leftjustify TRUE if a '-' is present or if the ** field width was negative. ** flag_zeropad TRUE if the width began with 0. ** flag_blanksign TRUE if a ' ' is present. ** width The specified field width. This is ** always non-negative. Zero is the default. ** precision The specified precision. The default ** is -1. ** xtype The class of the conversion. ** infop Pointer to the appropriate info struct. */ switch( xtype ){ case RADIX: longvalue = va_arg(ap,Int32); /* More sensible: turn off the prefix for octal (to prevent "00"), ** but leave the prefix for hex. */ if( longvalue==0 && infop->base==8 ) flag_alternateform = 0; if( infop->flag_signed ){ if( *(Int32*)&longvalue<0 ){ longvalue = -*(Int32*)&longvalue; prefix = '-'; }else if( flag_plussign ) prefix = '+'; else if( flag_blanksign ) prefix = ' '; else prefix = 0; }else prefix = 0; if( flag_zeropad && precision<width-(prefix!=0) ){ precision = width-(prefix!=0); } { register char *cset; /* Use registers for speed */ register Int32 base; cset = infop->charset; base = infop->base; bufpt = &buf[BUFSIZE]; do{ /* Convert to ascii */ *(--bufpt) = cset[longvalue%base]; longvalue = longvalue/base; }while( longvalue>0 ); } length = (Int32)&buf[BUFSIZE]-(Int32)bufpt; for(idx=precision-length; idx>0; idx--){ *(--bufpt) = '0'; /* Zero pad */ } if( prefix ) *(--bufpt) = prefix; /* Add sign */ if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ char *pre, x; pre = infop->prefix; if( *bufpt!=pre[0] ){ for(pre=infop->prefix; (x=*pre)!=0; pre++) *(--bufpt) = x; } } length = (Int32)&buf[BUFSIZE]-(Int32)bufpt; break; case FLOAT: case EXP: case GENERIC: realvalue = va_arg(ap,Float64); if( precision<0 ) precision = 4; /* Set default precision */ if( precision>BUFSIZE-10 ) precision = BUFSIZE-10; if( realvalue<0.0 ){ realvalue = -realvalue; prefix = '-'; }else{ if( flag_plussign ) prefix = '+'; else if( flag_blanksign ) prefix = ' '; else prefix = 0; } if( infop->type==GENERIC && precision>0 ) precision--; for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1); if( infop->type==FLOAT ) realvalue += rounder; /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; while( realvalue>=1e8 ){ realvalue *= 1e-8; exp+=8; } while( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } bufpt = buf; /* ** If the field type is GENERIC, then convert to either EXP ** or FLOAT, as appropriate. */ if( xtype==GENERIC ){ flag_rtz = !flag_alternateform; if( exp<-4 || exp>precision ){ xtype = EXP; }else{ precision = precision - exp; realvalue += rounder; xtype = FLOAT; } } /* ** The "exp+precision" test causes output to be of type EXP if ** the precision is too large to fit in buf[]. */ if( xtype==FLOAT && exp+precision<BUFSIZE-30 ){ flag_rtz = 0; flag_dp = (precision>0 || flag_alternateform); if( prefix ) *(bufpt++) = prefix; /* Sign */ if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue); if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ for(exp++; exp<0 && precision>0; precision--, exp++){ *(bufpt++) = '0'; } while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue); *(bufpt--) = 0; /* Null terminate */ if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; } bufpt++; /* point to next free slot */ }else{ /* EXP */ flag_rtz = 0; flag_dp = (precision>0 || flag_alternateform); realvalue += rounder; if( prefix ) *(bufpt++) = prefix; /* Sign */ *(bufpt++) = getdigit(&realvalue); /* First digit */ if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue); bufpt--; /* point to last digit */ if( flag_rtz && flag_dp ){ /* Remove tail zeros */ while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; } bufpt++; /* point to next free slot */ *(bufpt++) = infop->charset[0]; if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ else { *(bufpt++) = '+'; } if( exp>=100 ) *(bufpt++) = (exp/100)+'0'; /* 100's digit */ *(bufpt++) = exp/10+'0'; /* 10's digit */ *(bufpt++) = exp%10+'0'; /* 1's digit */ } /* The converted number is in buf[] and zero terminated. Output it. ** Note that the number is in the usual order, not reversed as with ** integer conversions. */ length = (Int32)bufpt-(Int32)buf; bufpt = buf; break; case SIZE: *(va_arg(ap,Int32*)) = count; length = width = 0; break; case PERCENT: buf[0] = '%'; bufpt = buf; length = 1; break; case CHARLIT: case CHAR: c = buf[0] = (xtype==CHAR ? va_arg(ap,Int32) : *++fmt); if( precision>=0 ){ for(idx=1; idx<precision; idx++) buf[idx] = c; length = precision; }else{ length =1; } bufpt = buf; break; case STRING: bufpt = va_arg(ap,char*); if( bufpt==0 ) bufpt = "(null)"; length = xstrlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; case IOERROR: buf[0] = '%'; buf[1] = c; errorflag = 0; idx = 1+(c!=0); (*func)("%",idx,arg); count += idx; if( c==0 ) fmt--; break; }/* End switch over the format type */ /* ** The text of the conversion is pointed to by "bufpt" and is ** "length" characters long. The field width is "width". Do ** the output. */ if( !flag_leftjustify ){ register Int32 nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=SPACESIZE ){ (*func)(spaces,SPACESIZE,arg); nspace -= SPACESIZE; } if( nspace>0 ) (*func)(spaces,nspace,arg); } } if( length>0 ){ (*func)(bufpt,length,arg); count += length; } if( flag_leftjustify ){ register Int32 nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=SPACESIZE ){ (*func)(spaces,SPACESIZE,arg); nspace -= SPACESIZE; } if( nspace>0 ) (*func)(spaces,nspace,arg); } } }/* End for loop over the format string */ return errorflag ? EOF : count; } /* End of function */