bestline.c 133 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587
  1. /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
  2. │vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
  3. ╞══════════════════════════════════════════════════════════════════════════════╡
  4. │ │
  5. │ Bestline ── Library for interactive pseudoteletypewriter command │
  6. │ sessions using ANSI Standard X3.64 control sequences │
  7. │ │
  8. │ OVERVIEW │
  9. │ │
  10. │ Bestline is a fork of linenoise (a popular readline alternative) │
  11. │ that fixes its bugs and adds the missing features while reducing │
  12. │ binary footprint (surprisingly) by removing bloated dependencies │
  13. │ which means you can finally have a permissively-licensed command │
  14. │ prompt w/ a 30kb footprint that's nearly as good as gnu readline │
  15. │ │
  16. │ EXAMPLE │
  17. │ │
  18. │ main() { │
  19. │ char *line; │
  20. │ while ((line = bestlineWithHistory("IN> ", "foo"))) { │
  21. │ fputs("OUT> ", stdout); │
  22. │ fputs(line, stdout); │
  23. │ fputs("\n", stdout); │
  24. │ free(line); │
  25. │ } │
  26. │ } │
  27. │ │
  28. │ CHANGES │
  29. │ │
  30. │ - Remove bell │
  31. │ - Add kill ring │
  32. │ - Fix flickering │
  33. │ - Add UTF-8 editing │
  34. │ - Add CTRL-R search │
  35. │ - Support unlimited lines │
  36. │ - Add parentheses awareness │
  37. │ - React to terminal resizing │
  38. │ - Don't generate .data section │
  39. │ - Support terminal flow control │
  40. │ - Make history loading 10x faster │
  41. │ - Make multiline mode the only mode │
  42. │ - Accommodate O_NONBLOCK file descriptors │
  43. │ - Restore raw mode on process foregrounding │
  44. │ - Make source code compatible with C++ compilers │
  45. │ - Fix corruption issues by using generalized parsing │
  46. │ - Implement nearly all GNU readline editing shortcuts │
  47. │ - Remove heavyweight dependencies like printf/sprintf │
  48. │ - Remove ISIG→^C→EAGAIN hack and use ephemeral handlers │
  49. │ - Support running on Windows in MinTTY or CMD.EXE on Win10+ │
  50. │ - Support diacratics, русский, Ελληνικά, 中国人, 日本語, 한국인 │
  51. │ │
  52. │ SHORTCUTS │
  53. │ │
  54. │ CTRL-E END │
  55. │ CTRL-A START │
  56. │ CTRL-B BACK │
  57. │ CTRL-F FORWARD │
  58. │ CTRL-L CLEAR │
  59. │ CTRL-H BACKSPACE │
  60. │ CTRL-D DELETE │
  61. │ CTRL-Y YANK │
  62. │ CTRL-D EOF (IF EMPTY) │
  63. │ CTRL-N NEXT HISTORY │
  64. │ CTRL-P PREVIOUS HISTORY │
  65. │ CTRL-R SEARCH HISTORY │
  66. │ CTRL-G CANCEL SEARCH │
  67. │ ALT-< BEGINNING OF HISTORY │
  68. │ ALT-> END OF HISTORY │
  69. │ ALT-F FORWARD WORD │
  70. │ ALT-B BACKWARD WORD │
  71. │ CTRL-ALT-F FORWARD EXPR │
  72. │ CTRL-ALT-B BACKWARD EXPR │
  73. │ ALT-RIGHT FORWARD EXPR │
  74. │ ALT-LEFT BACKWARD EXPR │
  75. │ ALT-SHIFT-B BARF EXPR │
  76. │ ALT-SHIFT-S SLURP EXPR │
  77. │ ALT-SHIFT-R RAISE EXPR │
  78. │ CTRL-K KILL LINE FORWARDS │
  79. │ CTRL-U KILL LINE BACKWARDS │
  80. │ ALT-H KILL WORD BACKWARDS │
  81. │ CTRL-W KILL WORD BACKWARDS │
  82. │ CTRL-ALT-H KILL WORD BACKWARDS │
  83. │ ALT-D KILL WORD FORWARDS │
  84. │ ALT-Y ROTATE KILL RING AND YANK AGAIN │
  85. │ ALT-\ SQUEEZE ADJACENT WHITESPACE │
  86. │ CTRL-T TRANSPOSE │
  87. │ ALT-T TRANSPOSE WORD │
  88. │ ALT-U UPPERCASE WORD │
  89. │ ALT-L LOWERCASE WORD │
  90. │ ALT-C CAPITALIZE WORD │
  91. │ CTRL-Z SUSPEND PROCESS │
  92. │ CTRL-\ QUIT PROCESS │
  93. │ CTRL-S PAUSE OUTPUT │
  94. │ CTRL-Q UNPAUSE OUTPUT (IF PAUSED) │
  95. │ CTRL-Q ESCAPED INSERT │
  96. │ CTRL-SPACE SET MARK │
  97. │ CTRL-X CTRL-X GOTO MARK │
  98. │ PROTIP REMAP CAPS LOCK TO CTRL │
  99. │ │
  100. ╞══════════════════════════════════════════════════════════════════════════════╡
  101. │ │
  102. │ Copyright 2018-2021 Justine Tunney <jtunney@gmail.com> │
  103. │ Copyright 2010-2016 Salvatore Sanfilippo <antirez@gmail.com> │
  104. │ Copyright 2010-2013 Pieter Noordhuis <pcnoordhuis@gmail.com> │
  105. │ │
  106. │ All rights reserved. │
  107. │ │
  108. │ Redistribution and use in source and binary forms, with or without │
  109. │ modification, are permitted provided that the following conditions are │
  110. │ met: │
  111. │ │
  112. │ * Redistributions of source code must retain the above copyright │
  113. │ notice, this list of conditions and the following disclaimer. │
  114. │ │
  115. │ * Redistributions in binary form must reproduce the above copyright │
  116. │ notice, this list of conditions and the following disclaimer in the │
  117. │ documentation and/or other materials provided with the distribution. │
  118. │ │
  119. │ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS │
  120. │ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT │
  121. │ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR │
  122. │ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT │
  123. │ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, │
  124. │ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT │
  125. │ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, │
  126. │ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY │
  127. │ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT │
  128. │ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE │
  129. │ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. │
  130. │ │
  131. ╚─────────────────────────────────────────────────────────────────────────────*/
  132. #include "bestline.h"
  133. #ifndef __COSMOPOLITAN__
  134. #define _POSIX_C_SOURCE 1 /* so GCC builds in ANSI mode */
  135. #define _XOPEN_SOURCE 700 /* so GCC builds in ANSI mode */
  136. #define _DARWIN_C_SOURCE 1 /* so SIGWINCH / IUTF8 on XNU */
  137. #include <termios.h>
  138. #include <unistd.h>
  139. #include <stdlib.h>
  140. #include <stdio.h>
  141. #include <errno.h>
  142. #include <string.h>
  143. #include <stdlib.h>
  144. #include <ctype.h>
  145. #include <sys/time.h>
  146. #include <sys/stat.h>
  147. #include <sys/types.h>
  148. #include <sys/ioctl.h>
  149. #include <sys/mman.h>
  150. #include <unistd.h>
  151. #include <setjmp.h>
  152. #include <poll.h>
  153. #include <assert.h>
  154. #include <signal.h>
  155. #include <fcntl.h>
  156. #include <limits.h>
  157. #ifndef SIGWINCH
  158. #define SIGWINCH 28 /* GNU/Systemd + XNU + FreeBSD + NetBSD + OpenBSD */
  159. #endif
  160. #ifndef IUTF8
  161. #define IUTF8 0
  162. #endif
  163. #endif
  164. __asm__(".ident\t\"\\n\\n\
  165. Bestline (BSD-2)\\n\
  166. Copyright 2018-2020 Justine Tunney <jtunney@gmail.com>\\n\
  167. Copyright 2010-2016 Salvatore Sanfilippo <antirez@gmail.com>\\n\
  168. Copyright 2010-2013 Pieter Noordhuis <pcnoordhuis@gmail.com>\"");
  169. #ifndef BESTLINE_MAX_RING
  170. #define BESTLINE_MAX_RING 8
  171. #endif
  172. #ifndef BESTLINE_MAX_HISTORY
  173. #define BESTLINE_MAX_HISTORY 1024
  174. #endif
  175. #define BESTLINE_HISTORY_FIRST +BESTLINE_MAX_HISTORY
  176. #define BESTLINE_HISTORY_PREV +1
  177. #define BESTLINE_HISTORY_NEXT -1
  178. #define BESTLINE_HISTORY_LAST -BESTLINE_MAX_HISTORY
  179. #define Ctrl(C) ((C) ^ 0100)
  180. #define Min(X, Y) ((Y) > (X) ? (X) : (Y))
  181. #define Max(X, Y) ((Y) < (X) ? (X) : (Y))
  182. #define Case(X, Y) case X: Y; break
  183. #define Read16le(X) \
  184. ((255 & (X)[0]) << 000 | \
  185. (255 & (X)[1]) << 010)
  186. #define Read32le(X) \
  187. ((unsigned)(255 & (X)[0]) << 000 | \
  188. (unsigned)(255 & (X)[1]) << 010 | \
  189. (unsigned)(255 & (X)[2]) << 020 | \
  190. (unsigned)(255 & (X)[3]) << 030)
  191. struct abuf {
  192. char *b;
  193. unsigned len;
  194. unsigned cap;
  195. };
  196. struct rune {
  197. unsigned c;
  198. unsigned n;
  199. };
  200. struct bestlineRing {
  201. unsigned i;
  202. char *p[BESTLINE_MAX_RING];
  203. };
  204. /* The bestlineState structure represents the state during line editing.
  205. * We pass this state to functions implementing specific editing
  206. * functionalities. */
  207. struct bestlineState {
  208. int ifd; /* terminal stdin file descriptor */
  209. int ofd; /* terminal stdout file descriptor */
  210. struct winsize ws; /* rows and columns in terminal */
  211. char *buf; /* edited line buffer */
  212. const char *prompt; /* prompt to display */
  213. int hindex; /* history index */
  214. int rows; /* rows being used */
  215. int oldpos; /* previous refresh cursor position */
  216. unsigned buflen; /* edited line buffer size */
  217. unsigned pos; /* current buffer index */
  218. unsigned len; /* current edited line length */
  219. unsigned mark; /* saved cursor position */
  220. unsigned yi, yj; /* boundaries of last yank */
  221. char seq[2][16]; /* keystroke history for yanking code */
  222. char final; /* set to true on last update */
  223. char dirty; /* if an update was squashed */
  224. };
  225. static const char *const kUnsupported[] = {"dumb","cons25","emacs"};
  226. static int gotint;
  227. static int gotcont;
  228. static int gotwinch;
  229. static char rawmode;
  230. static char maskmode;
  231. static char ispaused;
  232. static char iscapital;
  233. static unsigned historylen;
  234. static struct bestlineRing ring;
  235. static struct sigaction orig_cont;
  236. static struct sigaction orig_winch;
  237. static struct termios orig_termios;
  238. static char *history[BESTLINE_MAX_HISTORY];
  239. static bestlineXlatCallback *xlatCallback;
  240. static bestlineHintsCallback *hintsCallback;
  241. static bestlineFreeHintsCallback *freeHintsCallback;
  242. static bestlineCompletionCallback *completionCallback;
  243. static void bestlineAtExit(void);
  244. static void bestlineRefreshLine(struct bestlineState *);
  245. static void bestlineOnInt(int sig) {
  246. gotint = sig;
  247. }
  248. static void bestlineOnCont(int sig) {
  249. gotcont = sig;
  250. }
  251. static void bestlineOnWinch(int sig) {
  252. gotwinch = sig;
  253. }
  254. static char IsControl(unsigned c) {
  255. return c <= 0x1F || (0x7F <= c && c <= 0x9F);
  256. }
  257. static int GetMonospaceCharacterWidth(unsigned c) {
  258. return !IsControl(c)
  259. + (c >= 0x1100 &&
  260. (c <= 0x115f || c == 0x2329 || c == 0x232a ||
  261. (c >= 0x2e80 && c <= 0xa4cf && c != 0x303f) ||
  262. (c >= 0xac00 && c <= 0xd7a3) ||
  263. (c >= 0xf900 && c <= 0xfaff) ||
  264. (c >= 0xfe10 && c <= 0xfe19) ||
  265. (c >= 0xfe30 && c <= 0xfe6f) ||
  266. (c >= 0xff00 && c <= 0xff60) ||
  267. (c >= 0xffe0 && c <= 0xffe6) ||
  268. (c >= 0x20000 && c <= 0x2fffd) ||
  269. (c >= 0x30000 && c <= 0x3fffd)));
  270. }
  271. /**
  272. * Returns nonzero if 𝑐 isn't alphanumeric.
  273. *
  274. * Line reading interfaces generally define this operation as UNICODE
  275. * characters that aren't in the letter category (Lu, Ll, Lt, Lm, Lo)
  276. * and aren't in the number categorie (Nd, Nl, No). We also add a few
  277. * other things like blocks and emoji (So).
  278. */
  279. char bestlineIsSeparator(unsigned c) {
  280. int m, l, r, n;
  281. if (c < 0200) {
  282. return !(('0' <= c && c <= '9') ||
  283. ('A' <= c && c <= 'Z') ||
  284. ('a' <= c && c <= 'z'));
  285. }
  286. if (c <= 0xffff) {
  287. static const unsigned short kGlyphs[][2] = {
  288. {0x00aa, 0x00aa}, /* 1x English */
  289. {0x00b2, 0x00b3}, /* 2x English Arabic */
  290. {0x00b5, 0x00b5}, /* 1x Greek */
  291. {0x00b9, 0x00ba}, /* 2x English Arabic */
  292. {0x00bc, 0x00be}, /* 3x Vulgar English Arabic */
  293. {0x00c0, 0x00d6}, /* 23x Watin */
  294. {0x00d8, 0x00f6}, /* 31x Watin */
  295. {0x0100, 0x02c1}, /* 450x Watin-AB,IPA,Spacemod */
  296. {0x02c6, 0x02d1}, /* 12x Spacemod */
  297. {0x02e0, 0x02e4}, /* 5x Spacemod */
  298. {0x02ec, 0x02ec}, /* 1x Spacemod */
  299. {0x02ee, 0x02ee}, /* 1x Spacemod */
  300. {0x0370, 0x0374}, /* 5x Greek */
  301. {0x0376, 0x0377}, /* 2x Greek */
  302. {0x037a, 0x037d}, /* 4x Greek */
  303. {0x037f, 0x037f}, /* 1x Greek */
  304. {0x0386, 0x0386}, /* 1x Greek */
  305. {0x0388, 0x038a}, /* 3x Greek */
  306. {0x038c, 0x038c}, /* 1x Greek */
  307. {0x038e, 0x03a1}, /* 20x Greek */
  308. {0x03a3, 0x03f5}, /* 83x Greek */
  309. {0x03f7, 0x0481}, /* 139x Greek */
  310. {0x048a, 0x052f}, /* 166x Cyrillic */
  311. {0x0531, 0x0556}, /* 38x Armenian */
  312. {0x0560, 0x0588}, /* 41x Armenian */
  313. {0x05d0, 0x05ea}, /* 27x Hebrew */
  314. {0x0620, 0x064a}, /* 43x Arabic */
  315. {0x0660, 0x0669}, /* 10x Arabic */
  316. {0x0671, 0x06d3}, /* 99x Arabic */
  317. {0x06ee, 0x06fc}, /* 15x Arabic */
  318. {0x0712, 0x072f}, /* 30x Syriac */
  319. {0x074d, 0x07a5}, /* 89x Syriac,Arabic2,Thaana */
  320. {0x07c0, 0x07ea}, /* 43x NKo */
  321. {0x0800, 0x0815}, /* 22x Samaritan */
  322. {0x0840, 0x0858}, /* 25x Mandaic */
  323. {0x0904, 0x0939}, /* 54x Devanagari */
  324. {0x0993, 0x09a8}, /* 22x Bengali */
  325. {0x09e6, 0x09f1}, /* 12x Bengali */
  326. {0x0a13, 0x0a28}, /* 22x Gurmukhi */
  327. {0x0a66, 0x0a6f}, /* 10x Gurmukhi */
  328. {0x0a93, 0x0aa8}, /* 22x Gujarati */
  329. {0x0b13, 0x0b28}, /* 22x Oriya */
  330. {0x0c92, 0x0ca8}, /* 23x Kannada */
  331. {0x0caa, 0x0cb3}, /* 10x Kannada */
  332. {0x0ce6, 0x0cef}, /* 10x Kannada */
  333. {0x0d12, 0x0d3a}, /* 41x Malayalam */
  334. {0x0d85, 0x0d96}, /* 18x Sinhala */
  335. {0x0d9a, 0x0db1}, /* 24x Sinhala */
  336. {0x0de6, 0x0def}, /* 10x Sinhala */
  337. {0x0e01, 0x0e30}, /* 48x Thai */
  338. {0x0e8c, 0x0ea3}, /* 24x Lao */
  339. {0x0f20, 0x0f33}, /* 20x Tibetan */
  340. {0x0f49, 0x0f6c}, /* 36x Tibetan */
  341. {0x109e, 0x10c5}, /* 40x Myanmar,Georgian */
  342. {0x10d0, 0x10fa}, /* 43x Georgian */
  343. {0x10fc, 0x1248}, /* 333x Georgian,Hangul,Ethiopic */
  344. {0x13a0, 0x13f5}, /* 86x Cherokee */
  345. {0x1401, 0x166d}, /* 621x Aboriginal */
  346. {0x16a0, 0x16ea}, /* 75x Runic */
  347. {0x1700, 0x170c}, /* 13x Tagalog */
  348. {0x1780, 0x17b3}, /* 52x Khmer */
  349. {0x1820, 0x1878}, /* 89x Mongolian */
  350. {0x1a00, 0x1a16}, /* 23x Buginese */
  351. {0x1a20, 0x1a54}, /* 53x Tai Tham */
  352. {0x1a80, 0x1a89}, /* 10x Tai Tham */
  353. {0x1a90, 0x1a99}, /* 10x Tai Tham */
  354. {0x1b05, 0x1b33}, /* 47x Balinese */
  355. {0x1b50, 0x1b59}, /* 10x Balinese */
  356. {0x1b83, 0x1ba0}, /* 30x Sundanese */
  357. {0x1bae, 0x1be5}, /* 56x Sundanese */
  358. {0x1c90, 0x1cba}, /* 43x Georgian2 */
  359. {0x1cbd, 0x1cbf}, /* 3x Georgian2 */
  360. {0x1e00, 0x1f15}, /* 278x Watin-C,Greek2 */
  361. {0x2070, 0x2071}, /* 2x Supersub */
  362. {0x2074, 0x2079}, /* 6x Supersub */
  363. {0x207f, 0x2089}, /* 11x Supersub */
  364. {0x2090, 0x209c}, /* 13x Supersub */
  365. {0x2100, 0x2117}, /* 24x Letterlike */
  366. {0x2119, 0x213f}, /* 39x Letterlike */
  367. {0x2145, 0x214a}, /* 6x Letterlike */
  368. {0x214c, 0x218b}, /* 64x Letterlike,Numbery */
  369. {0x21af, 0x21cd}, /* 31x Arrows */
  370. {0x21d5, 0x21f3}, /* 31x Arrows */
  371. {0x230c, 0x231f}, /* 20x Technical */
  372. {0x232b, 0x237b}, /* 81x Technical */
  373. {0x237d, 0x239a}, /* 30x Technical */
  374. {0x23b4, 0x23db}, /* 40x Technical */
  375. {0x23e2, 0x2426}, /* 69x Technical,ControlPictures */
  376. {0x2460, 0x25b6}, /* 343x Enclosed,Boxes,Blocks,Shapes */
  377. {0x25c2, 0x25f7}, /* 54x Shapes */
  378. {0x2600, 0x266e}, /* 111x Symbols */
  379. {0x2670, 0x2767}, /* 248x Symbols,Dingbats */
  380. {0x2776, 0x27bf}, /* 74x Dingbats */
  381. {0x2800, 0x28ff}, /* 256x Braille */
  382. {0x2c00, 0x2c2e}, /* 47x Glagolitic */
  383. {0x2c30, 0x2c5e}, /* 47x Glagolitic */
  384. {0x2c60, 0x2ce4}, /* 133x Watin-D */
  385. {0x2d00, 0x2d25}, /* 38x Georgian2 */
  386. {0x2d30, 0x2d67}, /* 56x Tifinagh */
  387. {0x2d80, 0x2d96}, /* 23x Ethiopic2 */
  388. {0x2e2f, 0x2e2f}, /* 1x Punctuation2 */
  389. {0x3005, 0x3007}, /* 3x CJK Symbols & Punctuation */
  390. {0x3021, 0x3029}, /* 9x CJK Symbols & Punctuation */
  391. {0x3031, 0x3035}, /* 5x CJK Symbols & Punctuation */
  392. {0x3038, 0x303c}, /* 5x CJK Symbols & Punctuation */
  393. {0x3041, 0x3096}, /* 86x Hiragana */
  394. {0x30a1, 0x30fa}, /* 90x Katakana */
  395. {0x3105, 0x312f}, /* 43x Bopomofo */
  396. {0x3131, 0x318e}, /* 94x Hangul Compatibility Jamo */
  397. {0x31a0, 0x31ba}, /* 27x Bopomofo Extended */
  398. {0x31f0, 0x31ff}, /* 16x Katakana Phonetic Extensions */
  399. {0x3220, 0x3229}, /* 10x Enclosed CJK Letters & Months */
  400. {0x3248, 0x324f}, /* 8x Enclosed CJK Letters & Months */
  401. {0x3251, 0x325f}, /* 15x Enclosed CJK Letters & Months */
  402. {0x3280, 0x3289}, /* 10x Enclosed CJK Letters & Months */
  403. {0x32b1, 0x32bf}, /* 15x Enclosed CJK Letters & Months */
  404. {0x3400, 0x4db5}, /* 6582x CJK Unified Ideographs Extension A */
  405. {0x4dc0, 0x9fef}, /* 21040x Yijing Hexagram, CJK Unified Ideographs */
  406. {0xa000, 0xa48c}, /* 1165x Yi Syllables */
  407. {0xa4d0, 0xa4fd}, /* 46x Lisu */
  408. {0xa500, 0xa60c}, /* 269x Vai */
  409. {0xa610, 0xa62b}, /* 28x Vai */
  410. {0xa6a0, 0xa6ef}, /* 80x Bamum */
  411. {0xa80c, 0xa822}, /* 23x Syloti Nagri */
  412. {0xa840, 0xa873}, /* 52x Phags-pa */
  413. {0xa882, 0xa8b3}, /* 50x Saurashtra */
  414. {0xa8d0, 0xa8d9}, /* 10x Saurashtra */
  415. {0xa900, 0xa925}, /* 38x Kayah Li */
  416. {0xa930, 0xa946}, /* 23x Rejang */
  417. {0xa960, 0xa97c}, /* 29x Hangul Jamo Extended-A */
  418. {0xa984, 0xa9b2}, /* 47x Javanese */
  419. {0xa9cf, 0xa9d9}, /* 11x Javanese */
  420. {0xaa00, 0xaa28}, /* 41x Cham */
  421. {0xaa50, 0xaa59}, /* 10x Cham */
  422. {0xabf0, 0xabf9}, /* 10x Meetei Mayek */
  423. {0xac00, 0xd7a3}, /* 11172x Hangul Syllables */
  424. {0xf900, 0xfa6d}, /* 366x CJK Compatibility Ideographs */
  425. {0xfa70, 0xfad9}, /* 106x CJK Compatibility Ideographs */
  426. {0xfb1f, 0xfb28}, /* 10x Alphabetic Presentation Forms */
  427. {0xfb2a, 0xfb36}, /* 13x Alphabetic Presentation Forms */
  428. {0xfb46, 0xfbb1}, /* 108x Alphabetic Presentation Forms */
  429. {0xfbd3, 0xfd3d}, /* 363x Arabic Presentation Forms-A */
  430. {0xfe76, 0xfefc}, /* 135x Arabic Presentation Forms-B */
  431. {0xff10, 0xff19}, /* 10x Dubs */
  432. {0xff21, 0xff3a}, /* 26x Dubs */
  433. {0xff41, 0xff5a}, /* 26x Dubs */
  434. {0xff66, 0xffbe}, /* 89x Dubs */
  435. {0xffc2, 0xffc7}, /* 6x Dubs */
  436. {0xffca, 0xffcf}, /* 6x Dubs */
  437. {0xffd2, 0xffd7}, /* 6x Dubs */
  438. {0xffda, 0xffdc}, /* 3x Dubs */
  439. };
  440. l = 0;
  441. r = n = sizeof(kGlyphs) / sizeof(kGlyphs[0]);
  442. while (l < r) {
  443. m = (l + r) >> 1;
  444. if (kGlyphs[m][1] < c) {
  445. l = m + 1;
  446. } else {
  447. r = m;
  448. }
  449. }
  450. return !(l < n && kGlyphs[l][0] <= c && c <= kGlyphs[l][1]);
  451. } else {
  452. static const unsigned kAstralGlyphs[][2] = {
  453. {0x10107, 0x10133}, /* 45x Aegean */
  454. {0x10140, 0x10178}, /* 57x Ancient Greek Numbers */
  455. {0x1018a, 0x1018b}, /* 2x Ancient Greek Numbers */
  456. {0x10280, 0x1029c}, /* 29x Lycian */
  457. {0x102a0, 0x102d0}, /* 49x Carian */
  458. {0x102e1, 0x102fb}, /* 27x Coptic Epact Numbers */
  459. {0x10300, 0x10323}, /* 36x Old Italic */
  460. {0x1032d, 0x1034a}, /* 30x Old Italic, Gothic */
  461. {0x10350, 0x10375}, /* 38x Old Permic */
  462. {0x10380, 0x1039d}, /* 30x Ugaritic */
  463. {0x103a0, 0x103c3}, /* 36x Old Persian */
  464. {0x103c8, 0x103cf}, /* 8x Old Persian */
  465. {0x103d1, 0x103d5}, /* 5x Old Persian */
  466. {0x10400, 0x1049d}, /* 158x Deseret, Shavian, Osmanya */
  467. {0x104b0, 0x104d3}, /* 36x Osage */
  468. {0x104d8, 0x104fb}, /* 36x Osage */
  469. {0x10500, 0x10527}, /* 40x Elbasan */
  470. {0x10530, 0x10563}, /* 52x Caucasian Albanian */
  471. {0x10600, 0x10736}, /* 311x Linear A */
  472. {0x10800, 0x10805}, /* 6x Cypriot Syllabary */
  473. {0x1080a, 0x10835}, /* 44x Cypriot Syllabary */
  474. {0x10837, 0x10838}, /* 2x Cypriot Syllabary */
  475. {0x1083f, 0x1089e}, /* 86x Cypriot,ImperialAramaic,Palmyrene,Nabataean */
  476. {0x108e0, 0x108f2}, /* 19x Hatran */
  477. {0x108f4, 0x108f5}, /* 2x Hatran */
  478. {0x108fb, 0x1091b}, /* 33x Hatran */
  479. {0x10920, 0x10939}, /* 26x Lydian */
  480. {0x10980, 0x109b7}, /* 56x Meroitic Hieroglyphs */
  481. {0x109bc, 0x109cf}, /* 20x Meroitic Cursive */
  482. {0x109d2, 0x10a00}, /* 47x Meroitic Cursive */
  483. {0x10a10, 0x10a13}, /* 4x Kharoshthi */
  484. {0x10a15, 0x10a17}, /* 3x Kharoshthi */
  485. {0x10a19, 0x10a35}, /* 29x Kharoshthi */
  486. {0x10a40, 0x10a48}, /* 9x Kharoshthi */
  487. {0x10a60, 0x10a7e}, /* 31x Old South Arabian */
  488. {0x10a80, 0x10a9f}, /* 32x Old North Arabian */
  489. {0x10ac0, 0x10ac7}, /* 8x Manichaean */
  490. {0x10ac9, 0x10ae4}, /* 28x Manichaean */
  491. {0x10aeb, 0x10aef}, /* 5x Manichaean */
  492. {0x10b00, 0x10b35}, /* 54x Avestan */
  493. {0x10b40, 0x10b55}, /* 22x Inscriptional Parthian */
  494. {0x10b58, 0x10b72}, /* 27x Inscriptional Parthian and Pahlavi */
  495. {0x10b78, 0x10b91}, /* 26x Inscriptional Pahlavi, Psalter Pahlavi */
  496. {0x10c00, 0x10c48}, /* 73x Old Turkic */
  497. {0x10c80, 0x10cb2}, /* 51x Old Hungarian */
  498. {0x10cc0, 0x10cf2}, /* 51x Old Hungarian */
  499. {0x10cfa, 0x10d23}, /* 42x Old Hungarian, Hanifi Rohingya */
  500. {0x10d30, 0x10d39}, /* 10x Hanifi Rohingya */
  501. {0x10e60, 0x10e7e}, /* 31x Rumi Numeral Symbols */
  502. {0x10f00, 0x10f27}, /* 40x Old Sogdian */
  503. {0x10f30, 0x10f45}, /* 22x Sogdian */
  504. {0x10f51, 0x10f54}, /* 4x Sogdian */
  505. {0x10fe0, 0x10ff6}, /* 23x Elymaic */
  506. {0x11003, 0x11037}, /* 53x Brahmi */
  507. {0x11052, 0x1106f}, /* 30x Brahmi */
  508. {0x11083, 0x110af}, /* 45x Kaithi */
  509. {0x110d0, 0x110e8}, /* 25x Sora Sompeng */
  510. {0x110f0, 0x110f9}, /* 10x Sora Sompeng */
  511. {0x11103, 0x11126}, /* 36x Chakma */
  512. {0x11136, 0x1113f}, /* 10x Chakma */
  513. {0x11144, 0x11144}, /* 1x Chakma */
  514. {0x11150, 0x11172}, /* 35x Mahajani */
  515. {0x11176, 0x11176}, /* 1x Mahajani */
  516. {0x11183, 0x111b2}, /* 48x Sharada */
  517. {0x111c1, 0x111c4}, /* 4x Sharada */
  518. {0x111d0, 0x111da}, /* 11x Sharada */
  519. {0x111dc, 0x111dc}, /* 1x Sharada */
  520. {0x111e1, 0x111f4}, /* 20x Sinhala Archaic Numbers */
  521. {0x11200, 0x11211}, /* 18x Khojki */
  522. {0x11213, 0x1122b}, /* 25x Khojki */
  523. {0x11280, 0x11286}, /* 7x Multani */
  524. {0x11288, 0x11288}, /* 1x Multani */
  525. {0x1128a, 0x1128d}, /* 4x Multani */
  526. {0x1128f, 0x1129d}, /* 15x Multani */
  527. {0x1129f, 0x112a8}, /* 10x Multani */
  528. {0x112b0, 0x112de}, /* 47x Khudawadi */
  529. {0x112f0, 0x112f9}, /* 10x Khudawadi */
  530. {0x11305, 0x1130c}, /* 8x Grantha */
  531. {0x1130f, 0x11310}, /* 2x Grantha */
  532. {0x11313, 0x11328}, /* 22x Grantha */
  533. {0x1132a, 0x11330}, /* 7x Grantha */
  534. {0x11332, 0x11333}, /* 2x Grantha */
  535. {0x11335, 0x11339}, /* 5x Grantha */
  536. {0x1133d, 0x1133d}, /* 1x Grantha */
  537. {0x11350, 0x11350}, /* 1x Grantha */
  538. {0x1135d, 0x11361}, /* 5x Grantha */
  539. {0x11400, 0x11434}, /* 53x Newa */
  540. {0x11447, 0x1144a}, /* 4x Newa */
  541. {0x11450, 0x11459}, /* 10x Newa */
  542. {0x1145f, 0x1145f}, /* 1x Newa */
  543. {0x11480, 0x114af}, /* 48x Tirhuta */
  544. {0x114c4, 0x114c5}, /* 2x Tirhuta */
  545. {0x114c7, 0x114c7}, /* 1x Tirhuta */
  546. {0x114d0, 0x114d9}, /* 10x Tirhuta */
  547. {0x11580, 0x115ae}, /* 47x Siddham */
  548. {0x115d8, 0x115db}, /* 4x Siddham */
  549. {0x11600, 0x1162f}, /* 48x Modi */
  550. {0x11644, 0x11644}, /* 1x Modi */
  551. {0x11650, 0x11659}, /* 10x Modi */
  552. {0x11680, 0x116aa}, /* 43x Takri */
  553. {0x116b8, 0x116b8}, /* 1x Takri */
  554. {0x116c0, 0x116c9}, /* 10x Takri */
  555. {0x11700, 0x1171a}, /* 27x Ahom */
  556. {0x11730, 0x1173b}, /* 12x Ahom */
  557. {0x11800, 0x1182b}, /* 44x Dogra */
  558. {0x118a0, 0x118f2}, /* 83x Warang Citi */
  559. {0x118ff, 0x118ff}, /* 1x Warang Citi */
  560. {0x119a0, 0x119a7}, /* 8x Nandinagari */
  561. {0x119aa, 0x119d0}, /* 39x Nandinagari */
  562. {0x119e1, 0x119e1}, /* 1x Nandinagari */
  563. {0x119e3, 0x119e3}, /* 1x Nandinagari */
  564. {0x11a00, 0x11a00}, /* 1x Zanabazar Square */
  565. {0x11a0b, 0x11a32}, /* 40x Zanabazar Square */
  566. {0x11a3a, 0x11a3a}, /* 1x Zanabazar Square */
  567. {0x11a50, 0x11a50}, /* 1x Soyombo */
  568. {0x11a5c, 0x11a89}, /* 46x Soyombo */
  569. {0x11a9d, 0x11a9d}, /* 1x Soyombo */
  570. {0x11ac0, 0x11af8}, /* 57x Pau Cin Hau */
  571. {0x11c00, 0x11c08}, /* 9x Bhaiksuki */
  572. {0x11c0a, 0x11c2e}, /* 37x Bhaiksuki */
  573. {0x11c40, 0x11c40}, /* 1x Bhaiksuki */
  574. {0x11c50, 0x11c6c}, /* 29x Bhaiksuki */
  575. {0x11c72, 0x11c8f}, /* 30x Marchen */
  576. {0x11d00, 0x11d06}, /* 7x Masaram Gondi */
  577. {0x11d08, 0x11d09}, /* 2x Masaram Gondi */
  578. {0x11d0b, 0x11d30}, /* 38x Masaram Gondi */
  579. {0x11d46, 0x11d46}, /* 1x Masaram Gondi */
  580. {0x11d50, 0x11d59}, /* 10x Masaram Gondi */
  581. {0x11d60, 0x11d65}, /* 6x Gunjala Gondi */
  582. {0x11d67, 0x11d68}, /* 2x Gunjala Gondi */
  583. {0x11d6a, 0x11d89}, /* 32x Gunjala Gondi */
  584. {0x11d98, 0x11d98}, /* 1x Gunjala Gondi */
  585. {0x11da0, 0x11da9}, /* 10x Gunjala Gondi */
  586. {0x11ee0, 0x11ef2}, /* 19x Makasar */
  587. {0x11fc0, 0x11fd4}, /* 21x Tamil Supplement */
  588. {0x12000, 0x12399}, /* 922x Cuneiform */
  589. {0x12400, 0x1246e}, /* 111x Cuneiform Numbers & Punctuation */
  590. {0x12480, 0x12543}, /* 196x Early Dynastic Cuneiform */
  591. {0x13000, 0x1342e}, /* 1071x Egyptian Hieroglyphs */
  592. {0x14400, 0x14646}, /* 583x Anatolian Hieroglyphs */
  593. {0x16800, 0x16a38}, /* 569x Bamum Supplement */
  594. {0x16a40, 0x16a5e}, /* 31x Mro */
  595. {0x16a60, 0x16a69}, /* 10x Mro */
  596. {0x16ad0, 0x16aed}, /* 30x Bassa Vah */
  597. {0x16b00, 0x16b2f}, /* 48x Pahawh Hmong */
  598. {0x16b40, 0x16b43}, /* 4x Pahawh Hmong */
  599. {0x16b50, 0x16b59}, /* 10x Pahawh Hmong */
  600. {0x16b5b, 0x16b61}, /* 7x Pahawh Hmong */
  601. {0x16b63, 0x16b77}, /* 21x Pahawh Hmong */
  602. {0x16b7d, 0x16b8f}, /* 19x Pahawh Hmong */
  603. {0x16e40, 0x16e96}, /* 87x Medefaidrin */
  604. {0x16f00, 0x16f4a}, /* 75x Miao */
  605. {0x16f50, 0x16f50}, /* 1x Miao */
  606. {0x16f93, 0x16f9f}, /* 13x Miao */
  607. {0x16fe0, 0x16fe1}, /* 2x Ideographic Symbols & Punctuation */
  608. {0x16fe3, 0x16fe3}, /* 1x Ideographic Symbols & Punctuation */
  609. {0x17000, 0x187f7}, /* 6136x Tangut */
  610. {0x18800, 0x18af2}, /* 755x Tangut Components */
  611. {0x1b000, 0x1b11e}, /* 287x Kana Supplement */
  612. {0x1b150, 0x1b152}, /* 3x Small Kana Extension */
  613. {0x1b164, 0x1b167}, /* 4x Small Kana Extension */
  614. {0x1b170, 0x1b2fb}, /* 396x Nushu */
  615. {0x1bc00, 0x1bc6a}, /* 107x Duployan */
  616. {0x1bc70, 0x1bc7c}, /* 13x Duployan */
  617. {0x1bc80, 0x1bc88}, /* 9x Duployan */
  618. {0x1bc90, 0x1bc99}, /* 10x Duployan */
  619. {0x1d2e0, 0x1d2f3}, /* 20x Mayan Numerals */
  620. {0x1d360, 0x1d378}, /* 25x Counting Rod Numerals */
  621. {0x1d400, 0x1d454}, /* 85x 𝐀..𝑔 Math */
  622. {0x1d456, 0x1d49c}, /* 71x 𝑖..𝒜 Math */
  623. {0x1d49e, 0x1d49f}, /* 2x 𝒞..𝒟 Math */
  624. {0x1d4a2, 0x1d4a2}, /* 1x 𝒢..𝒢 Math */
  625. {0x1d4a5, 0x1d4a6}, /* 2x 𝒥..𝒦 Math */
  626. {0x1d4a9, 0x1d4ac}, /* 4x 𝒩..𝒬 Math */
  627. {0x1d4ae, 0x1d4b9}, /* 12x 𝒮..𝒹 Math */
  628. {0x1d4bb, 0x1d4bb}, /* 1x 𝒻..𝒻 Math */
  629. {0x1d4bd, 0x1d4c3}, /* 7x 𝒽..𝓃 Math */
  630. {0x1d4c5, 0x1d505}, /* 65x 𝓅..𝔅 Math */
  631. {0x1d507, 0x1d50a}, /* 4x 𝔇..𝔊 Math */
  632. {0x1d50d, 0x1d514}, /* 8x 𝔍..𝔔 Math */
  633. {0x1d516, 0x1d51c}, /* 7x 𝔖..𝔜 Math */
  634. {0x1d51e, 0x1d539}, /* 28x 𝔞..𝔹 Math */
  635. {0x1d53b, 0x1d53e}, /* 4x 𝔻..𝔾 Math */
  636. {0x1d540, 0x1d544}, /* 5x 𝕀..𝕄 Math */
  637. {0x1d546, 0x1d546}, /* 1x 𝕆..𝕆 Math */
  638. {0x1d54a, 0x1d550}, /* 7x 𝕊..𝕐 Math */
  639. {0x1d552, 0x1d6a5}, /* 340x 𝕒..𝚥 Math */
  640. {0x1d6a8, 0x1d6c0}, /* 25x 𝚨..𝛀 Math */
  641. {0x1d6c2, 0x1d6da}, /* 25x 𝛂..𝛚 Math */
  642. {0x1d6dc, 0x1d6fa}, /* 31x 𝛜..𝛺 Math */
  643. {0x1d6fc, 0x1d714}, /* 25x 𝛼..𝜔 Math */
  644. {0x1d716, 0x1d734}, /* 31x 𝜖..𝜴 Math */
  645. {0x1d736, 0x1d74e}, /* 25x 𝜶..𝝎 Math */
  646. {0x1d750, 0x1d76e}, /* 31x 𝝐..𝝮 Math */
  647. {0x1d770, 0x1d788}, /* 25x 𝝰..𝞈 Math */
  648. {0x1d78a, 0x1d7a8}, /* 31x 𝞊..𝞨 Math */
  649. {0x1d7aa, 0x1d7c2}, /* 25x 𝞪..𝟂 Math */
  650. {0x1d7c4, 0x1d7cb}, /* 8x 𝟄..𝟋 Math */
  651. {0x1d7ce, 0x1d9ff}, /* 562x Math, Sutton SignWriting */
  652. {0x1f100, 0x1f10c}, /* 13x Enclosed Alphanumeric Supplement */
  653. {0x20000, 0x2a6d6}, /* 42711x CJK Unified Ideographs Extension B */
  654. {0x2a700, 0x2b734}, /* 4149x CJK Unified Ideographs Extension C */
  655. {0x2b740, 0x2b81d}, /* 222x CJK Unified Ideographs Extension D */
  656. {0x2b820, 0x2cea1}, /* 5762x CJK Unified Ideographs Extension E */
  657. {0x2ceb0, 0x2ebe0}, /* 7473x CJK Unified Ideographs Extension F */
  658. {0x2f800, 0x2fa1d}, /* 542x CJK Compatibility Ideographs Supplement */
  659. };
  660. l = 0;
  661. r = n = sizeof(kAstralGlyphs) / sizeof(kAstralGlyphs[0]);
  662. while (l < r) {
  663. m = (l + r) >> 1;
  664. if (kAstralGlyphs[m][1] < c) {
  665. l = m + 1;
  666. } else {
  667. r = m;
  668. }
  669. }
  670. return !(l < n && kAstralGlyphs[l][0] <= c && c <= kAstralGlyphs[l][1]);
  671. }
  672. }
  673. unsigned bestlineLowercase(unsigned c) {
  674. int m, l, r, n;
  675. if (c < 0200) {
  676. if ('A' <= c && c <= 'Z') {
  677. return c + 32;
  678. } else {
  679. return c;
  680. }
  681. } else if (c <= 0xffff) {
  682. if ((0x0100 <= c && c <= 0x0176) || /* 60x Ā..ā → ā..ŵ Watin-A */
  683. (0x01de <= c && c <= 0x01ee) || /* 9x Ǟ..Ǯ → ǟ..ǯ Watin-B */
  684. (0x01f8 <= c && c <= 0x021e) || /* 20x Ǹ..Ȟ → ǹ..ȟ Watin-B */
  685. (0x0222 <= c && c <= 0x0232) || /* 9x Ȣ..Ȳ → ȣ..ȳ Watin-B */
  686. (0x1e00 <= c && c <= 0x1eff)) { /*256x Ḁ..Ỿ → ḁ..ỿ Watin-C */
  687. if (c == 0x0130) return c - 199;
  688. if (c == 0x1e9e) return c;
  689. return c + (~c & 1);
  690. } else if (0x01cf <= c && c <= 0x01db) {
  691. return c + (c & 1); /* 7x Ǐ..Ǜ → ǐ..ǜ Watin-B */
  692. } else if (0x13a0 <= c && c <= 0x13ef) {
  693. return c + 38864; /* 80x Ꭰ ..Ꮿ → ꭰ ..ꮿ Cherokee */
  694. } else {
  695. static const struct {
  696. unsigned short a;
  697. unsigned short b;
  698. short d;
  699. } kLower[] = {
  700. {0x00c0, 0x00d6, +32}, /* 23x À ..Ö → à ..ö Watin */
  701. {0x00d8, 0x00de, +32}, /* 7x Ø ..Þ → ø ..þ Watin */
  702. {0x0178, 0x0178, -121}, /* 1x Ÿ ..Ÿ → ÿ ..ÿ Watin-A */
  703. {0x0179, 0x0179, +1}, /* 1x Ź ..Ź → ź ..ź Watin-A */
  704. {0x017b, 0x017b, +1}, /* 1x Ż ..Ż → ż ..ż Watin-A */
  705. {0x017d, 0x017d, +1}, /* 1x Ž ..Ž → ž ..ž Watin-A */
  706. {0x0181, 0x0181, +210}, /* 1x Ɓ ..Ɓ → ɓ ..ɓ Watin-B */
  707. {0x0182, 0x0182, +1}, /* 1x Ƃ ..Ƃ → ƃ ..ƃ Watin-B */
  708. {0x0184, 0x0184, +1}, /* 1x Ƅ ..Ƅ → ƅ ..ƅ Watin-B */
  709. {0x0186, 0x0186, +206}, /* 1x Ɔ ..Ɔ → ɔ ..ɔ Watin-B */
  710. {0x0187, 0x0187, +1}, /* 1x Ƈ ..Ƈ → ƈ ..ƈ Watin-B */
  711. {0x0189, 0x018a, +205}, /* 2x Ɖ ..Ɗ → ɖ ..ɗ Watin-B */
  712. {0x018b, 0x018b, +1}, /* 1x Ƌ ..Ƌ → ƌ ..ƌ Watin-B */
  713. {0x018e, 0x018e, +79}, /* 1x Ǝ ..Ǝ → ǝ ..ǝ Watin-B */
  714. {0x018f, 0x018f, +202}, /* 1x Ə ..Ə → ə ..ə Watin-B */
  715. {0x0190, 0x0190, +203}, /* 1x Ɛ ..Ɛ → ɛ ..ɛ Watin-B */
  716. {0x0191, 0x0191, +1}, /* 1x Ƒ ..Ƒ → ƒ ..ƒ Watin-B */
  717. {0x0193, 0x0193, +205}, /* 1x Ɠ ..Ɠ → ɠ ..ɠ Watin-B */
  718. {0x0194, 0x0194, +207}, /* 1x Ɣ ..Ɣ → ɣ ..ɣ Watin-B */
  719. {0x0196, 0x0196, +211}, /* 1x Ɩ ..Ɩ → ɩ ..ɩ Watin-B */
  720. {0x0197, 0x0197, +209}, /* 1x Ɨ ..Ɨ → ɨ ..ɨ Watin-B */
  721. {0x0198, 0x0198, +1}, /* 1x Ƙ ..Ƙ → ƙ ..ƙ Watin-B */
  722. {0x019c, 0x019c, +211}, /* 1x Ɯ ..Ɯ → ɯ ..ɯ Watin-B */
  723. {0x019d, 0x019d, +213}, /* 1x Ɲ ..Ɲ → ɲ ..ɲ Watin-B */
  724. {0x019f, 0x019f, +214}, /* 1x Ɵ ..Ɵ → ɵ ..ɵ Watin-B */
  725. {0x01a0, 0x01a0, +1}, /* 1x Ơ ..Ơ → ơ ..ơ Watin-B */
  726. {0x01a2, 0x01a2, +1}, /* 1x Ƣ ..Ƣ → ƣ ..ƣ Watin-B */
  727. {0x01a4, 0x01a4, +1}, /* 1x Ƥ ..Ƥ → ƥ ..ƥ Watin-B */
  728. {0x01a6, 0x01a6, +218}, /* 1x Ʀ ..Ʀ → ʀ ..ʀ Watin-B */
  729. {0x01a7, 0x01a7, +1}, /* 1x Ƨ ..Ƨ → ƨ ..ƨ Watin-B */
  730. {0x01a9, 0x01a9, +218}, /* 1x Ʃ ..Ʃ → ʃ ..ʃ Watin-B */
  731. {0x01ac, 0x01ac, +1}, /* 1x Ƭ ..Ƭ → ƭ ..ƭ Watin-B */
  732. {0x01ae, 0x01ae, +218}, /* 1x Ʈ ..Ʈ → ʈ ..ʈ Watin-B */
  733. {0x01af, 0x01af, +1}, /* 1x Ư ..Ư → ư ..ư Watin-B */
  734. {0x01b1, 0x01b2, +217}, /* 2x Ʊ ..Ʋ → ʊ ..ʋ Watin-B */
  735. {0x01b3, 0x01b3, +1}, /* 1x Ƴ ..Ƴ → ƴ ..ƴ Watin-B */
  736. {0x01b5, 0x01b5, +1}, /* 1x Ƶ ..Ƶ → ƶ ..ƶ Watin-B */
  737. {0x01b7, 0x01b7, +219}, /* 1x Ʒ ..Ʒ → ʒ ..ʒ Watin-B */
  738. {0x01b8, 0x01b8, +1}, /* 1x Ƹ ..Ƹ → ƹ ..ƹ Watin-B */
  739. {0x01bc, 0x01bc, +1}, /* 1x Ƽ ..Ƽ → ƽ ..ƽ Watin-B */
  740. {0x01c4, 0x01c4, +2}, /* 1x DŽ ..DŽ → dž ..dž Watin-B */
  741. {0x01c5, 0x01c5, +1}, /* 1x Dž ..Dž → dž ..dž Watin-B */
  742. {0x01c7, 0x01c7, +2}, /* 1x LJ ..LJ → lj ..lj Watin-B */
  743. {0x01c8, 0x01c8, +1}, /* 1x Lj ..Lj → lj ..lj Watin-B */
  744. {0x01ca, 0x01ca, +2}, /* 1x NJ ..NJ → nj ..nj Watin-B */
  745. {0x01cb, 0x01cb, +1}, /* 1x Nj ..Nj → nj ..nj Watin-B */
  746. {0x01cd, 0x01cd, +1}, /* 1x Ǎ ..Ǎ → ǎ ..ǎ Watin-B */
  747. {0x01f1, 0x01f1, +2}, /* 1x DZ ..DZ → dz ..dz Watin-B */
  748. {0x01f2, 0x01f2, +1}, /* 1x Dz ..Dz → dz ..dz Watin-B */
  749. {0x01f4, 0x01f4, +1}, /* 1x Ǵ ..Ǵ → ǵ ..ǵ Watin-B */
  750. {0x01f6, 0x01f6, -97}, /* 1x Ƕ ..Ƕ → ƕ ..ƕ Watin-B */
  751. {0x01f7, 0x01f7, -56}, /* 1x Ƿ ..Ƿ → ƿ ..ƿ Watin-B */
  752. {0x0220, 0x0220, -130}, /* 1x Ƞ ..Ƞ → ƞ ..ƞ Watin-B */
  753. {0x023b, 0x023b, +1}, /* 1x Ȼ ..Ȼ → ȼ ..ȼ Watin-B */
  754. {0x023d, 0x023d, -163}, /* 1x Ƚ ..Ƚ → ƚ ..ƚ Watin-B */
  755. {0x0241, 0x0241, +1}, /* 1x Ɂ ..Ɂ → ɂ ..ɂ Watin-B */
  756. {0x0243, 0x0243, -195}, /* 1x Ƀ ..Ƀ → ƀ ..ƀ Watin-B */
  757. {0x0244, 0x0244, +69}, /* 1x Ʉ ..Ʉ → ʉ ..ʉ Watin-B */
  758. {0x0245, 0x0245, +71}, /* 1x Ʌ ..Ʌ → ʌ ..ʌ Watin-B */
  759. {0x0246, 0x0246, +1}, /* 1x Ɇ ..Ɇ → ɇ ..ɇ Watin-B */
  760. {0x0248, 0x0248, +1}, /* 1x Ɉ ..Ɉ → ɉ ..ɉ Watin-B */
  761. {0x024a, 0x024a, +1}, /* 1x Ɋ ..Ɋ → ɋ ..ɋ Watin-B */
  762. {0x024c, 0x024c, +1}, /* 1x Ɍ ..Ɍ → ɍ ..ɍ Watin-B */
  763. {0x024e, 0x024e, +1}, /* 1x Ɏ ..Ɏ → ɏ ..ɏ Watin-B */
  764. {0x0386, 0x0386, +38}, /* 1x Ά ..Ά → ά ..ά Greek */
  765. {0x0388, 0x038a, +37}, /* 3x Έ ..Ί → έ ..ί Greek */
  766. {0x038c, 0x038c, +64}, /* 1x Ό ..Ό → ό ..ό Greek */
  767. {0x038e, 0x038f, +63}, /* 2x Ύ ..Ώ → ύ ..ώ Greek */
  768. {0x0391, 0x03a1, +32}, /* 17x Α ..Ρ → α ..ρ Greek */
  769. {0x03a3, 0x03ab, +32}, /* 9x Σ ..Ϋ → σ ..ϋ Greek */
  770. {0x03dc, 0x03dc, +1}, /* 1x Ϝ ..Ϝ → ϝ ..ϝ Greek */
  771. {0x03f4, 0x03f4, -60}, /* 1x ϴ ..ϴ → θ ..θ Greek */
  772. {0x0400, 0x040f, +80}, /* 16x Ѐ ..Џ → ѐ ..џ Cyrillic */
  773. {0x0410, 0x042f, +32}, /* 32x А ..Я → а ..я Cyrillic */
  774. {0x0460, 0x0460, +1}, /* 1x Ѡ ..Ѡ → ѡ ..ѡ Cyrillic */
  775. {0x0462, 0x0462, +1}, /* 1x Ѣ ..Ѣ → ѣ ..ѣ Cyrillic */
  776. {0x0464, 0x0464, +1}, /* 1x Ѥ ..Ѥ → ѥ ..ѥ Cyrillic */
  777. {0x0472, 0x0472, +1}, /* 1x Ѳ ..Ѳ → ѳ ..ѳ Cyrillic */
  778. {0x0490, 0x0490, +1}, /* 1x Ґ ..Ґ → ґ ..ґ Cyrillic */
  779. {0x0498, 0x0498, +1}, /* 1x Ҙ ..Ҙ → ҙ ..ҙ Cyrillic */
  780. {0x049a, 0x049a, +1}, /* 1x Қ ..Қ → қ ..қ Cyrillic */
  781. {0x0531, 0x0556, +48}, /* 38x Ա ..Ֆ → ա ..ֆ Armenian */
  782. {0x10a0, 0x10c5, +7264}, /* 38x Ⴀ ..Ⴥ → ⴀ ..ⴥ Georgian */
  783. {0x10c7, 0x10c7, +7264}, /* 1x Ⴧ ..Ⴧ → ⴧ ..ⴧ Georgian */
  784. {0x10cd, 0x10cd, +7264}, /* 1x Ⴭ ..Ⴭ → ⴭ ..ⴭ Georgian */
  785. {0x13f0, 0x13f5, +8}, /* 6x Ᏸ ..Ᏽ → ᏸ ..ᏽ Cherokee */
  786. {0x1c90, 0x1cba, -3008}, /* 43x Ა ..Ჺ → ა ..ჺ Georgian2 */
  787. {0x1cbd, 0x1cbf, -3008}, /* 3x Ჽ ..Ჿ → ჽ ..ჿ Georgian2 */
  788. {0x1f08, 0x1f0f, -8}, /* 8x Ἀ ..Ἇ → ἀ ..ἇ Greek2 */
  789. {0x1f18, 0x1f1d, -8}, /* 6x Ἐ ..Ἕ → ἐ ..ἕ Greek2 */
  790. {0x1f28, 0x1f2f, -8}, /* 8x Ἠ ..Ἧ → ἠ ..ἧ Greek2 */
  791. {0x1f38, 0x1f3f, -8}, /* 8x Ἰ ..Ἷ → ἰ ..ἷ Greek2 */
  792. {0x1f48, 0x1f4d, -8}, /* 6x Ὀ ..Ὅ → ὀ ..ὅ Greek2 */
  793. {0x1f59, 0x1f59, -8}, /* 1x Ὑ ..Ὑ → ὑ ..ὑ Greek2 */
  794. {0x1f5b, 0x1f5b, -8}, /* 1x Ὓ ..Ὓ → ὓ ..ὓ Greek2 */
  795. {0x1f5d, 0x1f5d, -8}, /* 1x Ὕ ..Ὕ → ὕ ..ὕ Greek2 */
  796. {0x1f5f, 0x1f5f, -8}, /* 1x Ὗ ..Ὗ → ὗ ..ὗ Greek2 */
  797. {0x1f68, 0x1f6f, -8}, /* 8x Ὠ ..Ὧ → ὠ ..ὧ Greek2 */
  798. {0x1f88, 0x1f8f, -8}, /* 8x ᾈ ..ᾏ → ᾀ ..ᾇ Greek2 */
  799. {0x1f98, 0x1f9f, -8}, /* 8x ᾘ ..ᾟ → ᾐ ..ᾗ Greek2 */
  800. {0x1fa8, 0x1faf, -8}, /* 8x ᾨ ..ᾯ → ᾠ ..ᾧ Greek2 */
  801. {0x1fb8, 0x1fb9, -8}, /* 2x Ᾰ ..Ᾱ → ᾰ ..ᾱ Greek2 */
  802. {0x1fba, 0x1fbb, -74}, /* 2x Ὰ ..Ά → ὰ ..ά Greek2 */
  803. {0x1fbc, 0x1fbc, -9}, /* 1x ᾼ ..ᾼ → ᾳ ..ᾳ Greek2 */
  804. {0x1fc8, 0x1fcb, -86}, /* 4x Ὲ ..Ή → ὲ ..ή Greek2 */
  805. {0x1fcc, 0x1fcc, -9}, /* 1x ῌ ..ῌ → ῃ ..ῃ Greek2 */
  806. {0x1fd8, 0x1fd9, -8}, /* 2x Ῐ ..Ῑ → ῐ ..ῑ Greek2 */
  807. {0x1fda, 0x1fdb, -100}, /* 2x Ὶ ..Ί → ὶ ..ί Greek2 */
  808. {0x1fe8, 0x1fe9, -8}, /* 2x Ῠ ..Ῡ → ῠ ..ῡ Greek2 */
  809. {0x1fea, 0x1feb, -112}, /* 2x Ὺ ..Ύ → ὺ ..ύ Greek2 */
  810. {0x1fec, 0x1fec, -7}, /* 1x Ῥ ..Ῥ → ῥ ..ῥ Greek2 */
  811. {0x1ff8, 0x1ff9, -128}, /* 2x Ὸ ..Ό → ὸ ..ό Greek2 */
  812. {0x1ffa, 0x1ffb, -126}, /* 2x Ὼ ..Ώ → ὼ ..ώ Greek2 */
  813. {0x1ffc, 0x1ffc, -9}, /* 1x ῼ ..ῼ → ῳ ..ῳ Greek2 */
  814. {0x2126, 0x2126, -7517}, /* 1x Ω ..Ω → ω ..ω Letterlike */
  815. {0x212a, 0x212a, -8383}, /* 1x K ..K → k ..k Letterlike */
  816. {0x212b, 0x212b, -8262}, /* 1x Å ..Å → å ..å Letterlike */
  817. {0x2132, 0x2132, +28}, /* 1x Ⅎ ..Ⅎ → ⅎ ..ⅎ Letterlike */
  818. {0x2160, 0x216f, +16}, /* 16x Ⅰ ..Ⅿ → ⅰ ..ⅿ Numbery */
  819. {0x2183, 0x2183, +1}, /* 1x Ↄ ..Ↄ → ↄ ..ↄ Numbery */
  820. {0x24b6, 0x24cf, +26}, /* 26x Ⓐ ..Ⓩ → ⓐ ..ⓩ Enclosed */
  821. {0x2c00, 0x2c2e, +48}, /* 47x Ⰰ ..Ⱞ → ⰰ ..ⱞ Glagolitic */
  822. {0xff21, 0xff3a, +32}, /* 26x A..Z → a..z Dubs */
  823. };
  824. l = 0;
  825. r = n = sizeof(kLower) / sizeof(kLower[0]);
  826. while (l < r) {
  827. m = (l + r) >> 1;
  828. if (kLower[m].b < c) {
  829. l = m + 1;
  830. } else {
  831. r = m;
  832. }
  833. }
  834. if (l < n && kLower[l].a <= c && c <= kLower[l].b) {
  835. return c + kLower[l].d;
  836. } else {
  837. return c;
  838. }
  839. }
  840. } else {
  841. static struct {
  842. unsigned a;
  843. unsigned b;
  844. short d;
  845. } kAstralLower[] = {
  846. {0x10400, 0x10427, +40}, /* 40x 𐐀 ..𐐧 → 𐐨 ..𐑏 Deseret */
  847. {0x104b0, 0x104d3, +40}, /* 36x 𐒰 ..𐓓 → 𐓘 ..𐓻 Osage */
  848. {0x1d400, 0x1d419, +26}, /* 26x 𝐀 ..𝐙 → 𝐚 ..𝐳 Math */
  849. {0x1d43c, 0x1d44d, +26}, /* 18x 𝐼 ..𝑍 → 𝑖 ..𝑧 Math */
  850. {0x1d468, 0x1d481, +26}, /* 26x 𝑨 ..𝒁 → 𝒂 ..𝒛 Math */
  851. {0x1d4ae, 0x1d4b5, +26}, /* 8x 𝒮 ..𝒵 → 𝓈 ..𝓏 Math */
  852. {0x1d4d0, 0x1d4e9, +26}, /* 26x 𝓐 ..𝓩 → 𝓪 ..𝔃 Math */
  853. {0x1d50d, 0x1d514, +26}, /* 8x 𝔍 ..𝔔 → 𝔧 ..𝔮 Math */
  854. {0x1d56c, 0x1d585, +26}, /* 26x 𝕬 ..𝖅 → 𝖆 ..𝖟 Math */
  855. {0x1d5a0, 0x1d5b9, +26}, /* 26x 𝖠 ..𝖹 → 𝖺 ..𝗓 Math */
  856. {0x1d5d4, 0x1d5ed, +26}, /* 26x 𝗔 ..𝗭 → 𝗮 ..𝘇 Math */
  857. {0x1d608, 0x1d621, +26}, /* 26x 𝘈 ..𝘡 → 𝘢 ..𝘻 Math */
  858. {0x1d63c, 0x1d655, -442}, /* 26x 𝘼 ..𝙕 → 𝒂 ..𝒛 Math */
  859. {0x1d670, 0x1d689, +26}, /* 26x 𝙰 ..𝚉 → 𝚊 ..𝚣 Math */
  860. {0x1d6a8, 0x1d6b8, +26}, /* 17x 𝚨 ..𝚸 → 𝛂 ..𝛒 Math */
  861. {0x1d6e2, 0x1d6f2, +26}, /* 17x 𝛢 ..𝛲 → 𝛼 ..𝜌 Math */
  862. {0x1d71c, 0x1d72c, +26}, /* 17x 𝜜 ..𝜬 → 𝜶 ..𝝆 Math */
  863. {0x1d756, 0x1d766, +26}, /* 17x 𝝖 ..𝝦 → 𝝰 ..𝞀 Math */
  864. {0x1d790, 0x1d7a0, -90}, /* 17x 𝞐 ..𝞠 → 𝜶 ..𝝆 Math */
  865. };
  866. l = 0;
  867. r = n = sizeof(kAstralLower) / sizeof(kAstralLower[0]);
  868. while (l < r) {
  869. m = (l + r) >> 1;
  870. if (kAstralLower[m].b < c) {
  871. l = m + 1;
  872. } else {
  873. r = m;
  874. }
  875. }
  876. if (l < n && kAstralLower[l].a <= c && c <= kAstralLower[l].b) {
  877. return c + kAstralLower[l].d;
  878. } else {
  879. return c;
  880. }
  881. }
  882. }
  883. unsigned bestlineUppercase(unsigned c) {
  884. int m, l, r, n;
  885. if (c < 0200) {
  886. if ('a' <= c && c <= 'z') {
  887. return c - 32;
  888. } else {
  889. return c;
  890. }
  891. } else if (c <= 0xffff) {
  892. if ((0x0101 <= c && c <= 0x0177) || /* 60x ā..ŵ → Ā..ā Watin-A */
  893. (0x01df <= c && c <= 0x01ef) || /* 9x ǟ..ǯ → Ǟ..Ǯ Watin-B */
  894. (0x01f8 <= c && c <= 0x021e) || /* 20x ǹ..ȟ → Ǹ..Ȟ Watin-B */
  895. (0x0222 <= c && c <= 0x0232) || /* 9x ȣ..ȳ → Ȣ..Ȳ Watin-B */
  896. (0x1e01 <= c && c <= 0x1eff)) { /*256x ḁ..ỿ → Ḁ..Ỿ Watin-C */
  897. if (c == 0x0131) return c + 232;
  898. if (c == 0x1e9e) return c;
  899. return c - (c & 1);
  900. } else if (0x01d0 <= c && c <= 0x01dc) {
  901. return c - (~c & 1); /* 7x ǐ..ǜ → Ǐ..Ǜ Watin-B */
  902. } else if (0xab70 <= c && c <= 0xabbf) {
  903. return c - 38864; /* 80x ꭰ ..ꮿ → Ꭰ ..Ꮿ Cherokee Supplement */
  904. } else {
  905. static const struct {
  906. unsigned short a;
  907. unsigned short b;
  908. short d;
  909. } kUpper[] = {
  910. {0x00b5, 0x00b5, +743}, /* 1x µ ..µ → Μ ..Μ Watin */
  911. {0x00e0, 0x00f6, -32}, /* 23x à ..ö → À ..Ö Watin */
  912. {0x00f8, 0x00fe, -32}, /* 7x ø ..þ → Ø ..Þ Watin */
  913. {0x00ff, 0x00ff, +121}, /* 1x ÿ ..ÿ → Ÿ ..Ÿ Watin */
  914. {0x017a, 0x017a, -1}, /* 1x ź ..ź → Ź ..Ź Watin-A */
  915. {0x017c, 0x017c, -1}, /* 1x ż ..ż → Ż ..Ż Watin-A */
  916. {0x017e, 0x017e, -1}, /* 1x ž ..ž → Ž ..Ž Watin-A */
  917. {0x017f, 0x017f, -300}, /* 1x ſ ..ſ → S ..S Watin-A */
  918. {0x0180, 0x0180, +195}, /* 1x ƀ ..ƀ → Ƀ ..Ƀ Watin-B */
  919. {0x0183, 0x0183, -1}, /* 1x ƃ ..ƃ → Ƃ ..Ƃ Watin-B */
  920. {0x0185, 0x0185, -1}, /* 1x ƅ ..ƅ → Ƅ ..Ƅ Watin-B */
  921. {0x0188, 0x0188, -1}, /* 1x ƈ ..ƈ → Ƈ ..Ƈ Watin-B */
  922. {0x018c, 0x018c, -1}, /* 1x ƌ ..ƌ → Ƌ ..Ƌ Watin-B */
  923. {0x0192, 0x0192, -1}, /* 1x ƒ ..ƒ → Ƒ ..Ƒ Watin-B */
  924. {0x0195, 0x0195, +97}, /* 1x ƕ ..ƕ → Ƕ ..Ƕ Watin-B */
  925. {0x0199, 0x0199, -1}, /* 1x ƙ ..ƙ → Ƙ ..Ƙ Watin-B */
  926. {0x019a, 0x019a, +163}, /* 1x ƚ ..ƚ → Ƚ ..Ƚ Watin-B */
  927. {0x019e, 0x019e, +130}, /* 1x ƞ ..ƞ → Ƞ ..Ƞ Watin-B */
  928. {0x01a1, 0x01a1, -1}, /* 1x ơ ..ơ → Ơ ..Ơ Watin-B */
  929. {0x01a3, 0x01a3, -1}, /* 1x ƣ ..ƣ → Ƣ ..Ƣ Watin-B */
  930. {0x01a5, 0x01a5, -1}, /* 1x ƥ ..ƥ → Ƥ ..Ƥ Watin-B */
  931. {0x01a8, 0x01a8, -1}, /* 1x ƨ ..ƨ → Ƨ ..Ƨ Watin-B */
  932. {0x01ad, 0x01ad, -1}, /* 1x ƭ ..ƭ → Ƭ ..Ƭ Watin-B */
  933. {0x01b0, 0x01b0, -1}, /* 1x ư ..ư → Ư ..Ư Watin-B */
  934. {0x01b4, 0x01b4, -1}, /* 1x ƴ ..ƴ → Ƴ ..Ƴ Watin-B */
  935. {0x01b6, 0x01b6, -1}, /* 1x ƶ ..ƶ → Ƶ ..Ƶ Watin-B */
  936. {0x01b9, 0x01b9, -1}, /* 1x ƹ ..ƹ → Ƹ ..Ƹ Watin-B */
  937. {0x01bd, 0x01bd, -1}, /* 1x ƽ ..ƽ → Ƽ ..Ƽ Watin-B */
  938. {0x01bf, 0x01bf, +56}, /* 1x ƿ ..ƿ → Ƿ ..Ƿ Watin-B */
  939. {0x01c5, 0x01c5, -1}, /* 1x Dž ..Dž → DŽ ..DŽ Watin-B */
  940. {0x01c6, 0x01c6, -2}, /* 1x dž ..dž → DŽ ..DŽ Watin-B */
  941. {0x01c8, 0x01c8, -1}, /* 1x Lj ..Lj → LJ ..LJ Watin-B */
  942. {0x01c9, 0x01c9, -2}, /* 1x lj ..lj → LJ ..LJ Watin-B */
  943. {0x01cb, 0x01cb, -1}, /* 1x Nj ..Nj → NJ ..NJ Watin-B */
  944. {0x01cc, 0x01cc, -2}, /* 1x nj ..nj → NJ ..NJ Watin-B */
  945. {0x01ce, 0x01ce, -1}, /* 1x ǎ ..ǎ → Ǎ ..Ǎ Watin-B */
  946. {0x01dd, 0x01dd, -79}, /* 1x ǝ ..ǝ → Ǝ ..Ǝ Watin-B */
  947. {0x01f2, 0x01f2, -1}, /* 1x Dz ..Dz → DZ ..DZ Watin-B */
  948. {0x01f3, 0x01f3, -2}, /* 1x dz ..dz → DZ ..DZ Watin-B */
  949. {0x01f5, 0x01f5, -1}, /* 1x ǵ ..ǵ → Ǵ ..Ǵ Watin-B */
  950. {0x023c, 0x023c, -1}, /* 1x ȼ ..ȼ → Ȼ ..Ȼ Watin-B */
  951. {0x023f, 0x0240,+10815}, /* 2x ȿ ..ɀ → Ȿ ..Ɀ Watin-B */
  952. {0x0242, 0x0242, -1}, /* 1x ɂ ..ɂ → Ɂ ..Ɂ Watin-B */
  953. {0x0247, 0x0247, -1}, /* 1x ɇ ..ɇ → Ɇ ..Ɇ Watin-B */
  954. {0x0249, 0x0249, -1}, /* 1x ɉ ..ɉ → Ɉ ..Ɉ Watin-B */
  955. {0x024b, 0x024b, -1}, /* 1x ɋ ..ɋ → Ɋ ..Ɋ Watin-B */
  956. {0x024d, 0x024d, -1}, /* 1x ɍ ..ɍ → Ɍ ..Ɍ Watin-B */
  957. {0x024f, 0x024f, -1}, /* 1x ɏ ..ɏ → Ɏ ..Ɏ Watin-B */
  958. {0x037b, 0x037d, +130}, /* 3x ͻ ..ͽ → Ͻ ..Ͽ Greek */
  959. {0x03ac, 0x03ac, -38}, /* 1x ά ..ά → Ά ..Ά Greek */
  960. {0x03ad, 0x03af, -37}, /* 3x έ ..ί → Έ ..Ί Greek */
  961. {0x03b1, 0x03c1, -32}, /* 17x α ..ρ → Α ..Ρ Greek */
  962. {0x03c2, 0x03c2, -31}, /* 1x ς ..ς → Σ ..Σ Greek */
  963. {0x03c3, 0x03cb, -32}, /* 9x σ ..ϋ → Σ ..Ϋ Greek */
  964. {0x03cc, 0x03cc, -64}, /* 1x ό ..ό → Ό ..Ό Greek */
  965. {0x03cd, 0x03ce, -63}, /* 2x ύ ..ώ → Ύ ..Ώ Greek */
  966. {0x03d0, 0x03d0, -62}, /* 1x ϐ ..ϐ → Β ..Β Greek */
  967. {0x03d1, 0x03d1, -57}, /* 1x ϑ ..ϑ → Θ ..Θ Greek */
  968. {0x03d5, 0x03d5, -47}, /* 1x ϕ ..ϕ → Φ ..Φ Greek */
  969. {0x03d6, 0x03d6, -54}, /* 1x ϖ ..ϖ → Π ..Π Greek */
  970. {0x03dd, 0x03dd, -1}, /* 1x ϝ ..ϝ → Ϝ ..Ϝ Greek */
  971. {0x03f0, 0x03f0, -86}, /* 1x ϰ ..ϰ → Κ ..Κ Greek */
  972. {0x03f1, 0x03f1, -80}, /* 1x ϱ ..ϱ → Ρ ..Ρ Greek */
  973. {0x03f5, 0x03f5, -96}, /* 1x ϵ ..ϵ → Ε ..Ε Greek */
  974. {0x0430, 0x044f, -32}, /* 32x а ..я → А ..Я Cyrillic */
  975. {0x0450, 0x045f, -80}, /* 16x ѐ ..џ → Ѐ ..Џ Cyrillic */
  976. {0x0461, 0x0461, -1}, /* 1x ѡ ..ѡ → Ѡ ..Ѡ Cyrillic */
  977. {0x0463, 0x0463, -1}, /* 1x ѣ ..ѣ → Ѣ ..Ѣ Cyrillic */
  978. {0x0465, 0x0465, -1}, /* 1x ѥ ..ѥ → Ѥ ..Ѥ Cyrillic */
  979. {0x0473, 0x0473, -1}, /* 1x ѳ ..ѳ → Ѳ ..Ѳ Cyrillic */
  980. {0x0491, 0x0491, -1}, /* 1x ґ ..ґ → Ґ ..Ґ Cyrillic */
  981. {0x0499, 0x0499, -1}, /* 1x ҙ ..ҙ → Ҙ ..Ҙ Cyrillic */
  982. {0x049b, 0x049b, -1}, /* 1x қ ..қ → Қ ..Қ Cyrillic */
  983. {0x0561, 0x0586, -48}, /* 38x ա ..ֆ → Ա ..Ֆ Armenian */
  984. {0x10d0, 0x10fa, +3008}, /* 43x ა ..ჺ → Ა ..Ჺ Georgian */
  985. {0x10fd, 0x10ff, +3008}, /* 3x ჽ ..ჿ → Ჽ ..Ჿ Georgian */
  986. {0x13f8, 0x13fd, -8}, /* 6x ᏸ ..ᏽ → Ᏸ ..Ᏽ Cherokee */
  987. {0x214e, 0x214e, -28}, /* 1x ⅎ ..ⅎ → Ⅎ ..Ⅎ Letterlike */
  988. {0x2170, 0x217f, -16}, /* 16x ⅰ ..ⅿ → Ⅰ ..Ⅿ Numbery */
  989. {0x2184, 0x2184, -1}, /* 1x ↄ ..ↄ → Ↄ ..Ↄ Numbery */
  990. {0x24d0, 0x24e9, -26}, /* 26x ⓐ ..ⓩ → Ⓐ ..Ⓩ Enclosed */
  991. {0x2c30, 0x2c5e, -48}, /* 47x ⰰ ..ⱞ → Ⰰ ..Ⱞ Glagolitic */
  992. {0x2d00, 0x2d25, -7264}, /* 38x ⴀ ..ⴥ → Ⴀ ..Ⴥ Georgian2 */
  993. {0x2d27, 0x2d27, -7264}, /* 1x ⴧ ..ⴧ → Ⴧ ..Ⴧ Georgian2 */
  994. {0x2d2d, 0x2d2d, -7264}, /* 1x ⴭ ..ⴭ → Ⴭ ..Ⴭ Georgian2 */
  995. {0xff41, 0xff5a, -32}, /* 26x a..z → A..Z Dubs */
  996. };
  997. l = 0;
  998. r = n = sizeof(kUpper) / sizeof(kUpper[0]);
  999. while (l < r) {
  1000. m = (l + r) >> 1;
  1001. if (kUpper[m].b < c) {
  1002. l = m + 1;
  1003. } else {
  1004. r = m;
  1005. }
  1006. }
  1007. if (l < n && kUpper[l].a <= c && c <= kUpper[l].b) {
  1008. return c + kUpper[l].d;
  1009. } else {
  1010. return c;
  1011. }
  1012. }
  1013. } else {
  1014. static const struct {
  1015. unsigned a;
  1016. unsigned b;
  1017. short d;
  1018. } kAstralUpper[] = {
  1019. {0x10428, 0x1044f, -40}, /* 40x 𐐨..𐑏 → 𐐀..𐐧 Deseret */
  1020. {0x104d8, 0x104fb, -40}, /* 36x 𐓘..𐓻 → 𐒰..𐓓 Osage */
  1021. {0x1d41a, 0x1d433, -26}, /* 26x 𝐚..𝐳 → 𝐀..𝐙 Math */
  1022. {0x1d456, 0x1d467, -26}, /* 18x 𝑖..𝑧 → 𝐼..𝑍 Math */
  1023. {0x1d482, 0x1d49b, -26}, /* 26x 𝒂..𝒛 → 𝑨..𝒁 Math */
  1024. {0x1d4c8, 0x1d4cf, -26}, /* 8x 𝓈..𝓏 → 𝒮..𝒵 Math */
  1025. {0x1d4ea, 0x1d503, -26}, /* 26x 𝓪..𝔃 → 𝓐..𝓩 Math */
  1026. {0x1d527, 0x1d52e, -26}, /* 8x 𝔧..𝔮 → 𝔍..𝔔 Math */
  1027. {0x1d586, 0x1d59f, -26}, /* 26x 𝖆..𝖟 → 𝕬..𝖅 Math */
  1028. {0x1d5ba, 0x1d5d3, -26}, /* 26x 𝖺..𝗓 → 𝖠..𝖹 Math */
  1029. {0x1d5ee, 0x1d607, -26}, /* 26x 𝗮..𝘇 → 𝗔..𝗭 Math */
  1030. {0x1d622, 0x1d63b, -26}, /* 26x 𝘢..𝘻 → 𝘈..𝘡 Math */
  1031. {0x1d68a, 0x1d6a3, +442}, /* 26x 𝒂..𝒛 → 𝘼..𝙕 Math */
  1032. {0x1d6c2, 0x1d6d2, -26}, /* 26x 𝚊..𝚣 → 𝙰..𝚉 Math */
  1033. {0x1d6fc, 0x1d70c, -26}, /* 17x 𝛂..𝛒 → 𝚨..𝚸 Math */
  1034. {0x1d736, 0x1d746, -26}, /* 17x 𝛼..𝜌 → 𝛢..𝛲 Math */
  1035. {0x1d770, 0x1d780, -26}, /* 17x 𝜶..𝝆 → 𝜜..𝜬 Math */
  1036. {0x1d770, 0x1d756, -26}, /* 17x 𝝰..𝞀 → 𝝖..𝝦 Math */
  1037. {0x1d736, 0x1d790, -90}, /* 17x 𝜶..𝝆 → 𝞐..𝞠 Math */
  1038. };
  1039. l = 0;
  1040. r = n = sizeof(kAstralUpper) / sizeof(kAstralUpper[0]);
  1041. while (l < r) {
  1042. m = (l + r) >> 1;
  1043. if (kAstralUpper[m].b < c) {
  1044. l = m + 1;
  1045. } else {
  1046. r = m;
  1047. }
  1048. }
  1049. if (l < n && kAstralUpper[l].a <= c && c <= kAstralUpper[l].b) {
  1050. return c + kAstralUpper[l].d;
  1051. } else {
  1052. return c;
  1053. }
  1054. }
  1055. }
  1056. char bestlineNotSeparator(unsigned c) {
  1057. return !bestlineIsSeparator(c);
  1058. }
  1059. static unsigned GetMirror(const unsigned short A[][2], size_t n, unsigned c) {
  1060. int l, m, r;
  1061. l = 0;
  1062. r = n - 1;
  1063. while (l <= r) {
  1064. m = (l + r) >> 1;
  1065. if (A[m][0] < c) {
  1066. l = m + 1;
  1067. } else if (A[m][0] > c) {
  1068. r = m - 1;
  1069. } else {
  1070. return A[m][1];
  1071. }
  1072. }
  1073. return 0;
  1074. }
  1075. unsigned bestlineMirrorLeft(unsigned c) {
  1076. static const unsigned short kMirrorRight[][2] = {
  1077. {L')', L'('}, {L']', L'['}, {L'}', L'{'}, {L'⁆', L'⁅'},
  1078. {L'⁾', L'⁽'}, {L'₎', L'₍'}, {L'⌉', L'⌈'}, {L'⌋', L'⌊'},
  1079. {L'〉', L'〈'}, {L'❩', L'❨'}, {L'❫', L'❪'}, {L'❭', L'❬'},
  1080. {L'❯', L'❮'}, {L'❱', L'❰'}, {L'❳', L'❲'}, {L'❵', L'❴'},
  1081. {L'⟆', L'⟅'}, {L'⟧', L'⟦'}, {L'⟩', L'⟨'}, {L'⟫', L'⟪'},
  1082. {L'⟭', L'⟬'}, {L'⟯', L'⟮'}, {L'⦄', L'⦃'}, {L'⦆', L'⦅'},
  1083. {L'⦈', L'⦇'}, {L'⦊', L'⦉'}, {L'⦌', L'⦋'}, {L'⦎', L'⦏'},
  1084. {L'⦐', L'⦍'}, {L'⦒', L'⦑'}, {L'⦔', L'⦓'}, {L'⦘', L'⦗'},
  1085. {L'⧙', L'⧘'}, {L'⧛', L'⧚'}, {L'⧽', L'⧼'}, {L'﹚', L'﹙'},
  1086. {L'﹜', L'﹛'}, {L'﹞', L'﹝'}, {L')', L'('}, {L']', L'['},
  1087. {L'}', L'{'}, {L'」', L'「'},
  1088. };
  1089. return GetMirror(kMirrorRight,
  1090. sizeof(kMirrorRight) / sizeof(kMirrorRight[0]),
  1091. c);
  1092. }
  1093. unsigned bestlineMirrorRight(unsigned c) {
  1094. static const unsigned short kMirrorLeft[][2] = {
  1095. {L'(', L')'}, {L'[', L']'}, {L'{', L'}'}, {L'⁅', L'⁆'},
  1096. {L'⁽', L'⁾'}, {L'₍', L'₎'}, {L'⌈', L'⌉'}, {L'⌊', L'⌋'},
  1097. {L'〈', L'〉'}, {L'❨', L'❩'}, {L'❪', L'❫'}, {L'❬', L'❭'},
  1098. {L'❮', L'❯'}, {L'❰', L'❱'}, {L'❲', L'❳'}, {L'❴', L'❵'},
  1099. {L'⟅', L'⟆'}, {L'⟦', L'⟧'}, {L'⟨', L'⟩'}, {L'⟪', L'⟫'},
  1100. {L'⟬', L'⟭'}, {L'⟮', L'⟯'}, {L'⦃', L'⦄'}, {L'⦅', L'⦆'},
  1101. {L'⦇', L'⦈'}, {L'⦉', L'⦊'}, {L'⦋', L'⦌'}, {L'⦍', L'⦐'},
  1102. {L'⦏', L'⦎'}, {L'⦑', L'⦒'}, {L'⦓', L'⦔'}, {L'⦗', L'⦘'},
  1103. {L'⧘', L'⧙'}, {L'⧚', L'⧛'}, {L'⧼', L'⧽'}, {L'﹙', L'﹚'},
  1104. {L'﹛', L'﹜'}, {L'﹝', L'﹞'}, {L'(', L')'}, {L'[', L']'},
  1105. {L'{', L'}'}, {L'「', L'」'},
  1106. };
  1107. return GetMirror(kMirrorLeft,
  1108. sizeof(kMirrorLeft) / sizeof(kMirrorLeft[0]),
  1109. c);
  1110. }
  1111. char bestlineIsXeparator(unsigned c) {
  1112. return (bestlineIsSeparator(c) &&
  1113. !bestlineMirrorLeft(c) &&
  1114. !bestlineMirrorRight(c));
  1115. }
  1116. static unsigned Capitalize(unsigned c) {
  1117. if (!iscapital) {
  1118. c = bestlineUppercase(c);
  1119. iscapital = 1;
  1120. }
  1121. return c;
  1122. }
  1123. static inline int Bsr(unsigned long long x) {
  1124. #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
  1125. int b;
  1126. b = __builtin_clzll(x);
  1127. b ^= sizeof(unsigned long long) * CHAR_BIT - 1;
  1128. return b;
  1129. #else
  1130. static const char kDebruijn[64] = {
  1131. 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61,
  1132. 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62,
  1133. 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45,
  1134. 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63,
  1135. };
  1136. x |= x >> 1;
  1137. x |= x >> 2;
  1138. x |= x >> 4;
  1139. x |= x >> 8;
  1140. x |= x >> 16;
  1141. x |= x >> 32;
  1142. return kDebruijn[(x * 0x03f79d71b4cb0a89) >> 58];
  1143. #endif
  1144. }
  1145. static struct rune DecodeUtf8(int c) {
  1146. struct rune r;
  1147. if (c < 252) {
  1148. r.n = Bsr(255 & ~c);
  1149. r.c = c & (((1 << r.n) - 1) | 3);
  1150. r.n = 6 - r.n;
  1151. } else {
  1152. r.c = c & 3;
  1153. r.n = 5;
  1154. }
  1155. return r;
  1156. }
  1157. static unsigned long long EncodeUtf8(unsigned c) {
  1158. static const unsigned short kTpEnc[32 - 7] = {
  1159. 1|0300<<8, 1|0300<<8, 1|0300<<8, 1|0300<<8, 2|0340<<8,
  1160. 2|0340<<8, 2|0340<<8, 2|0340<<8, 2|0340<<8, 3|0360<<8,
  1161. 3|0360<<8, 3|0360<<8, 3|0360<<8, 3|0360<<8, 4|0370<<8,
  1162. 4|0370<<8, 4|0370<<8, 4|0370<<8, 4|0370<<8, 5|0374<<8,
  1163. 5|0374<<8, 5|0374<<8, 5|0374<<8, 5|0374<<8, 5|0374<<8,
  1164. };
  1165. int e, n;
  1166. unsigned long long w;
  1167. if (c < 0200) return c;
  1168. e = kTpEnc[Bsr(c) - 7];
  1169. n = e & 0xff;
  1170. w = 0;
  1171. do {
  1172. w |= 0200 | (c & 077);
  1173. w <<= 8;
  1174. c >>= 6;
  1175. } while (--n);
  1176. return c | w | e >> 8;
  1177. }
  1178. static struct rune GetUtf8(const char *p, size_t n) {
  1179. struct rune r;
  1180. if ((r.n = r.c = 0) < n && (r.c = p[r.n++] & 255) >= 0300) {
  1181. r.c = DecodeUtf8(r.c).c;
  1182. while (r.n < n && (p[r.n] & 0300) == 0200) {
  1183. r.c = r.c << 6 | (p[r.n++] & 077);
  1184. }
  1185. }
  1186. return r;
  1187. }
  1188. static char *FormatUnsigned(char *p, unsigned x) {
  1189. char t;
  1190. size_t i, a, b;
  1191. i = 0;
  1192. do {
  1193. p[i++] = x % 10 + '0';
  1194. x = x / 10;
  1195. } while (x > 0);
  1196. p[i] = '\0';
  1197. if (i) {
  1198. for (a = 0, b = i - 1; a < b; ++a, --b) {
  1199. t = p[a];
  1200. p[a] = p[b];
  1201. p[b] = t;
  1202. }
  1203. }
  1204. return p + i;
  1205. }
  1206. static void abInit(struct abuf *a) {
  1207. a->len = 0;
  1208. a->cap = 16;
  1209. a->b = (char *)malloc(a->cap);
  1210. a->b[0] = 0;
  1211. }
  1212. static char abGrow(struct abuf *a, int need) {
  1213. int cap;
  1214. char *b;
  1215. cap = a->cap;
  1216. do cap += cap / 2;
  1217. while (cap < need);
  1218. if (!(b = (char *)realloc(a->b, cap * sizeof(*a->b)))) return 0;
  1219. a->cap = cap;
  1220. a->b = b;
  1221. return 1;
  1222. }
  1223. static void abAppendw(struct abuf *a, unsigned long long w) {
  1224. char *p;
  1225. if (a->len + 8 > a->cap && !abGrow(a, a->len + 8)) return;
  1226. p = a->b + a->len;
  1227. p[0] = (0x00000000000000FF & w) >> 000;
  1228. p[1] = (0x000000000000FF00 & w) >> 010;
  1229. p[2] = (0x0000000000FF0000 & w) >> 020;
  1230. p[3] = (0x00000000FF000000 & w) >> 030;
  1231. p[4] = (0x000000FF00000000 & w) >> 040;
  1232. p[5] = (0x0000FF0000000000 & w) >> 050;
  1233. p[6] = (0x00FF000000000000 & w) >> 060;
  1234. p[7] = (0xFF00000000000000 & w) >> 070;
  1235. a->len += w ? (Bsr(w) >> 3) + 1 : 1;
  1236. }
  1237. static void abAppend(struct abuf *a, const char *s, int len) {
  1238. if (a->len + len + 1 > a->cap && !abGrow(a, a->len + len + 1)) return;
  1239. memcpy(a->b + a->len, s, len);
  1240. a->b[a->len + len] = 0;
  1241. a->len += len;
  1242. }
  1243. static void abAppends(struct abuf *a, const char *s) {
  1244. abAppend(a, s, strlen(s));
  1245. }
  1246. static void abAppendu(struct abuf *a, unsigned u) {
  1247. char b[11];
  1248. abAppend(a, b, FormatUnsigned(b, u) - b);
  1249. }
  1250. static void abFree(struct abuf *a) {
  1251. free(a->b);
  1252. a->b = 0;
  1253. }
  1254. static size_t GetFdSize(int fd) {
  1255. struct stat st;
  1256. st.st_size = 0;
  1257. fstat(fd, &st);
  1258. return st.st_size;
  1259. }
  1260. static char IsCharDev(int fd) {
  1261. struct stat st;
  1262. st.st_mode = 0;
  1263. fstat(fd, &st);
  1264. return (st.st_mode & S_IFMT) == S_IFCHR;
  1265. }
  1266. static int WaitUntilReady(int fd, int events) {
  1267. struct pollfd p[1];
  1268. p[0].fd = fd;
  1269. p[0].events = events;
  1270. return poll(p, 1, -1);
  1271. }
  1272. static char HasPendingInput(int fd) {
  1273. struct pollfd p[1];
  1274. p[0].fd = fd;
  1275. p[0].events = POLLIN;
  1276. return poll(p, 1, 0) == 1;
  1277. }
  1278. static char *GetLineBlock(FILE *f) {
  1279. ssize_t rc;
  1280. char *p = 0;
  1281. size_t n, c = 0;
  1282. if ((rc = getdelim(&p, &c, '\n', f)) != EOF) {
  1283. for (n = rc; n; --n) {
  1284. if (p[n - 1] == '\r' || p[n - 1] == '\n') {
  1285. p[n - 1] = 0;
  1286. } else {
  1287. break;
  1288. }
  1289. }
  1290. return p;
  1291. } else {
  1292. free(p);
  1293. return 0;
  1294. }
  1295. }
  1296. long bestlineReadCharacter(int fd, char *p, unsigned long n) {
  1297. int e;
  1298. size_t i;
  1299. ssize_t rc;
  1300. struct rune r;
  1301. unsigned char c;
  1302. enum { kAscii, kUtf8, kEsc, kCsi1, kCsi2, kSs, kNf, kStr, kStr2, kDone } t;
  1303. i = 0;
  1304. r.c = 0;
  1305. r.n = 0;
  1306. e = errno;
  1307. t = kAscii;
  1308. if (n) p[0] = 0;
  1309. do {
  1310. for (;;) {
  1311. if (gotint) {
  1312. errno = EINTR;
  1313. return -1;
  1314. }
  1315. if (n) {
  1316. rc = read(fd,&c,1);
  1317. } else {
  1318. rc = read(fd,0,0);
  1319. }
  1320. if (rc == -1 && errno == EINTR) {
  1321. if (!i) {
  1322. return -1;
  1323. }
  1324. } else if (rc == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
  1325. if (WaitUntilReady(fd, POLLIN) == -1) {
  1326. if (rc == -1 && errno == EINTR) {
  1327. if (!i) {
  1328. return -1;
  1329. }
  1330. } else {
  1331. return -1;
  1332. }
  1333. }
  1334. } else if (rc == -1) {
  1335. return -1;
  1336. } else if (!rc) {
  1337. if (!i) {
  1338. errno = e;
  1339. return 0;
  1340. } else {
  1341. errno = EILSEQ;
  1342. return -1;
  1343. }
  1344. } else {
  1345. break;
  1346. }
  1347. }
  1348. if (i + 1 < n) {
  1349. p[i] = c;
  1350. p[i+1] = 0;
  1351. } else if (i < n) {
  1352. p[i] = 0;
  1353. }
  1354. ++i;
  1355. switch (t) {
  1356. Whoopsie:
  1357. if (n) p[0] = c;
  1358. t = kAscii;
  1359. i = 1;
  1360. /* fallthrough */
  1361. case kAscii:
  1362. if (c < 0200) {
  1363. if (c == 033) {
  1364. t = kEsc;
  1365. } else {
  1366. t = kDone;
  1367. }
  1368. } else if (c >= 0300) {
  1369. t = kUtf8;
  1370. r = DecodeUtf8(c);
  1371. } else {
  1372. /* ignore overlong sequences */
  1373. }
  1374. break;
  1375. case kUtf8:
  1376. if ((c & 0300) == 0200) {
  1377. r.c <<= 6;
  1378. r.c |= c & 077;
  1379. if (!--r.n) {
  1380. switch (r.c) {
  1381. case 033:
  1382. t = kEsc; /* parsed but not canonicalized */
  1383. break;
  1384. case 0x9b:
  1385. t = kCsi1; /* unusual but legal */
  1386. break;
  1387. case 0x8e: /* SS2 (Single Shift Two) */
  1388. case 0x8f: /* SS3 (Single Shift Three) */
  1389. t = kSs;
  1390. break;
  1391. case 0x90: /* DCS (Device Control String) */
  1392. case 0x98: /* SOS (Start of String) */
  1393. case 0x9d: /* OSC (Operating System Command) */
  1394. case 0x9e: /* PM (Privacy Message) */
  1395. case 0x9f: /* APC (Application Program Command) */
  1396. t = kStr;
  1397. break;
  1398. default:
  1399. t = kDone;
  1400. break;
  1401. }
  1402. }
  1403. } else {
  1404. goto Whoopsie; /* ignore underlong sequences if not eof */
  1405. }
  1406. break;
  1407. case kEsc:
  1408. if (0x20 <= c && c <= 0x2f) { /* Nf */
  1409. /*
  1410. * Almost no one uses ANSI Nf sequences
  1411. * They overlaps with alt+graphic keystrokes
  1412. * We care more about being able to type alt-/
  1413. */
  1414. if (c == ' ' || c == '#') {
  1415. t = kNf;
  1416. } else {
  1417. t = kDone;
  1418. }
  1419. } else if (0x30 <= c && c <= 0x3f) { /* Fp */
  1420. t = kDone;
  1421. } else if (0x20 <= c && c <= 0x5F) { /* Fe */
  1422. switch (c) {
  1423. case '[':
  1424. t = kCsi1;
  1425. break;
  1426. case 'N': /* SS2 (Single Shift Two) */
  1427. case 'O': /* SS3 (Single Shift Three) */
  1428. t = kSs;
  1429. break;
  1430. case 'P': /* DCS (Device Control String) */
  1431. case 'X': /* SOS (Start of String) */
  1432. case ']': /* OSC (Operating System Command) */
  1433. case '^': /* PM (Privacy Message) */
  1434. case '_': /* APC (Application Program Command) */
  1435. t = kStr;
  1436. break;
  1437. default:
  1438. t = kDone;
  1439. break;
  1440. }
  1441. } else if (0x60 <= c && c <= 0x7e) { /* Fs */
  1442. t = kDone;
  1443. } else if (c == 033) {
  1444. if (i < 3) {
  1445. /* alt chording */
  1446. } else {
  1447. t = kDone; /* esc mashing */
  1448. i = 1;
  1449. }
  1450. } else {
  1451. t = kDone;
  1452. }
  1453. break;
  1454. case kSs:
  1455. t = kDone;
  1456. break;
  1457. case kNf:
  1458. if (0x30 <= c && c <= 0x7e) {
  1459. t = kDone;
  1460. } else if (!(0x20 <= c && c <= 0x2f)) {
  1461. goto Whoopsie;
  1462. }
  1463. break;
  1464. case kCsi1:
  1465. if (0x20 <= c && c <= 0x2f) {
  1466. t = kCsi2;
  1467. } else if (c == '[' && ((i == 3) ||
  1468. (i == 4 && p[1] == 033))) {
  1469. /* linux function keys */
  1470. } else if (0x40 <= c && c <= 0x7e) {
  1471. t = kDone;
  1472. } else if (!(0x30 <= c && c <= 0x3f)) {
  1473. goto Whoopsie;
  1474. }
  1475. break;
  1476. case kCsi2:
  1477. if (0x40 <= c && c <= 0x7e) {
  1478. t = kDone;
  1479. } else if (!(0x20 <= c && c <= 0x2f)) {
  1480. goto Whoopsie;
  1481. }
  1482. break;
  1483. case kStr:
  1484. switch (c) {
  1485. case '\a':
  1486. t = kDone;
  1487. break;
  1488. case 0033: /* ESC */
  1489. case 0302: /* C1 (UTF-8) */
  1490. t = kStr2;
  1491. break;
  1492. default:
  1493. break;
  1494. }
  1495. break;
  1496. case kStr2:
  1497. switch (c) {
  1498. case '\a':
  1499. case '\\': /* ST (ASCII) */
  1500. case 0234: /* ST (UTF-8) */
  1501. t = kDone;
  1502. break;
  1503. default:
  1504. t = kStr;
  1505. break;
  1506. }
  1507. break;
  1508. default:
  1509. assert(0);
  1510. }
  1511. } while (t != kDone);
  1512. errno = e;
  1513. return i;
  1514. }
  1515. static char *GetLineChar(int fin, int fout) {
  1516. size_t got;
  1517. ssize_t rc;
  1518. char seq[16];
  1519. struct abuf a;
  1520. struct sigaction sa[3];
  1521. abInit(&a);
  1522. gotint = 0;
  1523. sigemptyset(&sa->sa_mask);
  1524. sa->sa_flags = 0;
  1525. sa->sa_handler = bestlineOnInt;
  1526. sigaction(SIGINT,sa,sa+1);
  1527. sigaction(SIGQUIT,sa,sa+2);
  1528. for (;;) {
  1529. if (gotint) {
  1530. rc = -1;
  1531. break;
  1532. }
  1533. if ((rc = bestlineReadCharacter(fin, seq, sizeof(seq))) == -1) {
  1534. if (errno == EAGAIN || errno == EWOULDBLOCK) {
  1535. if (WaitUntilReady(fin, POLLIN) > 0) {
  1536. continue;
  1537. }
  1538. }
  1539. if (errno == EINTR) {
  1540. continue;
  1541. } else {
  1542. break;
  1543. }
  1544. }
  1545. if (!(got = rc)) {
  1546. if (a.len) {
  1547. break;
  1548. } else {
  1549. rc = -1;
  1550. break;
  1551. }
  1552. }
  1553. if (seq[0] == '\r') {
  1554. if (HasPendingInput(fin)) {
  1555. if ((rc = bestlineReadCharacter(fin, seq + 1, sizeof(seq) - 1)) > 0) {
  1556. if (seq[0] == '\n') {
  1557. break;
  1558. }
  1559. } else {
  1560. rc = -1;
  1561. break;
  1562. }
  1563. } else {
  1564. write(fout, "\n", 1);
  1565. break;
  1566. }
  1567. } else if (seq[0] == Ctrl('D')) {
  1568. break;
  1569. } else if (seq[0] == '\n') {
  1570. break;
  1571. } else if (seq[0] == '\b') {
  1572. while (a.len && (a.b[a.len - 1] & 0300) == 0200) --a.len;
  1573. if (a.len) --a.len;
  1574. }
  1575. if (!IsControl(seq[0])) {
  1576. abAppend(&a, seq, got);
  1577. }
  1578. }
  1579. sigaction(SIGQUIT,sa+2,0);
  1580. sigaction(SIGINT,sa+1,0);
  1581. if (gotint) {
  1582. abFree(&a);
  1583. raise(gotint);
  1584. errno = EINTR;
  1585. rc = -1;
  1586. }
  1587. if (rc != -1) {
  1588. return a.b;
  1589. } else {
  1590. abFree(&a);
  1591. return 0;
  1592. }
  1593. }
  1594. static char *GetLine(FILE *in, FILE *out) {
  1595. if (!IsCharDev(fileno(in))) {
  1596. return GetLineBlock(in);
  1597. } else {
  1598. return GetLineChar(fileno(in), fileno(out));
  1599. }
  1600. }
  1601. static char *Copy(char *d, const char *s, size_t n) {
  1602. memcpy(d, s, n);
  1603. return d + n;
  1604. }
  1605. static int CompareStrings(const char *a, const char *b) {
  1606. size_t i;
  1607. int x, y, c;
  1608. for (i = 0;; ++i) {
  1609. x = bestlineLowercase(a[i] & 255);
  1610. y = bestlineLowercase(b[i] & 255);
  1611. if ((c = x - y) || !x) {
  1612. return c;
  1613. }
  1614. }
  1615. }
  1616. static const char *FindSubstringReverse(const char *p, size_t n,
  1617. const char *q, size_t m) {
  1618. size_t i;
  1619. if (m <= n) {
  1620. n -= m;
  1621. do {
  1622. for (i = 0; i < m; ++i) {
  1623. if (p[n + i] != q[i]) {
  1624. break;
  1625. }
  1626. }
  1627. if (i == m) {
  1628. return p + n;
  1629. }
  1630. } while (n--);
  1631. }
  1632. return 0;
  1633. }
  1634. static int ParseUnsigned(const char *s, void *e) {
  1635. int c, x;
  1636. for (x = 0; (c = *s++);) {
  1637. if ('0' <= c && c <= '9') {
  1638. x = Min(c - '0' + x * 10, 32767);
  1639. } else {
  1640. break;
  1641. }
  1642. }
  1643. if (e) *(const char **)e = s;
  1644. return x;
  1645. }
  1646. /**
  1647. * Returns UNICODE CJK Monospace Width of string.
  1648. *
  1649. * Control codes and ANSI sequences have a width of zero. We only parse
  1650. * a limited subset of ANSI here since we don't store ANSI codes in the
  1651. * linenoiseState::buf, but we do encourage CSI color codes in prompts.
  1652. */
  1653. static size_t GetMonospaceWidth(const char *p, size_t n, char *out_haswides) {
  1654. int c, d;
  1655. size_t i, w;
  1656. struct rune r;
  1657. char haswides;
  1658. enum { kAscii, kUtf8, kEsc, kCsi1, kCsi2 } t;
  1659. for (haswides = r.c = r.n = w = i = 0, t = kAscii; i < n; ++i) {
  1660. c = p[i] & 255;
  1661. switch (t) {
  1662. Whoopsie:
  1663. t = kAscii;
  1664. /* fallthrough */
  1665. case kAscii:
  1666. if (c < 0200) {
  1667. if (c == 033) {
  1668. t = kEsc;
  1669. } else {
  1670. ++w;
  1671. }
  1672. } else if (c >= 0300) {
  1673. t = kUtf8;
  1674. r = DecodeUtf8(c);
  1675. }
  1676. break;
  1677. case kUtf8:
  1678. if ((c & 0300) == 0200) {
  1679. r.c <<= 6;
  1680. r.c |= c & 077;
  1681. if (!--r.n) {
  1682. d = GetMonospaceCharacterWidth(r.c);
  1683. d = Max(0, d);
  1684. w += d;
  1685. haswides |= d > 1;
  1686. t = kAscii;
  1687. break;
  1688. }
  1689. } else {
  1690. goto Whoopsie;
  1691. }
  1692. break;
  1693. case kEsc:
  1694. if (c == '[') {
  1695. t = kCsi1;
  1696. } else {
  1697. t = kAscii;
  1698. }
  1699. break;
  1700. case kCsi1:
  1701. if (0x20 <= c && c <= 0x2f) {
  1702. t = kCsi2;
  1703. } else if (0x40 <= c && c <= 0x7e) {
  1704. t = kAscii;
  1705. } else if (!(0x30 <= c && c <= 0x3f)) {
  1706. goto Whoopsie;
  1707. }
  1708. break;
  1709. case kCsi2:
  1710. if (0x40 <= c && c <= 0x7e) {
  1711. t = kAscii;
  1712. } else if (!(0x20 <= c && c <= 0x2f)) {
  1713. goto Whoopsie;
  1714. }
  1715. break;
  1716. default:
  1717. assert(0);
  1718. }
  1719. }
  1720. if (out_haswides) {
  1721. *out_haswides = haswides;
  1722. }
  1723. return w;
  1724. }
  1725. static int bestlineIsUnsupportedTerm(void) {
  1726. size_t i;
  1727. char *term;
  1728. static char once, res;
  1729. if (!once) {
  1730. if ((term = getenv("TERM"))) {
  1731. for (i = 0; i < sizeof(kUnsupported) / sizeof(*kUnsupported); i++) {
  1732. if (!CompareStrings(term,kUnsupported[i])) {
  1733. res = 1;
  1734. break;
  1735. }
  1736. }
  1737. }
  1738. once = 1;
  1739. }
  1740. return res;
  1741. }
  1742. static int enableRawMode(int fd) {
  1743. struct termios raw;
  1744. struct sigaction sa;
  1745. if (tcgetattr(fd,&orig_termios) != -1) {
  1746. raw = orig_termios;
  1747. raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  1748. raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  1749. raw.c_iflag |= IUTF8;
  1750. raw.c_cflag |= CS8;
  1751. raw.c_cc[VMIN] = 1;
  1752. raw.c_cc[VTIME] = 0;
  1753. if (tcsetattr(fd,TCSANOW,&raw) != -1) {
  1754. sa.sa_flags = 0;
  1755. sa.sa_handler = bestlineOnCont;
  1756. sigemptyset(&sa.sa_mask);
  1757. sigaction(SIGCONT,&sa,&orig_cont);
  1758. sa.sa_handler = bestlineOnWinch;
  1759. sigaction(SIGWINCH,&sa,&orig_winch);
  1760. rawmode = fd;
  1761. gotwinch = 0;
  1762. gotcont = 0;
  1763. return 0;
  1764. }
  1765. }
  1766. errno = ENOTTY;
  1767. return -1;
  1768. }
  1769. static void bestlineUnpause(int fd) {
  1770. if (ispaused) {
  1771. tcflow(fd, TCOON);
  1772. ispaused = 0;
  1773. }
  1774. }
  1775. void bestlineDisableRawMode(void) {
  1776. if (rawmode != -1) {
  1777. bestlineUnpause(rawmode);
  1778. sigaction(SIGCONT,&orig_cont,0);
  1779. sigaction(SIGWINCH,&orig_winch,0);
  1780. tcsetattr(rawmode,TCSANOW,&orig_termios);
  1781. rawmode = -1;
  1782. }
  1783. }
  1784. static int bestlineWrite(int fd, const void *p, size_t n) {
  1785. ssize_t rc;
  1786. size_t wrote;
  1787. do {
  1788. for (;;) {
  1789. if (gotint) {
  1790. errno = EINTR;
  1791. return -1;
  1792. }
  1793. if (ispaused) {
  1794. return 0;
  1795. }
  1796. rc = write(fd, p, n);
  1797. if (rc == -1 && errno == EINTR) {
  1798. continue;
  1799. } else if (rc == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
  1800. if (WaitUntilReady(fd, POLLOUT) == -1) {
  1801. if (errno == EINTR) {
  1802. continue;
  1803. } else {
  1804. return -1;
  1805. }
  1806. }
  1807. } else {
  1808. break;
  1809. }
  1810. }
  1811. if (rc != -1) {
  1812. wrote = rc;
  1813. n -= wrote;
  1814. p = (char *)p + wrote;
  1815. } else {
  1816. return -1;
  1817. }
  1818. } while (n);
  1819. return 0;
  1820. }
  1821. static int bestlineWriteStr(int fd, const char *p) {
  1822. return bestlineWrite(fd, p, strlen(p));
  1823. }
  1824. static ssize_t bestlineRead(int fd, char *buf, size_t size,
  1825. struct bestlineState *l) {
  1826. size_t got;
  1827. ssize_t rc;
  1828. int refreshme;
  1829. do {
  1830. refreshme = 0;
  1831. if (gotint) {
  1832. errno = EINTR;
  1833. return -1;
  1834. }
  1835. if (gotcont && rawmode != -1) {
  1836. enableRawMode(rawmode);
  1837. if (l) refreshme = 1;
  1838. }
  1839. if (gotwinch && l) {
  1840. refreshme = 1;
  1841. }
  1842. if (refreshme) bestlineRefreshLine(l);
  1843. rc = bestlineReadCharacter(fd, buf, size);
  1844. } while (rc == -1 && errno == EINTR);
  1845. if (rc != -1) {
  1846. got = rc;
  1847. if (got > 0 && l) {
  1848. memcpy(l->seq[1], l->seq[0], sizeof(l->seq[0]));
  1849. memset(l->seq[0], 0, sizeof(l->seq[0]));
  1850. memcpy(l->seq[0], buf, Min(Min(size, got), sizeof(l->seq[0]) - 1));
  1851. }
  1852. }
  1853. return rc;
  1854. }
  1855. /**
  1856. * Returns number of columns in current terminal.
  1857. *
  1858. * 1. Checks COLUMNS environment variable (set by Emacs)
  1859. * 2. Tries asking termios (works for pseudoteletypewriters)
  1860. * 3. Falls back to inband signalling (works w/ pipe or serial)
  1861. * 4. Otherwise we conservatively assume 80 columns
  1862. *
  1863. * @param ws should be initialized by caller to zero before first call
  1864. * @param ifd is input file descriptor
  1865. * @param ofd is output file descriptor
  1866. * @return window size
  1867. */
  1868. static struct winsize GetTerminalSize(struct winsize ws, int ifd, int ofd) {
  1869. int x;
  1870. ssize_t n;
  1871. char *p, *s, b[16];
  1872. ioctl(ofd, TIOCGWINSZ, &ws);
  1873. if ((!ws.ws_row &&
  1874. (s = getenv("ROWS")) &&
  1875. (x = ParseUnsigned(s, 0)))) {
  1876. ws.ws_row = x;
  1877. }
  1878. if ((!ws.ws_col &&
  1879. (s = getenv("COLUMNS")) &&
  1880. (x = ParseUnsigned(s, 0)))) {
  1881. ws.ws_col = x;
  1882. }
  1883. if (((!ws.ws_col || !ws.ws_row) &&
  1884. bestlineRead(ifd,0,0,0) != -1 &&
  1885. bestlineWriteStr(ofd,
  1886. "\0337" /* save position */
  1887. "\033[9979;9979H" /* move cursor to bottom right corner */
  1888. "\033[6n" /* report position */
  1889. "\0338") != -1 && /* restore position */
  1890. (n = bestlineRead(ifd,b,sizeof(b),0)) != -1 &&
  1891. n && b[0] == 033 && b[1] == '[' && b[n - 1] == 'R')) {
  1892. p = b+2;
  1893. if ((x = ParseUnsigned(p,&p))) ws.ws_row = x;
  1894. if (*p++ == ';' && (x = ParseUnsigned(p,0))) ws.ws_col = x;
  1895. }
  1896. if (!ws.ws_col) ws.ws_col = 80;
  1897. if (!ws.ws_row) ws.ws_row = 24;
  1898. return ws;
  1899. }
  1900. /* Clear the screen. Used to handle ctrl+l */
  1901. void bestlineClearScreen(int fd) {
  1902. bestlineWriteStr(fd,
  1903. "\033[H" /* move cursor to top left corner */
  1904. "\033[2J"); /* erase display */
  1905. }
  1906. static void bestlineBeep(void) {
  1907. /* THE TERMINAL BELL IS DEAD - HISTORY HAS KILLED IT */
  1908. }
  1909. static char bestlineGrow(struct bestlineState *ls, size_t n) {
  1910. char *p;
  1911. size_t m;
  1912. m = ls->buflen;
  1913. if (m >= n) return 1;
  1914. do m += m >> 1;
  1915. while (m < n);
  1916. if (!(p = (char *)realloc(ls->buf, m * sizeof(*ls->buf)))) return 0;
  1917. ls->buf = p;
  1918. ls->buflen = m;
  1919. return 1;
  1920. }
  1921. /* This is an helper function for bestlineEdit() and is called when the
  1922. * user types the <tab> key in order to complete the string currently in the
  1923. * input.
  1924. *
  1925. * The state of the editing is encapsulated into the pointed bestlineState
  1926. * structure as described in the structure definition. */
  1927. static ssize_t bestlineCompleteLine(struct bestlineState *ls, char *seq, int size) {
  1928. ssize_t nread;
  1929. size_t i, n, stop;
  1930. bestlineCompletions lc;
  1931. struct bestlineState saved;
  1932. nread=0;
  1933. memset(&lc,0,sizeof(lc));
  1934. completionCallback(ls->buf,&lc);
  1935. if (!lc.len) {
  1936. bestlineBeep();
  1937. } else {
  1938. i = 0;
  1939. stop = 0;
  1940. while (!stop) {
  1941. /* Show completion or original buffer */
  1942. if (i < lc.len) {
  1943. saved = *ls;
  1944. ls->len = ls->pos = strlen(lc.cvec[i]);
  1945. ls->buf = lc.cvec[i];
  1946. bestlineRefreshLine(ls);
  1947. ls->len = saved.len;
  1948. ls->pos = saved.pos;
  1949. ls->buf = saved.buf;
  1950. } else {
  1951. bestlineRefreshLine(ls);
  1952. }
  1953. if ((nread = bestlineRead(ls->ifd,seq,size,ls)) <= 0) {
  1954. bestlineFreeCompletions(&lc);
  1955. return -1;
  1956. }
  1957. switch (seq[0]) {
  1958. case '\t':
  1959. i = (i+1) % (lc.len+1);
  1960. if (i == lc.len) {
  1961. bestlineBeep();
  1962. }
  1963. break;
  1964. default:
  1965. if (i < lc.len) {
  1966. n = strlen(lc.cvec[i]);
  1967. if (bestlineGrow(ls, n + 1)) {
  1968. memcpy(ls->buf, lc.cvec[i], n + 1);
  1969. ls->len = ls->pos = n;
  1970. }
  1971. }
  1972. stop = 1;
  1973. break;
  1974. }
  1975. }
  1976. }
  1977. bestlineFreeCompletions(&lc);
  1978. return nread;
  1979. }
  1980. static void bestlineEditHistoryGoto(struct bestlineState *l, unsigned i) {
  1981. size_t n;
  1982. if (historylen <= 1) return;
  1983. i = Max(Min(i,historylen-1),0);
  1984. free(history[historylen - 1 - l->hindex]);
  1985. history[historylen - 1 - l->hindex] = strdup(l->buf);
  1986. l->hindex = i;
  1987. n = strlen(history[historylen - 1 - l->hindex]);
  1988. bestlineGrow(l, n + 1);
  1989. n = Min(n, l->buflen - 1);
  1990. memcpy(l->buf, history[historylen - 1 - l->hindex], n);
  1991. l->buf[n] = 0;
  1992. l->len = l->pos = n;
  1993. bestlineRefreshLine(l);
  1994. }
  1995. static void bestlineEditHistoryMove(struct bestlineState *l, int dx) {
  1996. bestlineEditHistoryGoto(l,l->hindex+dx);
  1997. }
  1998. static char *bestlineMakeSearchPrompt(struct abuf *ab, int fail, const char *s, int n) {
  1999. ab->len=0;
  2000. abAppendw(ab,'(');
  2001. if (fail) abAppends(ab,"failed ");
  2002. abAppends(ab,"reverse-i-search `\033[4m");
  2003. abAppend(ab,s,n);
  2004. abAppends(ab,"\033[24m");
  2005. abAppends(ab,s+n);
  2006. abAppendw(ab,Read32le("') "));
  2007. return ab->b;
  2008. }
  2009. static int bestlineSearch(struct bestlineState *l, char *seq, int size) {
  2010. char *p;
  2011. char isstale;
  2012. struct abuf ab;
  2013. struct abuf prompt;
  2014. unsigned i, j, k, matlen;
  2015. const char *oldprompt, *q;
  2016. int rc, fail, added, oldpos, oldindex;
  2017. if (historylen <= 1) return 0;
  2018. abInit(&ab);
  2019. abInit(&prompt);
  2020. oldpos = l->pos;
  2021. oldprompt = l->prompt;
  2022. oldindex = l->hindex;
  2023. for (fail=matlen=0;;) {
  2024. l->prompt = bestlineMakeSearchPrompt(&prompt,fail,ab.b,matlen);
  2025. bestlineRefreshLine(l);
  2026. fail = 1;
  2027. added = 0;
  2028. j = l->pos;
  2029. i = l->hindex;
  2030. rc = bestlineRead(l->ifd,seq,size,l);
  2031. if (rc > 0) {
  2032. if (seq[0] == Ctrl('?') || seq[0] == Ctrl('H')) {
  2033. if (ab.len) {
  2034. --ab.len;
  2035. matlen = Min(matlen, ab.len);
  2036. }
  2037. } else if (seq[0] == Ctrl('R')) {
  2038. if (j) {
  2039. --j;
  2040. } else if (i + 1 < historylen) {
  2041. ++i;
  2042. j = strlen(history[historylen - 1 - i]);
  2043. }
  2044. } else if (seq[0] == Ctrl('G')) {
  2045. bestlineEditHistoryGoto(l,oldindex);
  2046. l->pos = oldpos;
  2047. rc = 0;
  2048. break;
  2049. } else if (IsControl(seq[0])) { /* only sees canonical c0 */
  2050. break;
  2051. } else {
  2052. abAppend(&ab,seq,rc);
  2053. added = rc;
  2054. }
  2055. } else {
  2056. break;
  2057. }
  2058. isstale = 0;
  2059. while (i < historylen) {
  2060. p = history[historylen - 1 - i];
  2061. k = strlen(p);
  2062. if (!isstale) {
  2063. j = Min(k, j + ab.len);
  2064. } else {
  2065. isstale = 0;
  2066. j = k;
  2067. }
  2068. if ((q = FindSubstringReverse(p, j, ab.b, ab.len))) {
  2069. bestlineEditHistoryGoto(l,i);
  2070. l->pos = q - p;
  2071. fail = 0;
  2072. if (added) {
  2073. matlen += added;
  2074. added = 0;
  2075. }
  2076. break;
  2077. } else {
  2078. isstale = 1;
  2079. ++i;
  2080. }
  2081. }
  2082. }
  2083. l->prompt = oldprompt;
  2084. bestlineRefreshLine(l);
  2085. abFree(&prompt);
  2086. abFree(&ab);
  2087. bestlineRefreshLine(l);
  2088. return rc;
  2089. }
  2090. static void bestlineRingFree(void) {
  2091. size_t i;
  2092. for (i = 0; i < BESTLINE_MAX_RING; ++i) {
  2093. if (ring.p[i]) {
  2094. free(ring.p[i]);
  2095. ring.p[i] = 0;
  2096. }
  2097. }
  2098. }
  2099. static void bestlineRingPush(const char *p, size_t n) {
  2100. char *q;
  2101. if (!n) return;
  2102. if (!(q = (char *)malloc(n + 1))) return;
  2103. ring.i = (ring.i + 1) % BESTLINE_MAX_RING;
  2104. free(ring.p[ring.i]);
  2105. ring.p[ring.i] = (char *)memcpy(q, p, n);
  2106. ring.p[ring.i][n] = 0;
  2107. }
  2108. static void bestlineRingRotate(void) {
  2109. size_t i;
  2110. for (i = 0; i < BESTLINE_MAX_RING; ++i) {
  2111. ring.i = (ring.i - 1) % BESTLINE_MAX_RING;
  2112. if (ring.p[ring.i]) break;
  2113. }
  2114. }
  2115. static char *bestlineRefreshHints(struct bestlineState *l) {
  2116. char *hint;
  2117. struct abuf ab;
  2118. const char *ansi1, *ansi2;
  2119. if (!hintsCallback) return 0;
  2120. if (!(hint = hintsCallback(l->buf, &ansi1, &ansi2))) return 0;
  2121. abInit(&ab);
  2122. ansi1 = "\033[90m";
  2123. ansi2 = "\033[39m";
  2124. if (ansi1) abAppends(&ab, ansi1);
  2125. abAppends(&ab, hint);
  2126. if (ansi2) abAppends(&ab, ansi2);
  2127. if (freeHintsCallback) freeHintsCallback(hint);
  2128. return ab.b;
  2129. }
  2130. static size_t Backward(struct bestlineState *l, size_t pos) {
  2131. if (pos) {
  2132. do --pos;
  2133. while (pos && (l->buf[pos] & 0300) == 0200);
  2134. }
  2135. return pos;
  2136. }
  2137. static int bestlineEditMirrorLeft(struct bestlineState *l, int res[2]) {
  2138. unsigned c, pos, left, right, depth, index;
  2139. if ((pos = Backward(l, l->pos))) {
  2140. right = GetUtf8(l->buf + pos, l->len - pos).c;
  2141. if ((left = bestlineMirrorLeft(right))) {
  2142. depth = 0;
  2143. index = pos;
  2144. do {
  2145. pos = Backward(l, pos);
  2146. c = GetUtf8(l->buf + pos, l->len - pos).c;
  2147. if (c == right) {
  2148. ++depth;
  2149. } else if (c == left) {
  2150. if (depth) {
  2151. --depth;
  2152. } else {
  2153. res[0] = pos;
  2154. res[1] = index;
  2155. return 0;
  2156. }
  2157. }
  2158. } while (pos);
  2159. }
  2160. }
  2161. return -1;
  2162. }
  2163. static int bestlineEditMirrorRight(struct bestlineState *l, int res[2]) {
  2164. struct rune rune;
  2165. unsigned pos, left, right, depth, index;
  2166. pos = l->pos;
  2167. rune = GetUtf8(l->buf + pos, l->len - pos);
  2168. left = rune.c;
  2169. if ((right = bestlineMirrorRight(left))) {
  2170. depth = 0;
  2171. index = pos;
  2172. do {
  2173. pos += rune.n;
  2174. rune = GetUtf8(l->buf + pos, l->len - pos);
  2175. if (rune.c == left) {
  2176. ++depth;
  2177. } else if (rune.c == right) {
  2178. if (depth) {
  2179. --depth;
  2180. } else {
  2181. res[0] = index;
  2182. res[1] = pos;
  2183. return 0;
  2184. }
  2185. }
  2186. } while (pos + rune.n < l->len);
  2187. }
  2188. return -1;
  2189. }
  2190. static int bestlineEditMirror(struct bestlineState *l, int res[2]) {
  2191. int rc;
  2192. rc = bestlineEditMirrorLeft(l, res);
  2193. if (rc == -1) rc = bestlineEditMirrorRight(l, res);
  2194. return rc;
  2195. }
  2196. static void bestlineRefreshLineImpl(struct bestlineState *l, int force) {
  2197. char *hint;
  2198. char flipit;
  2199. char hasflip;
  2200. char haswides;
  2201. struct abuf ab;
  2202. const char *buf;
  2203. struct rune rune;
  2204. struct winsize oldsize;
  2205. int fd, plen, rows, len, pos;
  2206. unsigned x, xn, yn, width, pwidth;
  2207. int i, t, cx, cy, tn, resized, flip[2];
  2208. /*
  2209. * synchonize the i/o state
  2210. */
  2211. if (ispaused) {
  2212. if (force) {
  2213. bestlineUnpause(l->ofd);
  2214. } else {
  2215. return;
  2216. }
  2217. }
  2218. if (!force && HasPendingInput(l->ifd)) {
  2219. l->dirty = 1;
  2220. return;
  2221. }
  2222. oldsize = l->ws;
  2223. if ((resized = gotwinch) && rawmode != -1) {
  2224. gotwinch = 0;
  2225. l->ws = GetTerminalSize(l->ws, l->ifd, l->ofd);
  2226. }
  2227. hasflip = !l->final && !bestlineEditMirror(l, flip);
  2228. StartOver:
  2229. fd = l->ofd;
  2230. buf = l->buf;
  2231. pos = l->pos;
  2232. len = l->len;
  2233. xn = l->ws.ws_col;
  2234. yn = l->ws.ws_row;
  2235. plen = strlen(l->prompt);
  2236. pwidth = GetMonospaceWidth(l->prompt, plen, 0);
  2237. width = GetMonospaceWidth(buf, len, &haswides);
  2238. /*
  2239. * handle the case where the line is larger than the whole display
  2240. * gnu readline actually isn't able to deal with this situation!!!
  2241. * we kludge xn to address the edge case of wide chars on the edge
  2242. */
  2243. for (tn = xn - haswides * 2;;) {
  2244. if (pwidth + width + 1 < tn * yn) break; /* we're fine */
  2245. if (!len || width < 2) break; /* we can't do anything */
  2246. if (pwidth + 2 > tn * yn) break; /* we can't do anything */
  2247. if (pos > len / 2) {
  2248. /* hide content on the left if we're editing on the right */
  2249. rune = GetUtf8(buf, len);
  2250. buf += rune.n;
  2251. len -= rune.n;
  2252. pos -= rune.n;
  2253. } else {
  2254. /* hide content on the right if we're editing on left */
  2255. t = len;
  2256. while (len && (buf[len - 1] & 0300) == 0200) --len;
  2257. if (len) --len;
  2258. rune = GetUtf8(buf + len, t - len);
  2259. }
  2260. if ((t = GetMonospaceCharacterWidth(rune.c)) > 0) {
  2261. width -= t;
  2262. }
  2263. }
  2264. pos = Max(0, Min(pos, len));
  2265. /*
  2266. * now generate the terminal codes to update the line
  2267. *
  2268. * since we support unlimited lines it's important that we don't
  2269. * clear the screen before we draw the screen. doing that causes
  2270. * flickering. the key with terminals is to overwrite cells, and
  2271. * then use \e[K and \e[J to clear everything else.
  2272. *
  2273. * we make the assumption that prompts and hints may contain ansi
  2274. * sequences, but the buffer does not.
  2275. *
  2276. * we need to handle the edge case where a wide character like 度
  2277. * might be at the edge of the window, when there's one cell left.
  2278. * so we can't use division based on string width to compute the
  2279. * coordinates and have to track it as we go.
  2280. */
  2281. cy = -1;
  2282. cx = -1;
  2283. rows = 1;
  2284. abInit(&ab);
  2285. abAppendw(&ab, '\r'); /* start of line */
  2286. if (l->rows - l->oldpos - 1 > 0) {
  2287. abAppends(&ab, "\033[");
  2288. abAppendu(&ab, l->rows - l->oldpos - 1);
  2289. abAppendw(&ab, 'A'); /* cursor up clamped */
  2290. }
  2291. abAppends(&ab, l->prompt);
  2292. x = pwidth;
  2293. for (i = 0; i < len; i += rune.n) {
  2294. rune = GetUtf8(buf + i, len - i);
  2295. if (x && x + rune.n > xn) {
  2296. if (cy >= 0) ++cy;
  2297. abAppends(&ab, "\033[K" /* clear line forward */
  2298. "\r" /* start of line */
  2299. "\n"); /* cursor down unclamped */
  2300. ++rows;
  2301. x = 0;
  2302. }
  2303. if (i == pos) {
  2304. cy = 0;
  2305. cx = x;
  2306. }
  2307. if (maskmode) {
  2308. abAppendw(&ab, '*');
  2309. } else {
  2310. flipit = hasflip && (i == flip[0] || i == flip[1]);
  2311. if (flipit) abAppends(&ab, "\033[1m");
  2312. abAppendw(&ab, EncodeUtf8(rune.c));
  2313. if (flipit) abAppends(&ab, "\033[22m");
  2314. }
  2315. t = GetMonospaceCharacterWidth(rune.c);
  2316. t = Max(0, t);
  2317. x += t;
  2318. }
  2319. if (!l->final && (hint = bestlineRefreshHints(l))) {
  2320. if (GetMonospaceWidth(hint, strlen(hint), 0) < xn - x) {
  2321. if (cx < 0) {
  2322. cx = x;
  2323. }
  2324. abAppends(&ab, hint);
  2325. }
  2326. free(hint);
  2327. }
  2328. abAppendw(&ab, Read32le("\033[J")); /* erase display forwards */
  2329. /*
  2330. * if we are at the very end of the screen with our prompt, we need
  2331. * to emit a newline and move the prompt to the first column.
  2332. */
  2333. if (pos && pos == len && x >= xn) {
  2334. abAppendw(&ab, Read32le("\n\r\0"));
  2335. ++rows;
  2336. }
  2337. /*
  2338. * move cursor to right position
  2339. */
  2340. if (cy > 0) {
  2341. abAppends(&ab, "\033[");
  2342. abAppendu(&ab, cy);
  2343. abAppendw(&ab, 'A'); /* cursor up */
  2344. }
  2345. if (cx > 0) {
  2346. abAppendw(&ab, Read32le("\r\033["));
  2347. abAppendu(&ab, cx);
  2348. abAppendw(&ab, 'C'); /* cursor right */
  2349. } else if (!cx) {
  2350. abAppendw(&ab, '\r'); /* start */
  2351. }
  2352. /*
  2353. * now get ready to progress state
  2354. * we use a mostly correct kludge when the tty resizes
  2355. */
  2356. l->rows = rows;
  2357. if (resized && oldsize.ws_col > l->ws.ws_col) {
  2358. resized = 0;
  2359. abFree(&ab);
  2360. goto StartOver;
  2361. }
  2362. l->dirty = 0;
  2363. l->oldpos = Max(0, cy);
  2364. /*
  2365. * send codes to terminal
  2366. */
  2367. bestlineWrite(fd, ab.b, ab.len);
  2368. abFree(&ab);
  2369. }
  2370. static void bestlineRefreshLine(struct bestlineState *l) {
  2371. bestlineRefreshLineImpl(l, 0);
  2372. }
  2373. static void bestlineRefreshLineForce(struct bestlineState *l) {
  2374. bestlineRefreshLineImpl(l, 1);
  2375. }
  2376. static void bestlineEditInsert(struct bestlineState *l,
  2377. const char *p, size_t n) {
  2378. if (!bestlineGrow(l, l->len + n + 1)) return;
  2379. if (*p == ' ' && l->pos && l->buf[l->pos - 1] == ' ') return;
  2380. memmove(l->buf + l->pos + n, l->buf + l->pos, l->len - l->pos);
  2381. memcpy(l->buf + l->pos, p, n);
  2382. l->pos += n;
  2383. l->len += n;
  2384. l->buf[l->len] = 0;
  2385. bestlineRefreshLine(l);
  2386. }
  2387. static void bestlineEditHome(struct bestlineState *l) {
  2388. l->pos = 0;
  2389. bestlineRefreshLine(l);
  2390. }
  2391. static void bestlineEditEnd(struct bestlineState *l) {
  2392. l->pos = l->len;
  2393. bestlineRefreshLine(l);
  2394. }
  2395. static void bestlineEditUp(struct bestlineState *l) {
  2396. bestlineEditHistoryMove(l,BESTLINE_HISTORY_PREV);
  2397. }
  2398. static void bestlineEditDown(struct bestlineState *l) {
  2399. bestlineEditHistoryMove(l,BESTLINE_HISTORY_NEXT);
  2400. }
  2401. static void bestlineEditBof(struct bestlineState *l) {
  2402. bestlineEditHistoryMove(l,BESTLINE_HISTORY_FIRST);
  2403. }
  2404. static void bestlineEditEof(struct bestlineState *l) {
  2405. bestlineEditHistoryMove(l,BESTLINE_HISTORY_LAST);
  2406. }
  2407. static void bestlineEditRefresh(struct bestlineState *l) {
  2408. bestlineClearScreen(l->ofd);
  2409. bestlineRefreshLine(l);
  2410. }
  2411. static size_t Forward(struct bestlineState *l, size_t pos) {
  2412. return pos + GetUtf8(l->buf + pos, l->len - pos).n;
  2413. }
  2414. static size_t Backwards(struct bestlineState *l, size_t pos, char pred(unsigned)) {
  2415. size_t i;
  2416. struct rune r;
  2417. while (pos) {
  2418. i = Backward(l, pos);
  2419. r = GetUtf8(l->buf + i, l->len - i);
  2420. if (pred(r.c)) {
  2421. pos = i;
  2422. } else {
  2423. break;
  2424. }
  2425. }
  2426. return pos;
  2427. }
  2428. static size_t Forwards(struct bestlineState *l, size_t pos, char pred(unsigned)) {
  2429. struct rune r;
  2430. while (pos < l->len) {
  2431. r = GetUtf8(l->buf + pos, l->len - pos);
  2432. if (pred(r.c)) {
  2433. pos += r.n;
  2434. } else {
  2435. break;
  2436. }
  2437. }
  2438. return pos;
  2439. }
  2440. static size_t ForwardWord(struct bestlineState *l, size_t pos) {
  2441. pos = Forwards(l, pos, bestlineIsSeparator);
  2442. pos = Forwards(l, pos, bestlineNotSeparator);
  2443. return pos;
  2444. }
  2445. static size_t BackwardWord(struct bestlineState *l, size_t pos) {
  2446. pos = Backwards(l, pos, bestlineIsSeparator);
  2447. pos = Backwards(l, pos, bestlineNotSeparator);
  2448. return pos;
  2449. }
  2450. static size_t EscapeWord(struct bestlineState *l) {
  2451. size_t i, j;
  2452. struct rune r;
  2453. for (i = l->pos; i && i < l->len; i += r.n) {
  2454. if (i < l->len) {
  2455. r = GetUtf8(l->buf + i, l->len - i);
  2456. if (bestlineIsSeparator(r.c)) break;
  2457. }
  2458. if ((j = i)) {
  2459. do --j;
  2460. while (j && (l->buf[j] & 0300) == 0200);
  2461. r = GetUtf8(l->buf + j, l->len - j);
  2462. if (bestlineIsSeparator(r.c)) break;
  2463. }
  2464. }
  2465. return i;
  2466. }
  2467. static void bestlineEditLeft(struct bestlineState *l) {
  2468. l->pos = Backward(l, l->pos);
  2469. bestlineRefreshLine(l);
  2470. }
  2471. static void bestlineEditRight(struct bestlineState *l) {
  2472. if (l->pos == l->len) return;
  2473. do l->pos++;
  2474. while (l->pos < l->len && (l->buf[l->pos] & 0300) == 0200);
  2475. bestlineRefreshLine(l);
  2476. }
  2477. static void bestlineEditLeftWord(struct bestlineState *l) {
  2478. l->pos = BackwardWord(l, l->pos);
  2479. bestlineRefreshLine(l);
  2480. }
  2481. static void bestlineEditRightWord(struct bestlineState *l) {
  2482. l->pos = ForwardWord(l, l->pos);
  2483. bestlineRefreshLine(l);
  2484. }
  2485. static void bestlineEditLeftExpr(struct bestlineState *l) {
  2486. int mark[2];
  2487. l->pos = Backwards(l, l->pos, bestlineIsXeparator);
  2488. if (!bestlineEditMirrorLeft(l, mark)) {
  2489. l->pos = mark[0];
  2490. } else {
  2491. l->pos = Backwards(l, l->pos, bestlineNotSeparator);
  2492. }
  2493. bestlineRefreshLine(l);
  2494. }
  2495. static void bestlineEditRightExpr(struct bestlineState *l) {
  2496. int mark[2];
  2497. l->pos = Forwards(l, l->pos, bestlineIsXeparator);
  2498. if (!bestlineEditMirrorRight(l, mark)) {
  2499. l->pos = Forward(l, mark[1]);
  2500. } else {
  2501. l->pos = Forwards(l, l->pos, bestlineNotSeparator);
  2502. }
  2503. bestlineRefreshLine(l);
  2504. }
  2505. static void bestlineEditDelete(struct bestlineState *l) {
  2506. size_t i;
  2507. if (l->pos == l->len) return;
  2508. i = Forward(l, l->pos);
  2509. memmove(l->buf+l->pos, l->buf+i, l->len-i+1);
  2510. l->len -= i - l->pos;
  2511. bestlineRefreshLine(l);
  2512. }
  2513. static void bestlineEditRubout(struct bestlineState *l) {
  2514. size_t i;
  2515. if (!l->pos) return;
  2516. i = Backward(l, l->pos);
  2517. memmove(l->buf+i, l->buf+l->pos, l->len-l->pos+1);
  2518. l->len -= l->pos - i;
  2519. l->pos = i;
  2520. bestlineRefreshLine(l);
  2521. }
  2522. static void bestlineEditDeleteWord(struct bestlineState *l) {
  2523. size_t i;
  2524. if (l->pos == l->len) return;
  2525. i = ForwardWord(l, l->pos);
  2526. bestlineRingPush(l->buf + l->pos, i - l->pos);
  2527. memmove(l->buf + l->pos, l->buf + i, l->len - i + 1);
  2528. l->len -= i - l->pos;
  2529. bestlineRefreshLine(l);
  2530. }
  2531. static void bestlineEditRuboutWord(struct bestlineState *l) {
  2532. size_t i;
  2533. if (!l->pos) return;
  2534. i = BackwardWord(l, l->pos);
  2535. bestlineRingPush(l->buf + i, l->pos - i);
  2536. memmove(l->buf + i, l->buf + l->pos, l->len - l->pos + 1);
  2537. l->len -= l->pos - i;
  2538. l->pos = i;
  2539. bestlineRefreshLine(l);
  2540. }
  2541. static void bestlineEditXlatWord(struct bestlineState *l, unsigned xlat(unsigned)) {
  2542. unsigned c;
  2543. size_t i, j;
  2544. struct rune r;
  2545. struct abuf ab;
  2546. abInit(&ab);
  2547. i = Forwards(l, l->pos, bestlineIsSeparator);
  2548. for (j = i; j < l->len; j += r.n) {
  2549. r = GetUtf8(l->buf + j, l->len - j);
  2550. if (bestlineIsSeparator(r.c)) break;
  2551. if ((c = xlat(r.c)) != r.c) {
  2552. abAppendw(&ab, EncodeUtf8(c));
  2553. } else { /* avoid canonicalization */
  2554. abAppend(&ab, l->buf + j, r.n);
  2555. }
  2556. }
  2557. if (ab.len && bestlineGrow(l, i + ab.len + l->len - j + 1)) {
  2558. l->pos = i + ab.len;
  2559. abAppend(&ab, l->buf + j, l->len - j);
  2560. l->len = i + ab.len;
  2561. memcpy(l->buf + i, ab.b, ab.len + 1);
  2562. bestlineRefreshLine(l);
  2563. }
  2564. abFree(&ab);
  2565. }
  2566. static void bestlineEditLowercaseWord(struct bestlineState *l) {
  2567. bestlineEditXlatWord(l, bestlineLowercase);
  2568. }
  2569. static void bestlineEditUppercaseWord(struct bestlineState *l) {
  2570. bestlineEditXlatWord(l, bestlineUppercase);
  2571. }
  2572. static void bestlineEditCapitalizeWord(struct bestlineState *l) {
  2573. iscapital = 0;
  2574. bestlineEditXlatWord(l, Capitalize);
  2575. }
  2576. static void bestlineEditKillLeft(struct bestlineState *l) {
  2577. size_t diff, old_pos;
  2578. bestlineRingPush(l->buf, l->pos);
  2579. old_pos = l->pos;
  2580. l->pos = 0;
  2581. diff = old_pos - l->pos;
  2582. memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1);
  2583. l->len -= diff;
  2584. bestlineRefreshLine(l);
  2585. }
  2586. static void bestlineEditKillRight(struct bestlineState *l) {
  2587. bestlineRingPush(l->buf + l->pos, l->len - l->pos);
  2588. l->buf[l->pos] = '\0';
  2589. l->len = l->pos;
  2590. bestlineRefreshLine(l);
  2591. }
  2592. static void bestlineEditYank(struct bestlineState *l) {
  2593. char *p;
  2594. size_t n;
  2595. if (!ring.p[ring.i]) return;
  2596. n = strlen(ring.p[ring.i]);
  2597. if (!bestlineGrow(l, l->len + n + 1)) return;
  2598. if (!(p = (char *)malloc(l->len - l->pos + 1))) return;
  2599. memcpy(p, l->buf + l->pos, l->len - l->pos + 1);
  2600. memcpy(l->buf + l->pos, ring.p[ring.i], n);
  2601. memcpy(l->buf + l->pos + n, p, l->len - l->pos + 1);
  2602. free(p);
  2603. l->yi = l->pos;
  2604. l->yj = l->pos + n;
  2605. l->pos += n;
  2606. l->len += n;
  2607. bestlineRefreshLine(l);
  2608. }
  2609. static void bestlineEditRotate(struct bestlineState *l) {
  2610. if ((l->seq[1][0] == Ctrl('Y') ||
  2611. (l->seq[1][0] == 033 && l->seq[1][1] == 'y'))) {
  2612. if (l->yi < l->len && l->yj <= l->len) {
  2613. memmove(l->buf + l->yi, l->buf + l->yj, l->len - l->yj + 1);
  2614. l->len -= l->yj - l->yi;
  2615. l->pos -= l->yj - l->yi;
  2616. }
  2617. bestlineRingRotate();
  2618. bestlineEditYank(l);
  2619. }
  2620. }
  2621. static void bestlineEditTranspose(struct bestlineState *l) {
  2622. char *q, *p;
  2623. size_t a, b, c;
  2624. b = l->pos;
  2625. a = Backward(l, b);
  2626. c = Forward(l, b);
  2627. if (!(a < b && b < c)) return;
  2628. p = q = (char *)malloc(c - a);
  2629. p = Copy(p, l->buf + b, c - b);
  2630. p = Copy(p, l->buf + a, b - a);
  2631. assert((size_t)(p - q) == c - a);
  2632. memcpy(l->buf + a, q, p - q);
  2633. l->pos = c;
  2634. free(q);
  2635. bestlineRefreshLine(l);
  2636. }
  2637. static void bestlineEditTransposeWords(struct bestlineState *l) {
  2638. char *q, *p;
  2639. size_t pi, xi, xj, yi, yj;
  2640. pi = EscapeWord(l);
  2641. xj = Backwards(l, pi, bestlineIsSeparator);
  2642. xi = Backwards(l, xj, bestlineNotSeparator);
  2643. yi = Forwards(l, pi, bestlineIsSeparator);
  2644. yj = Forwards(l, yi, bestlineNotSeparator);
  2645. if (!(xi < xj && xj < yi && yi < yj)) return;
  2646. p = q = (char *)malloc(yj - xi);
  2647. p = Copy(p, l->buf + yi, yj - yi);
  2648. p = Copy(p, l->buf + xj, yi - xj);
  2649. p = Copy(p, l->buf + xi, xj - xi);
  2650. assert((size_t)(p - q) == yj - xi);
  2651. memcpy(l->buf + xi, q, p - q);
  2652. l->pos = yj;
  2653. free(q);
  2654. bestlineRefreshLine(l);
  2655. }
  2656. static void bestlineEditSqueeze(struct bestlineState *l) {
  2657. size_t i, j;
  2658. i = Backwards(l, l->pos, bestlineIsSeparator);
  2659. j = Forwards(l, l->pos, bestlineIsSeparator);
  2660. if (!(i < j)) return;
  2661. memmove(l->buf + i, l->buf + j, l->len - j + 1);
  2662. l->len -= j - i;
  2663. l->pos = i;
  2664. bestlineRefreshLine(l);
  2665. }
  2666. static void bestlineEditMark(struct bestlineState *l) {
  2667. l->mark = l->pos;
  2668. }
  2669. static void bestlineEditGoto(struct bestlineState *l) {
  2670. if (l->mark > l->len) return;
  2671. l->pos = Min(l->mark, l->len);
  2672. bestlineRefreshLine(l);
  2673. }
  2674. static size_t bestlineEscape(char *d, const char *s, size_t n) {
  2675. char *p;
  2676. size_t i;
  2677. unsigned c, w, l;
  2678. for (p = d, l = i = 0; i < n; ++i) {
  2679. switch ((c = s[i] & 255)) {
  2680. Case('\a', w = Read16le("\\a"));
  2681. Case('\b', w = Read16le("\\b"));
  2682. Case('\t', w = Read16le("\\t"));
  2683. Case('\n', w = Read16le("\\n"));
  2684. Case('\v', w = Read16le("\\v"));
  2685. Case('\f', w = Read16le("\\f"));
  2686. Case('\r', w = Read16le("\\r"));
  2687. Case('"', w = Read16le("\\\""));
  2688. Case('\'', w = Read16le("\\\'"));
  2689. Case('\\', w = Read16le("\\\\"));
  2690. default:
  2691. if (c <= 0x1F || c == 0x7F ||
  2692. (c == '?' && l == '?')) {
  2693. w = Read16le("\\x");
  2694. w |= "0123456789abcdef"[(c & 0xF0) >> 4] << 020;
  2695. w |= "0123456789abcdef"[(c & 0x0F) >> 0] << 030;
  2696. } else {
  2697. w = c;
  2698. }
  2699. break;
  2700. }
  2701. p[0] = (w & 0x000000ff) >> 000;
  2702. p[1] = (w & 0x0000ff00) >> 010;
  2703. p[2] = (w & 0x00ff0000) >> 020;
  2704. p[3] = (w & 0xff000000) >> 030;
  2705. p += (Bsr(w) >> 3) + 1;
  2706. l = w;
  2707. }
  2708. return p - d;
  2709. }
  2710. static void bestlineEditInsertEscape(struct bestlineState *l) {
  2711. size_t m;
  2712. ssize_t n;
  2713. char seq[16];
  2714. char esc[sizeof(seq) * 4];
  2715. if ((n = bestlineRead(l->ifd, seq, sizeof(seq), l)) > 0) {
  2716. m = bestlineEscape(esc, seq, n);
  2717. bestlineEditInsert(l, esc, m);
  2718. }
  2719. }
  2720. static void bestlineEditInterrupt(void) {
  2721. gotint = SIGINT;
  2722. }
  2723. static void bestlineEditQuit(void) {
  2724. gotint = SIGQUIT;
  2725. }
  2726. static void bestlineEditSuspend(void) {
  2727. raise(SIGSTOP);
  2728. }
  2729. static void bestlineEditPause(struct bestlineState *l) {
  2730. tcflow(l->ofd, TCOOFF);
  2731. ispaused = 1;
  2732. }
  2733. static void bestlineEditCtrlq(struct bestlineState *l) {
  2734. if (ispaused) {
  2735. bestlineUnpause(l->ofd);
  2736. bestlineRefreshLineForce(l);
  2737. } else {
  2738. bestlineEditInsertEscape(l);
  2739. }
  2740. }
  2741. /**
  2742. * Moves last item inside current s-expression to outside, e.g.
  2743. *
  2744. * (a| b c)
  2745. * (a| b) c
  2746. *
  2747. * The cursor position changes only if a paren is moved before it:
  2748. *
  2749. * (a b c |)
  2750. * (a b) c |
  2751. *
  2752. * To accommodate non-LISP languages we connect unspaced outer symbols:
  2753. *
  2754. * f(a,| b, g())
  2755. * f(a,| b), g()
  2756. *
  2757. * Our standard keybinding is ALT-SHIFT-B.
  2758. */
  2759. static void bestlineEditBarf(struct bestlineState *l) {
  2760. struct rune r;
  2761. unsigned long w;
  2762. size_t i, j, pos, depth = 0;
  2763. unsigned lhs, rhs, end, *stack = 0;
  2764. /* go as far right within current s-expr as possible */
  2765. for (pos = l->pos;; pos += r.n) {
  2766. if (pos == l->len) goto Finish;
  2767. r = GetUtf8(l->buf + pos, l->len - pos);
  2768. if (depth) {
  2769. if (r.c == stack[depth - 1]) {
  2770. --depth;
  2771. }
  2772. } else {
  2773. if ((rhs = bestlineMirrorRight(r.c))) {
  2774. stack = realloc(stack, ++depth * sizeof(*stack));
  2775. stack[depth - 1] = rhs;
  2776. } else if (bestlineMirrorLeft(r.c)) {
  2777. end = pos;
  2778. break;
  2779. }
  2780. }
  2781. }
  2782. /* go back one item */
  2783. pos = Backwards(l, pos, bestlineIsXeparator);
  2784. for (;; pos = i) {
  2785. if (!pos) goto Finish;
  2786. i = Backward(l, pos);
  2787. r = GetUtf8(l->buf + i, l->len - i);
  2788. if (depth) {
  2789. if (r.c == stack[depth - 1]) {
  2790. --depth;
  2791. }
  2792. } else {
  2793. if ((lhs = bestlineMirrorLeft(r.c))) {
  2794. stack = realloc(stack, ++depth * sizeof(*stack));
  2795. stack[depth - 1] = lhs;
  2796. } else if (bestlineIsSeparator(r.c)) {
  2797. break;
  2798. }
  2799. }
  2800. }
  2801. pos = Backwards(l, pos, bestlineIsXeparator);
  2802. /* now move the text */
  2803. r = GetUtf8(l->buf + end, l->len - end);
  2804. memmove(l->buf + pos + r.n, l->buf + pos, end - pos);
  2805. w = EncodeUtf8(r.c);
  2806. for (i = 0; i < r.n; ++i) {
  2807. l->buf[pos + i] = w;
  2808. w >>= 8;
  2809. }
  2810. if (l->pos > pos) {
  2811. l->pos += r.n;
  2812. }
  2813. bestlineRefreshLine(l);
  2814. Finish:
  2815. free(stack);
  2816. }
  2817. /**
  2818. * Moves first item outside current s-expression to inside, e.g.
  2819. *
  2820. * (a| b) c d
  2821. * (a| b c) d
  2822. *
  2823. * To accommodate non-LISP languages we connect unspaced outer symbols:
  2824. *
  2825. * f(a,| b), g()
  2826. * f(a,| b, g())
  2827. *
  2828. * Our standard keybinding is ALT-SHIFT-S.
  2829. */
  2830. static void bestlineEditSlurp(struct bestlineState *l) {
  2831. char rp[6];
  2832. struct rune r;
  2833. unsigned long w;
  2834. size_t i, pos, depth = 0;
  2835. unsigned rhs, point = 0, start = 0, *stack = 0;
  2836. /* go to outside edge of current s-expr */
  2837. for (pos = l->pos; pos < l->len; pos += r.n) {
  2838. r = GetUtf8(l->buf + pos, l->len - pos);
  2839. if (depth) {
  2840. if (r.c == stack[depth - 1]) {
  2841. --depth;
  2842. }
  2843. } else {
  2844. if ((rhs = bestlineMirrorRight(r.c))) {
  2845. stack = realloc(stack, ++depth * sizeof(*stack));
  2846. stack[depth - 1] = rhs;
  2847. } else if (bestlineMirrorLeft(r.c)) {
  2848. point = pos;
  2849. pos += r.n;
  2850. start = pos;
  2851. break;
  2852. }
  2853. }
  2854. }
  2855. /* go forward one item */
  2856. pos = Forwards(l, pos, bestlineIsXeparator);
  2857. for (; pos < l->len ; pos += r.n) {
  2858. r = GetUtf8(l->buf + pos, l->len - pos);
  2859. if (depth) {
  2860. if (r.c == stack[depth - 1]) {
  2861. --depth;
  2862. }
  2863. } else {
  2864. if ((rhs = bestlineMirrorRight(r.c))) {
  2865. stack = realloc(stack, ++depth * sizeof(*stack));
  2866. stack[depth - 1] = rhs;
  2867. } else if (bestlineIsSeparator(r.c)) {
  2868. break;
  2869. }
  2870. }
  2871. }
  2872. /* now move the text */
  2873. memcpy(rp, l->buf + point, start - point);
  2874. memmove(l->buf + point, l->buf + start, pos - start);
  2875. memcpy(l->buf + pos - (start - point), rp, start - point);
  2876. bestlineRefreshLine(l);
  2877. free(stack);
  2878. }
  2879. static void bestlineEditRaise(struct bestlineState *l) {
  2880. (void)l;
  2881. }
  2882. static char IsBalanced(struct bestlineState *l) {
  2883. int i, d;
  2884. for (d = i = 0; i < l->len; ++i) {
  2885. if (l->buf[i] == '(') ++d;
  2886. if (l->buf[i] == ')') --d;
  2887. }
  2888. return d <= 0;
  2889. }
  2890. /**
  2891. * Runs bestline engine.
  2892. *
  2893. * This function is the core of the line editing capability of bestline.
  2894. * It expects 'fd' to be already in "raw mode" so that every key pressed
  2895. * will be returned ASAP to read().
  2896. *
  2897. * The resulting string is put into 'buf' when the user type enter, or
  2898. * when ctrl+d is typed.
  2899. *
  2900. * Returns chomped character count in buf >=0 or -1 on eof / error
  2901. */
  2902. static ssize_t bestlineEdit(int stdin_fd, int stdout_fd, const char *prompt,
  2903. char **obuf) {
  2904. ssize_t rc;
  2905. size_t nread;
  2906. struct rune rune;
  2907. char *p, seq[16];
  2908. unsigned long long w;
  2909. struct bestlineState l;
  2910. memset(&l,0,sizeof(l));
  2911. if (!(l.buf = (char *)malloc((l.buflen = 32)))) return -1;
  2912. l.buf[0] = 0;
  2913. l.ifd = stdin_fd;
  2914. l.ofd = stdout_fd;
  2915. l.prompt = prompt ? prompt : "";
  2916. l.ws = GetTerminalSize(l.ws,l.ifd,l.ofd);
  2917. bestlineHistoryAdd("");
  2918. bestlineWriteStr(l.ofd,l.prompt);
  2919. while (1) {
  2920. if (l.dirty) bestlineRefreshLineForce(&l);
  2921. rc = bestlineRead(l.ifd,seq,sizeof(seq),&l);
  2922. if (rc > 0) {
  2923. if (seq[0] == Ctrl('R')) {
  2924. rc = bestlineSearch(&l,seq,sizeof(seq));
  2925. if (!rc) continue;
  2926. } else if (seq[0] == '\t' && completionCallback) {
  2927. rc = bestlineCompleteLine(&l,seq,sizeof(seq));
  2928. if (!rc) continue;
  2929. }
  2930. }
  2931. if (rc > 0) {
  2932. nread = rc;
  2933. } else if (!rc && l.len) {
  2934. nread = 1;
  2935. seq[0] = '\r';
  2936. seq[1] = 0;
  2937. } else {
  2938. free(history[--historylen]);
  2939. history[historylen] = 0;
  2940. free(l.buf);
  2941. return -1;
  2942. }
  2943. switch (seq[0]) {
  2944. Case(Ctrl('P'), bestlineEditUp(&l));
  2945. Case(Ctrl('E'), bestlineEditEnd(&l));
  2946. Case(Ctrl('N'), bestlineEditDown(&l));
  2947. Case(Ctrl('A'), bestlineEditHome(&l));
  2948. Case(Ctrl('B'), bestlineEditLeft(&l));
  2949. Case(Ctrl('@'), bestlineEditMark(&l));
  2950. Case(Ctrl('Y'), bestlineEditYank(&l));
  2951. Case(Ctrl('Q'), bestlineEditCtrlq(&l));
  2952. Case(Ctrl('F'), bestlineEditRight(&l));
  2953. Case(Ctrl('\\'), bestlineEditQuit());
  2954. Case(Ctrl('S'), bestlineEditPause(&l));
  2955. Case(Ctrl('?'), bestlineEditRubout(&l));
  2956. Case(Ctrl('H'), bestlineEditRubout(&l));
  2957. Case(Ctrl('L'), bestlineEditRefresh(&l));
  2958. Case(Ctrl('Z'), bestlineEditSuspend());
  2959. Case(Ctrl('U'), bestlineEditKillLeft(&l));
  2960. Case(Ctrl('T'), bestlineEditTranspose(&l));
  2961. Case(Ctrl('K'), bestlineEditKillRight(&l));
  2962. Case(Ctrl('W'), bestlineEditRuboutWord(&l));
  2963. case Ctrl('C'):
  2964. if (bestlineRead(l.ifd,seq,sizeof(seq),&l) != 1) break;
  2965. switch (seq[0]) {
  2966. Case(Ctrl('C'), bestlineEditInterrupt());
  2967. Case(Ctrl('B'), bestlineEditBarf(&l));
  2968. Case(Ctrl('S'), bestlineEditSlurp(&l));
  2969. Case(Ctrl('R'), bestlineEditRaise(&l));
  2970. default:
  2971. break;
  2972. }
  2973. break;
  2974. case Ctrl('X'):
  2975. if (l.seq[1][0] == Ctrl('X')) {
  2976. bestlineEditGoto(&l);
  2977. }
  2978. break;
  2979. case Ctrl('D'):
  2980. if (l.len) {
  2981. bestlineEditDelete(&l);
  2982. } else {
  2983. free(history[--historylen]);
  2984. history[historylen] = 0;
  2985. free(l.buf);
  2986. return -1;
  2987. }
  2988. break;
  2989. case '\r':
  2990. if (IsBalanced(&l)) {
  2991. l.final = 1;
  2992. free(history[--historylen]);
  2993. history[historylen] = 0;
  2994. bestlineEditEnd(&l);
  2995. bestlineRefreshLineForce(&l);
  2996. if ((p = (char *)realloc(l.buf, l.len + 1))) l.buf = p;
  2997. *obuf = l.buf;
  2998. return l.len;
  2999. } else {
  3000. break;
  3001. }
  3002. case 033:
  3003. if (nread < 2) break;
  3004. switch (seq[1]) {
  3005. Case('<', bestlineEditBof(&l));
  3006. Case('>', bestlineEditEof(&l));
  3007. Case('B', bestlineEditBarf(&l));
  3008. Case('S', bestlineEditSlurp(&l));
  3009. Case('R', bestlineEditRaise(&l));
  3010. Case('y', bestlineEditRotate(&l));
  3011. Case('\\', bestlineEditSqueeze(&l));
  3012. Case('b', bestlineEditLeftWord(&l));
  3013. Case('f', bestlineEditRightWord(&l));
  3014. Case('h', bestlineEditRuboutWord(&l));
  3015. Case('d', bestlineEditDeleteWord(&l));
  3016. Case('l', bestlineEditLowercaseWord(&l));
  3017. Case('u', bestlineEditUppercaseWord(&l));
  3018. Case('c', bestlineEditCapitalizeWord(&l));
  3019. Case('t', bestlineEditTransposeWords(&l));
  3020. Case(Ctrl('B'), bestlineEditLeftExpr(&l));
  3021. Case(Ctrl('F'), bestlineEditRightExpr(&l));
  3022. Case(Ctrl('H'), bestlineEditRuboutWord(&l));
  3023. case '[':
  3024. if (nread < 3) break;
  3025. if (seq[2] >= '0' && seq[2] <= '9') {
  3026. if (nread < 4) break;
  3027. if (seq[3] == '~') {
  3028. switch (seq[2]) {
  3029. Case('1', bestlineEditHome(&l)); /* \e[1~ */
  3030. Case('3', bestlineEditDelete(&l)); /* \e[3~ */
  3031. Case('4', bestlineEditEnd(&l)); /* \e[4~ */
  3032. default:
  3033. break;
  3034. }
  3035. }
  3036. } else {
  3037. switch (seq[2]) {
  3038. Case('A', bestlineEditUp(&l));
  3039. Case('B', bestlineEditDown(&l));
  3040. Case('C', bestlineEditRight(&l));
  3041. Case('D', bestlineEditLeft(&l));
  3042. Case('H', bestlineEditHome(&l));
  3043. Case('F', bestlineEditEnd(&l));
  3044. default:
  3045. break;
  3046. }
  3047. }
  3048. break;
  3049. case 'O':
  3050. if (nread < 3) break;
  3051. switch (seq[2]) {
  3052. Case('A', bestlineEditUp(&l));
  3053. Case('B', bestlineEditDown(&l));
  3054. Case('C', bestlineEditRight(&l));
  3055. Case('D', bestlineEditLeft(&l));
  3056. Case('H', bestlineEditHome(&l));
  3057. Case('F', bestlineEditEnd(&l));
  3058. default:
  3059. break;
  3060. }
  3061. break;
  3062. case 033:
  3063. if (nread < 3) break;
  3064. switch (seq[2]) {
  3065. case '[':
  3066. if (nread < 4) break;
  3067. switch (seq[3]) {
  3068. Case('C', bestlineEditRightExpr(&l)); /* \e\e[C alt-right */
  3069. Case('D', bestlineEditLeftExpr(&l)); /* \e\e[D alt-left */
  3070. default:
  3071. break;
  3072. }
  3073. break;
  3074. case 'O':
  3075. if (nread < 4) break;
  3076. switch (seq[3]) {
  3077. Case('C', bestlineEditRightExpr(&l)); /* \e\eOC alt-right */
  3078. Case('D', bestlineEditLeftExpr(&l)); /* \e\eOD alt-left */
  3079. default:
  3080. break;
  3081. }
  3082. break;
  3083. default:
  3084. break;
  3085. }
  3086. break;
  3087. default:
  3088. break;
  3089. }
  3090. break;
  3091. default:
  3092. if (!IsControl(seq[0])) { /* only sees canonical c0 */
  3093. if (xlatCallback) {
  3094. rune = GetUtf8(seq,nread);
  3095. w = EncodeUtf8(xlatCallback(rune.c));
  3096. nread = 0;
  3097. do {
  3098. seq[nread++] = w;
  3099. } while ((w >>= 8));
  3100. }
  3101. bestlineEditInsert(&l,seq,nread);
  3102. }
  3103. break;
  3104. }
  3105. }
  3106. }
  3107. void bestlineFree(void *ptr) {
  3108. free(ptr);
  3109. }
  3110. void bestlineHistoryFree(void) {
  3111. size_t i;
  3112. for (i = 0; i < BESTLINE_MAX_HISTORY; i++) {
  3113. if (history[i]) {
  3114. free(history[i]);
  3115. history[i] = 0;
  3116. }
  3117. }
  3118. historylen = 0;
  3119. }
  3120. static void bestlineAtExit(void) {
  3121. bestlineDisableRawMode();
  3122. bestlineHistoryFree();
  3123. bestlineRingFree();
  3124. }
  3125. int bestlineHistoryAdd(const char *line) {
  3126. char *linecopy;
  3127. if (!BESTLINE_MAX_HISTORY) return 0;
  3128. if (historylen && !strcmp(history[historylen-1], line)) return 0;
  3129. if (!(linecopy = strdup(line))) return 0;
  3130. if (historylen == BESTLINE_MAX_HISTORY) {
  3131. free(history[0]);
  3132. memmove(history,history+1,sizeof(char*)*(BESTLINE_MAX_HISTORY-1));
  3133. historylen--;
  3134. }
  3135. history[historylen++] = linecopy;
  3136. return 1;
  3137. }
  3138. /**
  3139. * Saves line editing history to file.
  3140. *
  3141. * @return 0 on success, or -1 w/ errno
  3142. */
  3143. int bestlineHistorySave(const char *filename) {
  3144. FILE *fp;
  3145. unsigned j;
  3146. mode_t old_umask;
  3147. old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
  3148. fp = fopen(filename,"w");
  3149. umask(old_umask);
  3150. if (!fp) return -1;
  3151. chmod(filename,S_IRUSR|S_IWUSR);
  3152. for (j = 0; j < historylen; j++) {
  3153. fputs(history[j],fp);
  3154. fputc('\n',fp);
  3155. }
  3156. fclose(fp);
  3157. return 0;
  3158. }
  3159. /**
  3160. * Loads history from the specified file.
  3161. *
  3162. * If the file doesn't exist, zero is returned and this will do nothing.
  3163. * If the file does exists and the operation succeeded zero is returned
  3164. * otherwise on error -1 is returned.
  3165. *
  3166. * @return 0 on success, or -1 w/ errno
  3167. */
  3168. int bestlineHistoryLoad(const char *filename) {
  3169. char **h;
  3170. int rc, fd, err;
  3171. size_t i, j, k, n, t;
  3172. char *m, *e, *p, *q, *f, *s;
  3173. err = errno, rc = 0;
  3174. if (!BESTLINE_MAX_HISTORY) return 0;
  3175. if (!(h = (char**)calloc(2*BESTLINE_MAX_HISTORY,sizeof(char*)))) return -1;
  3176. if ((fd = open(filename,O_RDONLY)) != -1) {
  3177. if ((n = GetFdSize(fd))) {
  3178. if ((m = (char *)mmap(0,n,PROT_READ,MAP_SHARED,fd,0))!=MAP_FAILED) {
  3179. for (i = 0, e = (p = m) + n; p < e; p = f + 1) {
  3180. if (!(q = (char *)memchr(p, '\n', e - p))) q = e;
  3181. for (f = q; q > p; --q) {
  3182. if (q[-1] != '\n' && q[-1] != '\r') break;
  3183. }
  3184. if (q > p) {
  3185. h[i * 2 + 0] = p;
  3186. h[i * 2 + 1] = q;
  3187. i = (i + 1) % BESTLINE_MAX_HISTORY;
  3188. }
  3189. }
  3190. bestlineHistoryFree();
  3191. for (j = 0; j < BESTLINE_MAX_HISTORY; ++j) {
  3192. if (h[(k = (i + j) % BESTLINE_MAX_HISTORY) * 2]) {
  3193. if ((s = (char *)malloc((t=h[k*2+1]-h[k*2])+1))) {
  3194. memcpy(s,h[k*2],t),s[t]=0;
  3195. history[historylen++] = s;
  3196. }
  3197. }
  3198. }
  3199. munmap(m,n);
  3200. } else {
  3201. rc = -1;
  3202. }
  3203. }
  3204. close(fd);
  3205. } else if (errno == ENOENT) {
  3206. errno = err;
  3207. } else {
  3208. rc = -1;
  3209. }
  3210. free(h);
  3211. return rc;
  3212. }
  3213. /**
  3214. * Reads line interactively.
  3215. *
  3216. * This function can be used instead of bestline() in cases where we
  3217. * know for certain we're dealing with a terminal, which means we can
  3218. * avoid linking any stdio code.
  3219. *
  3220. * @return chomped allocated string of read line or null on eof/error
  3221. */
  3222. char *bestlineRaw(const char *prompt, int infd, int outfd) {
  3223. char *buf;
  3224. ssize_t rc;
  3225. static char once;
  3226. struct sigaction sa[3];
  3227. if (!once) atexit(bestlineAtExit), once = 1;
  3228. if (enableRawMode(infd) == -1) return 0;
  3229. buf = 0;
  3230. gotint = 0;
  3231. sigemptyset(&sa->sa_mask);
  3232. sa->sa_flags = 0;
  3233. sa->sa_handler = bestlineOnInt;
  3234. sigaction(SIGINT,sa,sa+1);
  3235. sigaction(SIGQUIT,sa,sa+2);
  3236. rc = bestlineEdit(infd,outfd,prompt,&buf);
  3237. bestlineDisableRawMode();
  3238. sigaction(SIGQUIT,sa+2,0);
  3239. sigaction(SIGINT,sa+1,0);
  3240. if (gotint) {
  3241. free(buf);
  3242. buf = 0;
  3243. raise(gotint);
  3244. errno = EINTR;
  3245. rc = -1;
  3246. }
  3247. if (rc != -1) {
  3248. bestlineWriteStr(outfd,"\n");
  3249. return buf;
  3250. } else {
  3251. free(buf);
  3252. return 0;
  3253. }
  3254. }
  3255. /**
  3256. * Reads line intelligently.
  3257. *
  3258. * The high level function that is the main API of the bestline library.
  3259. * This function checks if the terminal has basic capabilities, just checking
  3260. * for a blacklist of inarticulate terminals, and later either calls the line
  3261. * editing function or uses dummy fgets() so that you will be able to type
  3262. * something even in the most desperate of the conditions.
  3263. *
  3264. * @param prompt is printed before asking for input if we have a term
  3265. * and this may be set to empty or null to disable and prompt may
  3266. * contain ansi escape sequences, color, utf8, etc.
  3267. * @return chomped allocated string of read line or null on eof/error
  3268. */
  3269. char *bestline(const char *prompt) {
  3270. if (prompt && *prompt &&
  3271. (strchr(prompt, '\n') || strchr(prompt, '\t') ||
  3272. strchr(prompt + 1, '\r'))) {
  3273. errno = EINVAL;
  3274. return 0;
  3275. }
  3276. if ((!isatty(fileno(stdin)) ||
  3277. !isatty(fileno(stdout)))) {
  3278. if (prompt && *prompt && (IsCharDev(fileno(stdin)) &&
  3279. IsCharDev(fileno(stdout)))) {
  3280. fputs(prompt,stdout);
  3281. fflush(stdout);
  3282. }
  3283. return GetLine(stdin, stdout);
  3284. } else if (bestlineIsUnsupportedTerm()) {
  3285. if (prompt && *prompt) {
  3286. fputs(prompt,stdout);
  3287. fflush(stdout);
  3288. }
  3289. return GetLine(stdin, stdout);
  3290. } else {
  3291. fflush(stdout);
  3292. return bestlineRaw(prompt,fileno(stdin),fileno(stdout));
  3293. }
  3294. }
  3295. /**
  3296. * Reads line intelligently w/ history, e.g.
  3297. *
  3298. * // see ~/.foo_history
  3299. * main() {
  3300. * char *line;
  3301. * while ((line = bestlineWithHistory("IN> ", "foo"))) {
  3302. * printf("OUT> %s\n", line);
  3303. * free(line);
  3304. * }
  3305. * }
  3306. *
  3307. * @param prompt is printed before asking for input if we have a term
  3308. * and this may be set to empty or null to disable and prompt may
  3309. * contain ansi escape sequences, color, utf8, etc.
  3310. * @param prog is name of your app, used to generate history filename
  3311. * however if it contains a slash / dot then we'll assume prog is
  3312. * the history filename which as determined by the caller
  3313. * @return chomped allocated string of read line or null on eof/error
  3314. */
  3315. char *bestlineWithHistory(const char *prompt, const char *prog) {
  3316. char *line;
  3317. struct abuf path;
  3318. const char *a, *b;
  3319. abInit(&path);
  3320. if (prog) {
  3321. if (strchr(prog, '/') || strchr(prog, '.')) {
  3322. abAppends(&path, prog);
  3323. } else {
  3324. b = "";
  3325. if (!(a = getenv("HOME"))) {
  3326. if (!(a = getenv("HOMEDRIVE")) ||
  3327. !(b = getenv("HOMEPATH"))) {
  3328. a = "";
  3329. }
  3330. }
  3331. if (*a) {
  3332. abAppends(&path, a);
  3333. abAppends(&path, b);
  3334. abAppendw(&path, '/');
  3335. }
  3336. abAppendw(&path, '.');
  3337. abAppends(&path, prog);
  3338. abAppends(&path, "_history");
  3339. }
  3340. }
  3341. if (path.len) {
  3342. bestlineHistoryLoad(path.b);
  3343. }
  3344. line = bestline(prompt);
  3345. if (path.len && line && *line) {
  3346. /* history here is inefficient but helpful when the user has multiple
  3347. * repls open at the same time, so history propagates between them */
  3348. bestlineHistoryLoad(path.b);
  3349. bestlineHistoryAdd(line);
  3350. bestlineHistorySave(path.b);
  3351. }
  3352. abFree(&path);
  3353. return line;
  3354. }
  3355. /**
  3356. * Registers tab completion callback.
  3357. */
  3358. void bestlineSetCompletionCallback(bestlineCompletionCallback *fn) {
  3359. completionCallback = fn;
  3360. }
  3361. /**
  3362. * Registers hints callback.
  3363. *
  3364. * Register a hits function to be called to show hits to the user at the
  3365. * right of the prompt.
  3366. */
  3367. void bestlineSetHintsCallback(bestlineHintsCallback *fn) {
  3368. hintsCallback = fn;
  3369. }
  3370. /**
  3371. * Sets free hints callback.
  3372. *
  3373. * This registers a function to free the hints returned by the hints
  3374. * callback registered with bestlineSetHintsCallback().
  3375. */
  3376. void bestlineSetFreeHintsCallback(bestlineFreeHintsCallback *fn) {
  3377. freeHintsCallback = fn;
  3378. }
  3379. /**
  3380. * Sets character translation callback.
  3381. */
  3382. void bestlineSetXlatCallback(bestlineXlatCallback *fn) {
  3383. xlatCallback = fn;
  3384. }
  3385. /**
  3386. * Adds completion.
  3387. *
  3388. * This function is used by the callback function registered by the user
  3389. * in order to add completion options given the input string when the
  3390. * user typed <tab>. See the example.c source code for a very easy to
  3391. * understand example.
  3392. */
  3393. void bestlineAddCompletion(bestlineCompletions *lc, const char *str) {
  3394. size_t len;
  3395. char *copy, **cvec;
  3396. if ((copy = (char *)malloc((len = strlen(str))+1))) {
  3397. memcpy(copy,str,len+1);
  3398. if ((cvec = (char **)realloc(lc->cvec,(lc->len+1)*sizeof(*lc->cvec)))) {
  3399. lc->cvec = cvec;
  3400. lc->cvec[lc->len++] = copy;
  3401. } else {
  3402. free(copy);
  3403. }
  3404. }
  3405. }
  3406. /**
  3407. * Frees list of completion option populated by bestlineAddCompletion().
  3408. */
  3409. void bestlineFreeCompletions(bestlineCompletions *lc) {
  3410. size_t i;
  3411. for (i = 0; i < lc->len; i++)
  3412. free(lc->cvec[i]);
  3413. if (lc->cvec)
  3414. free(lc->cvec);
  3415. }
  3416. /**
  3417. * Enables "mask mode".
  3418. *
  3419. * When it is enabled, instead of the input that the user is typing, the
  3420. * terminal will just display a corresponding number of asterisks, like
  3421. * "****". This is useful for passwords and other secrets that should
  3422. * not be displayed.
  3423. *
  3424. * @see bestlineMaskModeDisable()
  3425. */
  3426. void bestlineMaskModeEnable(void) {
  3427. maskmode = 1;
  3428. }
  3429. /**
  3430. * Disables "mask mode".
  3431. */
  3432. void bestlineMaskModeDisable(void) {
  3433. maskmode = 0;
  3434. }