int _fmtcpy(Fmt *f, void *vm, int n, int sz) { Rune *rt, *rs, r; char *t, *s, *m, *me; ulong fl; int nc, w; m = vm; me = m + sz; w = f->width; fl = f->flags; if((fl & FmtPrec) && n > f->prec) n = f->prec; if(f->runes){ if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0) return -1; rt = f->to; rs = f->stop; for(nc = n; nc > 0; nc--){ r = *(uchar*)m; if(r < Runeself) m++; else if((me - m) >= UTFmax || fullrune(m, me-m)) m += chartorune(&r, m); else break; FMTRCHAR(f, rt, rs, r); } f->nfmt += rt - (Rune *)f->to; f->to = rt; if(m < me) return -1; if(fl & FmtLeft && _rfmtpad(f, w - n) < 0) return -1; }else{ if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0) return -1; t = f->to; s = f->stop; for(nc = n; nc > 0; nc--){ r = *(uchar*)m; if(r < Runeself) m++; else if((me - m) >= UTFmax || fullrune(m, me-m)) m += chartorune(&r, m); else break; FMTRUNE(f, t, s, r); } f->nfmt += t - (char *)f->to; f->to = t; if(fl & FmtLeft && _fmtpad(f, w - n) < 0) return -1; } return 0; }
/* * Do p and q point at equal utf codes */ int equtf(uint8_t *p, uint8_t *q) { Rune pr, qr; if(*p!=*q) return 0; chartorune(&pr, (char*)p); chartorune(&qr, (char*)q); return pr == qr; }
static int strncmpcanon(const char *a, const char *b, int n) { Rune ra, rb; int c; while (n--) { if (!*a) return -1; if (!*b) return 1; a += chartorune(&ra, a); b += chartorune(&rb, b); c = canon(ra) - canon(rb); if (c) return c; } return 0; }
Point memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, char *cs) { int w, width; uchar *s; Rune c; Fontchar *i; s = (uchar*)cs; for(; (c=*s); p.x+=width, cp.x+=width){ width = 0; if(c < Runeself) s++; else{ w = chartorune(&c, (char*)s); if(w == 0){ s++; continue; } s += w; } if(c >= f->n) continue; // i = f->info+c; i = &(f->info[c]); width = i->width; memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom), color, cp, f->bits, Pt(i->x, i->top), SoverD); } return p; }
V7_PRIVATE enum v7_err Str_search(struct v7_c_func_arg *cfa) { #define v7 (cfa->v7) /* Needed for TRY() macro below */ struct v7_val *arg = cfa->args[0]; struct Resub sub; int shift = -1, utf_shift = -1; if (cfa->num_args > 0) { TRY(check_str_re_conv(v7, &arg, 1)); TRY(regex_check_prog(arg)); if (!re_exec(arg->v.str.prog, arg->fl.fl, cfa->this_obj->v.str.buf, &sub)) shift = sub.sub[0].start - cfa->this_obj->v.str.buf; } if (shift > 0) { /* calc shift for UTF-8 */ Rune rune; const char *str = cfa->this_obj->v.str.buf; utf_shift = 0; do { str += chartorune(&rune, str); utf_shift++; } while (str - cfa->this_obj->v.str.buf < shift); } v7_push_number(v7, utf_shift); return V7_OK; #undef v7 }
int getchr(void) { char s[UTFmax]; int i; Rune r; if(lastc = peekc) { peekc = 0; return lastc; } if(globp) { if((lastc=*globp++) != 0) return lastc; globp = 0; return EOF; } for(i=0;;) { if(read(0, s+i, 1) <= 0) return lastc = EOF; i++; if(fullrune(s, i)) break; } chartorune(&r, s); lastc = r; return lastc; }
/* From Plan 9 to Unix */ char* exportname(char* name) { Rune r; int nr; char *uxname; char *up; if (name == 0 || (utfrune(name, altspc) == 0 && utfrune(name,altlparen) == 0 && utfrune(name,altrparen) == 0 && utfrune(name,altamp) == 0 && utfrune(name,altquote) == 0)) return name; up = uxname = emalloc(strlen(name) + 1); names[nnames++] = uxname; while(*name != 0){ nr = chartorune(&r, name); if (r == altspc) r = ' '; if (r == altlparen) r = '('; if (r == altrparen) r = ')'; if (r == altamp) r = '&'; if (r == altquote) r = '\''; up += runetochar(up, &r); name += nr; } *up = 0; return uxname; }
char* utfrune(char *s, long c) { long c1; Rune r; int n; if(c < Runesync) /* not part of utf sequence */ return strchr(s, c); for(;;) { c1 = *(uchar*)s; if(c1 < Runeself) { /* one byte rune */ if(c1 == 0) return 0; if(c1 == c) return s; s++; continue; } n = chartorune(&r, s); if(r == c) return s; s += n; } return 0; }
static void buildmap(Biobuf *fp) /* map goes from char name to value to print via *string() */ { uchar *p, *line, ch[100]; int val; Rune r; curmap++; if(curmap >= NMAP) { fprint(2, "proof: out of char maps; recompile\n"); exits("charmap"); } while ((line = Brdline(fp, '\n'))!= 0) { if (line[0] == '\n') return; line[Blinelen(fp)-1] = 0; scanstr((char *) line, (char *) ch, (char **) &p); if (ch[0] == '\0') { fprint(2, "bad map file line '%s'\n", (char*)line); continue; } val = strtol((char *) p, 0, 10); dprint(2, "buildmap %s (%x %x) %s %d\n", (char*)ch, ch[0], ch[1], (char*)p, val); chartorune(&r, (char*)ch); if(utflen((char*)ch)==1 && r<QUICK) charmap[curmap].quick[r] = val; else addmap(curmap, strdup((char *) ch), val); /* put somewhere else */ } }
long Bgetrune(Biobuf *bp) { int c, i; Rune rune; char str[UTFmax]; c = Bgetc(bp); if(c < Runeself) { /* one char */ bp->runesize = 1; return c; } str[0] = c; for(i=1;;) { c = Bgetc(bp); if(c < 0) return c; str[i++] = c; if(fullrune(str, i)) { bp->runesize = chartorune(&rune, str); while(i > bp->runesize) { Bungetc(bp); i--; } return rune; } } }
/* public helper routine: fmt out a null terminated string already in hand */ int fmtstrcpy(Fmt *f, char *s) { int i, j; if(!s) return __fmtcpy(f, "<nil>", 5, 5); /* if precision is specified, make sure we don't wander off the end */ if(f->flags & FmtPrec){ #ifdef PLAN9PORT Rune r; i = 0; for(j=0; j<f->prec && s[i]; j++) i += chartorune(&r, s+i); #else /* ANSI requires precision in bytes, not Runes */ for(i=0; i<f->prec; i++) if(s[i] == 0) break; j = utfnlen(s, i); /* won't print partial at end */ #endif return __fmtcpy(f, s, j, i); } return __fmtcpy(f, s, utflen(s), strlen(s)); }
void fmtr(char *f) { int i, w, cw; Rune r; static int nstart; USED(f); if(nstart) xprint("%*c", 3*nstart, ' '); for(i=nstart; i<ndata; ) if(data[i] < Runeself) onefmtc(data[i++]); else{ w = chartorune(&r, (char *)data+i); if(w == 1 || i + w>nread) onefmtc(data[i++]); else{ cw = w; if(i + w>ndata) cw = ndata - i; xprint(rfmt[0][0], r); xprint("%*c", 3*cw-3, ' '); i += w; } } if(i > ndata) nstart = i - ndata; else nstart = 0; }
/* * classify by initial contents of file */ HContents dataclass(HConnect *hc, char *buf, int n) { HContents conts; Rune r; int c, m; for(; n > 0; n -= m){ c = *buf; if(c < Runeself){ if(c < 32 && c != '\n' && c != '\r' && c != '\t' && c != '\v'){ conts.type = nil; conts.encoding = nil; return conts; } m = 1; }else{ m = chartorune(&r, buf); if(r == Runeerror){ conts.type = nil; conts.encoding = nil; return conts; } } buf += m; } conts.type = hmkcontent(hc, "text", "plain", nil); conts.encoding = nil; return conts; }
static void termscreenputs(char *s, int n) { int i, locked; Rune r; char buf[4]; lock(&screenlock); locked = drawcanqlock(); while(n > 0){ i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; screenputc(buf); } if(locked) drawqunlock(); screenflush(); unlock(&screenlock); }
static void pstr(const char *s) { static const char *HEX = "0123456789ABCDEF"; Rune c; pc('"'); while (*s) { s += chartorune(&c, s); switch (c) { case '"': ps("\\\""); break; case '\\': ps("\\\\"); break; case '\b': ps("\\b"); break; case '\f': ps("\\f"); break; case '\n': ps("\\n"); break; case '\r': ps("\\r"); break; case '\t': ps("\\t"); break; default: if (c < ' ' || c > 127) { ps("\\u"); pc(HEX[(c>>12)&15]); pc(HEX[(c>>8)&15]); pc(HEX[(c>>4)&15]); pc(HEX[c&15]); } else { pc(c); break; } }
int httpfmt(Fmt *f) { char buf[HMaxWord*2]; Rune r; char *t, *s; Htmlesc *l; s = va_arg(f->args, char*); for(t = buf; t < buf + sizeof(buf) - 8; ){ s += chartorune(&r, s); if(r == 0) break; for(l = htmlesc; l->name != nil; l++) if(l->value == r) break; if(l->name != nil){ strcpy(t, l->name); t += strlen(t); }else *t++ = r; } *t = 0; return fmtstrcpy(f, buf); }
void specialout(char *stoken) { Rune rune; chartorune(&rune, stoken); glyphout(rune, stoken, TRUE); }
/* * extract a variable name */ static Bufblock* varname(char **s) { Bufblock *b; char *cp; Rune r; int n; b = newbuf(); cp = *s; for(;;){ n = chartorune(&r, cp); if (!WORDCHR(r)) break; rinsert(b, r); cp += n; } if (b->current == b->start){ SYNERR(-1); fprint(2, "missing variable name <%s>\n", *s); freebuf(b); return 0; } *s = cp; insert(b, 0); return b; }
void cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls) { uchar *q; Rune *s; int j, w; /* * Always guaranteed that n bytes may be interpreted * without worrying about partial runes. This may mean * reading up to UTFmax-1 more bytes than n; the caller * knows this. If n is a firm limit, the caller should * set p[n] = 0. */ q = (uchar*)p; s = r; for(j=0; j<n; j+=w){ if(*q < Runeself){ w = 1; *s = *q++; }else{ w = chartorune(s, (char*)q); q += w; } if(*s) s++; else if(nulls) *nulls = TRUE; } *nb = (char*)q-p; *nr = s-r; }
static void ekeyslave(int fd) { Rune r; char t[1+UTFmax], k[10]; int kr, kn, w; if(eforkslave(Ekeyboard) < MAXSLAVE) return; kn = 0; t[0] = Skeyboard; for(;;){ while(!fullrune(k, kn)){ kr = read(fd, k+kn, sizeof k - kn); if(kr <= 0) goto breakout; kn += kr; } w = chartorune(&r, k); kn -= w; memmove(t+1, k, w); memmove(k, &k[w], kn); if(write(epipe[1], t, sizeof(t)) != sizeof(t)) break; } breakout:; t[0] = MAXSLAVE; write(epipe[1], t, 1); _exits(0); }
char* utfrrune(char *s, long c) { long c1; Rune r; char *s1; if(c < Runesync) /* not part of utf sequence */ return strrchr(s, c); s1 = 0; for(;;) { c1 = *(uchar*)s; if(c1 < Runeself) { /* one byte rune */ if(c1 == 0) return s1; if(c1 == c) s1 = s; s++; continue; } c1 = chartorune(&r, s); if(r == c) s1 = s; s += c1; } }
static void myscreenputs(char *s, int n) { int i; Rune r; char buf[4]; if(!islo()) { /* don't deadlock trying to print in interrupt */ if(!canlock(&screenlock)) return; } else lock(&screenlock); while(n > 0){ i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; screenputc(buf); } unlock(&screenlock); }
int smbucs2put(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string) { uchar *p = buf + n; int l; int align; align = (flags & SMB_STRING_UNALIGNED) == 0 && (n & 1) != 0; l = string ? utflen(string) * 2 : 0; if (n + l + ((flags & SMB_STRING_UNTERMINATED) ? 0 : 2) + align > maxlen) return 0; if (align) *p++ = 0; while (string && *string) { Rune r; int i; i = chartorune(&r, string); if (flags & SMB_STRING_CONVERT_MASK) r = smbruneconvert(r, flags); smbhnputs(p, r); p += 2; string += i; } if ((flags & SMB_STRING_UNTERMINATED) == 0) { smbhnputs(p, 0); p += 2; } assert(p <= buf + maxlen); return p - (buf + n); }
static int fromsnarf(Win *w, int p0) { int fd, rc; char *buf, *p; Rune *rbuf, *r; int nc, end; fd = open("/dev/snarf", OREAD); if(fd < 0){ cmdprint("fromsnarf: %r"); return -1; } buf = nil; nc = 0; for(;;){ buf = realloc(buf, nc + 4096); rc = readn(fd, buf + nc, nc + 4096); if(rc <= 0) break; nc += rc; if(rc < 4096) break; } close(fd); rbuf = emalloc(sizeof(Rune) * nc); r = rbuf; for(p = buf; p < buf + nc; r++) p += chartorune(r, p); end = p0 == w->nrunes; cmdinsert(w, rbuf, r - rbuf, p0); if(end && r > rbuf && r[-1] == '\n') cmdline(w); return 0; }
/* From Unix to Plan 9 */ char* importname(char* name) { Rune r; int nr; char *up; char *p9name; if (name == 0 || (strchr(name, ' ') == 0 && strchr(name, '(') == 0 && strchr(name, ')') == 0 && strchr(name, '&') == 0 && strchr(name, '\'')== 0)) return name; p9name = emalloc(strlen(name) * 3 + 1); // worst case: all blanks + 0 up = p9name; names[nnames++] = p9name; while (*name != 0){ nr = chartorune(&r, name); if (r == ' ') r = altspc; if (r == '(') r = altlparen; if (r == ')') r = altrparen; if (r == '&') r = altamp; if (r == '\'') r = altquote; up += runetochar(up, &r); name += nr; } *up = 0; return p9name; }
int _stringnwidth(Font *f, char *s, Rune *r, int len) { int wid, twid, n, max, l; char *name; enum { Max = 64 }; ushort cbuf[Max]; Rune rune, **rptr; char *subfontname, **sptr; Font *def; Subfont *sf; if(s == nil){ s = ""; sptr = nil; }else sptr = &s; if(r == nil){ r = L""; rptr = nil; }else rptr = &r; sf = nil; twid = 0; while(len>0 && (*s || *r)){ max = Max; if(len < max) max = len; n = 0; while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ if(++n > 10){ if(*r) rune = *r; else chartorune(&rune, s); if(f->name != nil) name = f->name; else name = "unnamed font"; fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); return twid; } if(subfontname){ freesubfont(sf); if((sf=_getsubfont(f->display, subfontname)) == 0){ def = f->display->defaultfont; if(def && f!=def) f = def; else break; } } } agefont(f); twid += wid; len -= l; } freesubfont(sf); return twid; }
int getfields(char *str, char **args, int max, int mflag, char *set) { Rune r; int nr, intok, narg; if(max <= 0) return 0; narg = 0; args[narg] = str; if(!mflag) narg++; intok = 0; for(;; str += nr) { nr = chartorune(&r, str); if(r == 0) break; if(utfrune(set, r)) { if(narg >= max) break; *str = 0; intok = 0; args[narg] = str + nr; if(!mflag) narg++; } else { if(!intok && mflag) narg++; intok = 1; } } return narg; }
Point memsubfontwidth(Memsubfont *f, char *cs) { Rune c; Point p; uchar *s; Fontchar *i; int w, width; p = Pt(0, f->height); s = (uchar*)cs; for(; (c=*s); p.x+=width){ width = 0; if(c < Runeself) s++; else{ w = chartorune(&c, (char*)s); if(w == 0){ s++; continue; } s += w; } if(c >= f->n) continue; i = f->info+c; width = i->width; } return p; }
int tktindrune(TkTindex *ix) { int ans; Rune r; switch(ix->item->kind) { case TkTascii: ans = ix->item->istring[ix->pos]; break; case TkTrune: chartorune(&r, ix->item->istring + tktutfpos(ix->item->istring, ix->pos)); ans = r; break; case TkTtab: ans = '\t'; break; case TkTnewline: ans = '\n'; break; default: /* only care that it isn't a word char */ ans = 0x80; } return ans; }
int _frcanfit(Frame *f, Point pt, Frbox *b) { int left, w, nr; uchar *p; Rune r; left = f->r.max.x-pt.x; if(b->nrune < 0) return b->minwid <= left; if(left >= b->wid) return b->nrune; for(nr=0,p=b->ptr; *p; p+=w,nr++){ r = *p; if(r < Runeself) w = 1; else w = chartorune(&r, (char*)p); left -= stringnwidth(f->font, (char*)p, 1); if(left < 0) return nr; } drawerror(f->display, "_frcanfit can't"); return 0; }