U8 *Tabs2Spaces(U8 *src) {//MAlloc str with tabs to spaces. I64 ch, i, j, l = StrLen(src) << 1 + 2, col = 0; U8 *dst = MAlloc(l), *tmp; while (ch = *src++) { if (ch == '\t') { j = (col + 8) & ~7; for (i = col; i < j; i++) { dst[i] = CH_SPACE; if (i >= l - 2) { tmp = MAlloc(l << 1); MemCopy(tmp, dst, i + 1); Free(dst); l <<= 1; dst = tmp; } } col = j; } else { dst[col] = ch; if (col >= l - 2) { tmp = MAlloc(l << 1); MemCopy(tmp, dst, col + 1); Free(dst); l <<= 1; dst = tmp; } col++; } } dst[col] = 0; return dst; } U8 *ScaleIndent(U8 *src, F64 indent_scale_factor) {//MAlloced str. 8*0.25-->2 or 8*2.0-->16 I64 ch, i, col = 0; U8 *dst, *dst2; while (ch = *src++) { if (ch == '\t') col = (col + 8) & -0x8; else if (ch == CH_SPACE) col++; else break; } src--; col = Round(indent_scale_factor * col); dst = dst2 = MAlloc(StrLen(src) + col / 8 + col & 7 + 1); for (i = col / 8; i > 0; i--) *dst2++ = '\t'; for (i = col & 7; i > 0; i--) *dst2++ = CH_SPACE; StrCopy(dst2, src); return dst; } U8 *MStrUtil(U8 *src, I64 flags, F64 indent_scale_factor=0) {//MAlloc StrUtil(). U8 *dst = StrNew(src), *dst2, *tmp; StrUtil(dst, flags); if (flags & SUF_T2S) { tmp = Tabs2Spaces(dst); Free(dst); dst = tmp; } if (flags & SUF_SCALE_INDENT) dst2 = ScaleIndent(dst, indent_scale_factor); else dst2 = StrNew(dst); //Shorten to just right size. Free(dst); return dst2; } U0 GetOutOfDollar() {//If a $ has been printed, print another $ to exit mode. CDoc *doc; if (IsRaw) { if (text.raw_flags & RAWF_IN_DOLLAR) '$'; } else { if (fp_doc_put && (doc = (*fp_doc_put)(Fs)) && doc->flags & DOCF_IN_DOLLAR) '$'; } } Bool YorN() {//Wait for user to answer Y or N. I64 ch; "(y or n)? "; while (TRUE) { ch = ToUpper(CharGet(, FALSE)); if (ch == 'Y') { "$PT$YES$FG$\n"; return TRUE; } else if (ch == 'N') { "$PT$NO$FG$\n"; return FALSE; } } } I64 PressAKey() {//Print "Press a key" and wait for non-zero ASCII key. "$BK,1$PRESS A KEY$BK,0$\n"; return CharGet(, FALSE); } Bool AreYouSure() {//Print "Are you sure" and waits for Y or N. "ARE YOU SURE "; return YorN; } U0 Help() {//Debug help or master help index file. if (IsDebugMode) DebugHelp; else PopUp("Type(\"::/Doc/HelpIndex.DD\");DocTop;View;"); } U0 FlagsScan(U8 *_dst_flags, U8 *list, U8 *src) {/*More than 64 flags. Flags passed by ref. Examples: FlagsScan(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags); I64 flags=0; FlagsScan(&flags,"R\0L\0Dump\0Scan\0","+Dump-R"); //Sets Bit#2, Clears Bit#0. */ I64 i; U8 *buf, *ptr; if (src) { buf = MAlloc(StrLen(src) + 1); while (*src) { while (*src && *src != '+' && *src != '-') src++; if (*src == '+') { src++; if (*src) { ptr = buf; while (*src && *src != '+' && *src != '-' && *src != CH_SPACE) *ptr++ = *src++; *ptr = 0; i = ListMatch(buf, list); if (i >= 0) LBts(_dst_flags, i); else { Free(buf); throw('ScanFlag'); } } } else if (*src == '-') { src++; if (*src) { ptr = buf; while (*src && *src != '+' && *src != '-' && *src != CH_SPACE) *ptr++ = *src++; *ptr = 0; i = ListMatch(buf, list); if (i >= 0) LBtr(_dst_flags, i); else { Free(buf); throw('ScanFlag'); } } } } Free(buf); } } U8 *FlagsStrPrint(U8 *dst, U8 *list, I64 flags, Bool print_all=FALSE, I64 print_all_length=0) {//Only 64 flags. Flags passed by value. print_all will print false flags using `-`. //Specify print_all_length (list length) if print_all is true. I64 i = 0; *dst = 0; if (!print_all_length || print_all_length > 64) print_all_length = 64; while (i < print_all_length) { if (Bt(&flags, i)) CatPrint(dst, "+%z", i, list); else if (print_all) CatPrint(dst, "-%z", i, list); i++; } return dst; }