regularExp.cpp 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859
  1. /*------------------------------------------------------------------------*
  2. * static const char CVSID[] = "$Id: regularExp.c,v 1.30 2006/08/13 21:47:45 yooden Exp $";
  3. * `CompileRE', `ExecRE', and `substituteRE' -- regular expression parsing
  4. *
  5. * This is a HIGHLY ALTERED VERSION of Henry Spencer's `regcomp' and
  6. * `regexec' code adapted for NEdit.
  7. *
  8. * .-------------------------------------------------------------------.
  9. * | ORIGINAL COPYRIGHT NOTICE: |
  10. * | |
  11. * | Copyright (c) 1986 by University of Toronto. |
  12. * | Written by Henry Spencer. Not derived from licensed software. |
  13. * | |
  14. * | Permission is granted to anyone to use this software for any |
  15. * | purpose on any computer system, and to redistribute it freely, |
  16. * | subject to the following restrictions: |
  17. * | |
  18. * | 1. The author is not responsible for the consequences of use of |
  19. * | this software, no matter how awful, even if they arise |
  20. * | from defects in it. |
  21. * | |
  22. * | 2. The origin of this software must not be misrepresented, either |
  23. * | by explicit claim or by omission. |
  24. * | |
  25. * | 3. Altered versions should be plainly marked as such, and must not |
  26. * | be misrepresented as being the original software. |
  27. * `-------------------------------------------------------------------'
  28. *
  29. * This is free software; you can redistribute it and/or modify it under the
  30. * terms of the GNU General Public License as published by the Free Software
  31. * Foundation; either version 2 of the License, or (at your option) any later
  32. * version. In addition, you may distribute version of this program linked to
  33. * Motif or Open Motif. See README for details.
  34. *
  35. * This software is distributed in the hope that it will be useful, but WITHOUT
  36. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  37. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  38. * for more details.
  39. *
  40. * You should have received a copy of the GNU General Public License along with
  41. * software; if not, write to the Free Software Foundation, Inc., 59 Temple
  42. * Place, Suite 330, Boston, MA 02111-1307 USA
  43. *
  44. *
  45. * BEWARE that some of this code is subtly aware of the way operator
  46. * precedence is structured in regular expressions. Serious changes in
  47. * regular-expression syntax might require a total rethink.
  48. * -- Henry Spencer
  49. * (Yes, it did!) -- Christopher Conrad, Dec. 1999
  50. *
  51. * January, 1994, Mark Edel
  52. * Consolidated files, changed names of external functions to avoid
  53. * potential conflicts with native regcomp and regexec functions, changed
  54. * error reporting to NEdit form, added multi-line and reverse searching,
  55. * and added \n \t \u \U \l \L.
  56. *
  57. * June, 1996, Mark Edel
  58. * Bug in NEXT macro, didn't work for expressions which compiled to over
  59. * 256 bytes.
  60. *
  61. * December, 1999, Christopher Conrad
  62. * Reformatted code for readability, improved error output, added octal and
  63. * hexadecimal escapes, added back-references (\1-\9), added positive look
  64. * ahead: (?=...), added negative lookahead: (?!...), added non-capturing
  65. * parentheses: (?:...), added case insensitive constructs (?i...) and
  66. * (?I...), added newline matching constructs (?n...) and (?N...), added
  67. * regex comments: (?#...), added shortcut escapes: \d\D\l\L\s\S\w\W\y\Y.
  68. * Added "not a word boundary" anchor \B.
  69. *
  70. * July, 2002, Eddy De Greef
  71. * Added look behind, both positive (?<=...) and negative (?<!...) for
  72. * bounded-length patterns.
  73. *
  74. * November, 2004, Eddy De Greef
  75. * Added constrained matching (allowing specification of the logical end
  76. * of the string iso. matching till \0), and fixed several (probably
  77. * very old) string overrun errors that could easily result in crashes,
  78. * especially in client code.
  79. *
  80. * June, 2008, David Weenink
  81. * Adaptation for use in the Praat program.
  82. * Changed reg_error to call Melder_error.
  83. * Extra parameter for SubstituteRE to allow error differentiation
  84. * (not enough memory can be repaired upstream).
  85. *
  86. * April, 2018, Paul Boersma
  87. * Added Unicode-based definitions of letters, digits, spaces and word boundaries.
  88. * Thereby removed shortcut escapes from classes.
  89. */
  90. #include <ctype.h>
  91. #include <limits.h>
  92. #include "melder.h"
  93. /* The first byte of the regexp internal `program' is a magic number to help
  94. guard against corrupted data; the compiled regex code really begins in the
  95. second byte. */
  96. #define MAGIC 0234
  97. /* The "internal use only" fields in `regexp.h' are present to pass info from
  98. * `CompileRE' to `ExecRE' which permits the execute phase to run lots faster on
  99. * simple cases. They are:
  100. *
  101. * match_start Character that must begin a match; '\0' if none obvious.
  102. * anchor Is the match anchored (at beginning-of-line only)?
  103. *
  104. * `match_start' and `anchor' permit very fast decisions on suitable starting
  105. * points for a match, considerably reducing the work done by ExecRE. */
  106. /* STRUCTURE FOR A REGULAR EXPRESSION (regex) `PROGRAM'.
  107. *
  108. * This is essentially a linear encoding of a nondeterministic finite-state
  109. * machine or NFA (aka syntax charts or `railroad normal form' in parsing
  110. * technology). Each node is an opcode plus a NEXT pointer, possibly
  111. * followed by operands. NEXT pointers of all nodes except BRANCH implement
  112. * concatenation; a NEXT pointer with a BRANCH on both ends of it is
  113. * connecting two alternatives. (Here we have one of the subtle syntax
  114. * dependencies: an individual BRANCH (as opposed to a collection of them) is
  115. * never concatenated with anything because of operator precedence.) The
  116. * operand of some types of nodes is a literal string; for others, it is a node
  117. * leading into a sub-FSM. In particular, the operand of a BRANCH node is the
  118. * first node of the branch. (NB this is _NOT_ a tree structure: the tail of
  119. * the branch connects to the thing following the set of BRANCHes.)
  120. *
  121. * The opcodes are: */
  122. /* DEFINITION VALUE MEANING */
  123. #define END 1 /* End of program. */
  124. /* Zero width positional assertions. */
  125. #define BOL 2 /* Match position at beginning of line. */
  126. #define EOL 3 /* Match position at end of line. */
  127. #define BOWORD 4 /* Match "" representing word delimiter or BOL */
  128. #define EOWORD 5 /* Match "" representing word delimiter or EOL */
  129. #define NOT_BOUNDARY 6 /* Not word boundary (\B, opposite of < and >) */
  130. /* Op codes with null terminated string operands. */
  131. #define EXACTLY 7 /* Match this string. */
  132. #define SIMILAR 8 /* Match this case insensitive string */
  133. #define ANY_OF 9 /* Match any character in the set. */
  134. #define ANY_BUT 10 /* Match any character not in the set. */
  135. /* Op codes to match any character. */
  136. #define ANY 11 /* Match any one character (implements '.') */
  137. #define EVERY 12 /* Same as ANY but matches newline. */
  138. /* Shortcut escapes, \d, \D, \l, \L, \s, \S, \w, \W, \y, \Y. */
  139. #define DIGIT 13 /* Match any digit, i.e. [0123456789] */
  140. #define NOT_DIGIT 14 /* Match any non-digit, i.e. [^0123456789] */
  141. #define LETTER 15 /* Match any letter character [a-zA-Z] */
  142. #define NOT_LETTER 16 /* Match any non-letter character [^a-zA-Z] */
  143. #define SPACE 17 /* Match any whitespace character EXCEPT \n */
  144. #define SPACE_NL 18 /* Match any whitespace character INCLUDING \n */
  145. #define NOT_SPACE 19 /* Match any non-whitespace character */
  146. #define NOT_SPACE_NL 20 /* Same as NOT_SPACE but matches newline. */
  147. #define WORD_CHAR 21 /* Match any word character [a-zA-Z0-9_] */
  148. #define NOT_WORD_CHAR 22 /* Match any non-word character [^a-zA-Z0-9_] */
  149. #define IS_DELIM 23 /* Match any character that's a word delimiter */
  150. #define NOT_DELIM 24 /* Match any character NOT a word delimiter */
  151. /* Quantifier nodes. (Only applied to SIMPLE nodes. Quantifiers applied to non
  152. SIMPLE nodes or larger atoms are implemented using complex constructs.)*/
  153. #define STAR 25 /* Match this (simple) thing 0 or more times. */
  154. #define LAZY_STAR 26 /* Minimal matching STAR */
  155. #define QUESTION 27 /* Match this (simple) thing 0 or 1 times. */
  156. #define LAZY_QUESTION 28 /* Minimal matching QUESTION */
  157. #define PLUS 29 /* Match this (simple) thing 1 or more times. */
  158. #define LAZY_PLUS 30 /* Minimal matching PLUS */
  159. #define BRACE 31 /* Match this (simple) thing m to n times. */
  160. #define LAZY_BRACE 32 /* Minimal matching BRACE */
  161. /* Nodes used to build complex constructs. */
  162. #define NOTHING 33 /* Match empty string (always matches) */
  163. #define BRANCH 34 /* Match this alternative, or the next... */
  164. #define BACK 35 /* Always matches, NEXT ptr points backward. */
  165. #define INIT_COUNT 36 /* Initialize {m,n} counter to zero */
  166. #define INC_COUNT 37 /* Increment {m,n} counter by one */
  167. #define TEST_COUNT 38 /* Test {m,n} counter against operand */
  168. /* Back Reference nodes. */
  169. #define BACK_REF 39 /* Match latest matched parenthesized text */
  170. #define BACK_REF_CI 40 /* Case insensitive version of BACK_REF */
  171. #define X_REGEX_BR 41 /* Cross-Regex Back-Ref for syntax highlighting */
  172. #define X_REGEX_BR_CI 42 /* Case insensitive version of X_REGEX_BR_CI */
  173. /* Various nodes used to implement parenthetical constructs. */
  174. #define POS_AHEAD_OPEN 43 /* Begin positive look ahead */
  175. #define NEG_AHEAD_OPEN 44 /* Begin negative look ahead */
  176. #define LOOK_AHEAD_CLOSE 45 /* End positive or negative look ahead */
  177. #define POS_BEHIND_OPEN 46 /* Begin positive look behind */
  178. #define NEG_BEHIND_OPEN 47 /* Begin negative look behind */
  179. #define LOOK_BEHIND_CLOSE 48 /* Close look behind */
  180. #define OPEN 49 /* Open for capturing parentheses. */
  181. /* OPEN+1 is number 1, etc. */
  182. #define CLOSE (OPEN + NSUBEXP) /* Close for capturing parentheses. */
  183. #define LAST_PAREN (CLOSE + NSUBEXP)
  184. #if (LAST_PAREN > UCHAR_MAX)
  185. #error "Too many parentheses for storage in an unsigned char (LAST_PAREN too big.)"
  186. #endif
  187. /* The next_ptr () function can consume up to 30% of the time during matching
  188. because it is called an immense number of times (an average of 25
  189. next_ptr() calls per match() call was witnessed for Perl syntax
  190. highlighting). Therefore it is well worth removing some of the function
  191. call overhead by selectively inlining the next_ptr() calls. Moreover,
  192. the inlined code can be simplified for matching because one of the tests,
  193. only necessary during compilation, can be left out.
  194. The net result of using this inlined version at two critical places is
  195. a 25% speedup (again, witnesses on Perl syntax highlighting). */
  196. #define NEXT_PTR(in_ptr, out_ptr)\
  197. next_ptr_offset = GET_OFFSET (in_ptr);\
  198. if (next_ptr_offset == 0)\
  199. out_ptr = NULL;\
  200. else {\
  201. if (GET_OP_CODE (in_ptr) == BACK)\
  202. out_ptr = in_ptr - next_ptr_offset;\
  203. else \
  204. out_ptr = in_ptr + next_ptr_offset;\
  205. }
  206. /* OPCODE NOTES:
  207. ------------
  208. All nodes consist of an 8 bit op code followed by 2 bytes that make up a 16
  209. bit NEXT pointer. Some nodes have a null terminated character string operand
  210. following the NEXT pointer. Other nodes may have an 8 bit index operand.
  211. The TEST_COUNT node has an index operand followed by a 16 bit test value.
  212. The BRACE and LAZY_BRACE nodes have two 16 bit values for min and max but no
  213. index value.
  214. SIMILAR
  215. Operand(s): null terminated string
  216. Implements a case insensitive match of a string. Mostly intended for use
  217. in syntax highlighting patterns for keywords of languages like FORTRAN
  218. and Ada that are case insensitive. The regex text in this node is
  219. converted to lower case during regex compile.
  220. DIGIT, NOT_DIGIT, LETTER, NOT_LETTER, SPACE, NOT_SPACE, WORD_CHAR,
  221. NOT_WORD_CHAR
  222. Operand(s): None
  223. Implements shortcut escapes \d, \D, \l, \L, \s, \S, \w, \W.
  224. The Unicode-aware functions Melder_isDecimalNumber(), Melder_isLetter(),
  225. Melder_isHorizontalSpace(), and Melder_isWordCharacter are
  226. used to implement these in the hopes of increasing portability.
  227. NOT_BOUNDARY
  228. Operand(s): None
  229. Implements \B as a zero width assertion that the current character is
  230. NOT on a word boundary. Word boundaries are defined to be the position
  231. between two characters where one of those characters is
  232. a Unicode word character and the other character is not.
  233. IS_DELIM
  234. Operand(s): None
  235. Implements \y as any character that is a Unicode word delimiter.
  236. NOT_DELIM
  237. Operand(s): None
  238. Implements \Y as any character that is NOT a Unicode word delimiter.
  239. STAR, PLUS, QUESTION, and complex '*', '+', and '?'
  240. Operand(s): None (Note: NEXT pointer is usually zero. The code that
  241. processes this node skips over it.)
  242. Complex (parenthesized) versions implemented as circular BRANCH
  243. structures using BACK. SIMPLE versions (one character per match) are
  244. implemented separately for speed and to minimize recursion.
  245. BRACE, LAZY_BRACE
  246. Operand(s): minimum value (2 bytes), maximum value (2 bytes)
  247. Implements the {m,n} construct for atoms that are SIMPLE.
  248. BRANCH
  249. Operand(s): None
  250. The set of branches constituting a single choice are hooked together
  251. with their NEXT pointers, since precedence prevents anything being
  252. concatenated to any individual branch. The NEXT pointer of the last
  253. BRANCH in a choice points to the thing following the whole choice. This
  254. is also where the final NEXT pointer of each individual branch points;
  255. each branch starts with the operand node of a BRANCH node.
  256. BACK
  257. Operand(s): None
  258. Normal NEXT pointers all implicitly point forward. Back implicitly
  259. points backward. BACK exists to make loop structures possible.
  260. INIT_COUNT
  261. Operand(s): index (1 byte)
  262. Initializes the count array element referenced by the index operand.
  263. This node is used to build general (i.e. parenthesized) {m,n} constructs.
  264. INC_COUNT
  265. Operand(s): index (1 byte)
  266. Increments the count array element referenced by the index operand.
  267. This node is used to build general (i.e. parenthesized) {m,n} constructs.
  268. TEST_COUNT
  269. Operand(s): index (1 byte), test value (2 bytes)
  270. Tests the current value of the count array element specified by the
  271. index operand against the test value. If the current value is less than
  272. the test value, control passes to the node after that TEST_COUNT node.
  273. Otherwise control passes to the node referenced by the NEXT pointer for
  274. the TEST_COUNT node. This node is used to build general (i.e.
  275. parenthesized) {m,n} constructs.
  276. BACK_REF, BACK_REF_CI
  277. Operand(s): index (1 byte, value 1-9)
  278. Implements back references. This node will attempt to match whatever text
  279. was most recently captured by the index'th set of parentheses.
  280. BACK_REF_CI is case insensitive version.
  281. X_REGEX_BR, X_REGEX_BR_CI
  282. (NOT IMPLEMENTED YET)
  283. Operand(s): index (1 byte, value 1-9)
  284. Implements back references into a previously matched but separate regular
  285. expression. This is used by syntax highlighting patterns. This node will
  286. attempt to match whatever text was most captured by the index'th set of
  287. parentheses of the separate regex passed to ExecRE. X_REGEX_BR_CI is case
  288. insensitive version.
  289. POS_AHEAD_OPEN, NEG_AHEAD_OPEN, LOOK_AHEAD_CLOSE
  290. Operand(s): None
  291. Implements positive and negative look ahead. Look ahead is an assertion
  292. that something is either there or not there. Once this is determined the
  293. regex engine backtracks to where it was just before the look ahead was
  294. encountered, i.e. look ahead is a zero width assertion.
  295. POS_BEHIND_OPEN, NEG_BEHIND_OPEN, LOOK_BEHIND_CLOSE
  296. Operand(s): 2x2 bytes for OPEN (match boundaries), None for CLOSE
  297. Implements positive and negative look behind. Look behind is an assertion
  298. that something is either there or not there in front of the current
  299. position. Look behind is a zero width assertion, with the additional
  300. constraint that it must have a bounded length (for complexity and
  301. efficiency reasons; note that most other implementation even impose
  302. fixed length).
  303. OPEN, CLOSE
  304. Operand(s): None
  305. OPEN + n = Start of parenthesis 'n', CLOSE + n = Close of parenthesis
  306. 'n', and are numbered at compile time.
  307. */
  308. /* A node is one char of opcode followed by two chars of NEXT pointer plus
  309. * any operands. NEXT pointers are stored as two 8-bit pieces, high order
  310. * first. The value is a positive offset from the opcode of the node
  311. * containing it. An operand, if any, simply follows the node. (Note that
  312. * much of the code generation knows about this implicit relationship.)
  313. *
  314. * Using two bytes for NEXT_PTR_SIZE is vast overkill for most things,
  315. * but allows patterns to get big without disasters. */
  316. #define OP_CODE_SIZE 1
  317. #define NEXT_PTR_SIZE 2
  318. #define INDEX_SIZE 1
  319. #define LENGTH_SIZE 4
  320. #define NODE_SIZE (NEXT_PTR_SIZE + OP_CODE_SIZE)
  321. #define GET_OP_CODE(p) (*(char32 *)(p))
  322. #define OPERAND(p) ((p) + NODE_SIZE)
  323. #define GET_OFFSET(p) ((( *((p) + 1) & 0377) << 8) + (( *((p) + 2)) & 0377))
  324. #define PUT_OFFSET_L(v) (char32)(((v) >> 8) & 0377)
  325. #define PUT_OFFSET_R(v) (char32) ((v) & 0377)
  326. #define GET_LOWER(p) ((( *((p) + NODE_SIZE) & 0377) << 8) + \
  327. (( *((p) + NODE_SIZE+1)) & 0377))
  328. #define GET_UPPER(p) ((( *((p) + NODE_SIZE+2) & 0377) << 8) + \
  329. (( *((p) + NODE_SIZE+3)) & 0377))
  330. /* Utility definitions. */
  331. #define REG_FAIL(m) {*Error_Ptr = (m); return (NULL);}
  332. #define IS_QUANTIFIER(c) ((c) == '*' || (c) == '+' || \
  333. (c) == '?' || (c) == Brace_Char)
  334. #define SET_BIT(i,n) ((i) |= (1 << ((n) - 1)))
  335. #define TEST_BIT(i,n) ((i) & (1 << ((n) - 1)))
  336. #define U_CHAR_AT(p) ((unsigned int) *(char32 *)(p))
  337. /* Flags to be passed up and down via function parameters during compile. */
  338. #define WORST 0 /* Worst case. No assumptions can be made.*/
  339. #define HAS_WIDTH 1 /* Known never to match null string. */
  340. #define SIMPLE 2 /* Simple enough to be STAR/PLUS operand. */
  341. #define NO_PAREN 0 /* Only set by initial call to "chunk". */
  342. #define PAREN 1 /* Used for normal capturing parentheses. */
  343. #define NO_CAPTURE 2 /* Non-capturing parentheses (grouping only). */
  344. #define INSENSITIVE 3 /* Case insensitive parenthetical construct */
  345. #define SENSITIVE 4 /* Case sensitive parenthetical construct */
  346. #define NEWLINE 5 /* Construct to match newlines in most cases */
  347. #define NO_NEWLINE 6 /* Construct to match newlines normally */
  348. #define REG_INFINITY 0UL
  349. #define REG_ZERO 0UL
  350. #define REG_ONE 1UL
  351. /* Flags for function shortcut_escape() */
  352. #define CHECK_ESCAPE 0 /* Check an escape sequence for validity only. */
  353. #define CHECK_CLASS_ESCAPE 1 /* Check the validity of an escape within a character class */
  354. #define EMIT_NODE 2 /* Emit the appropriate node. */
  355. /* Number of bytes to offset from the beginning of the regex program to the start
  356. of the actual compiled regex code, i.e. skipping over the MAGIC number and
  357. the two counters at the front. */
  358. #define REGEX_START_OFFSET 3
  359. #define MAX_COMPILED_SIZE 32767UL /* Largest size a compiled regex can be.
  360. Probably could be 65535UL. */
  361. /* Global work variables for `CompileRE'. */
  362. static char32 *Reg_Parse; /* Input scan ptr (scans user's regex) */
  363. static int Total_Paren; /* Parentheses, (), counter. */
  364. static int Num_Braces; /* Number of general {m,n} constructs.
  365. {m,n} quantifiers of SIMPLE atoms are
  366. not included in this count. */
  367. static int Closed_Parens; /* Bit flags indicating () closure. */
  368. static int Paren_Has_Width; /* Bit flags indicating ()'s that are
  369. known to not match the empty string */
  370. static char32 Compute_Size; /* Address of this used as flag. */
  371. static char32 *Code_Emit_Ptr; /* When Code_Emit_Ptr is set to
  372. &Compute_Size no code is emitted.
  373. Instead, the size of code that WOULD
  374. have been generated is accumulated in
  375. Reg_Size. Otherwise, Code_Emit_Ptr
  376. points to where compiled regex code is
  377. to be written. */
  378. static unsigned long Reg_Size; /* Size of compiled regex code. */
  379. static const char32 **Error_Ptr; /* Place to store error messages so
  380. they can be returned by `CompileRE' */
  381. static char32 Error_Text [128];/* Sting to build error messages in. */
  382. static int Is_Case_Insensitive;
  383. static int Match_Newline;
  384. static int Enable_Counting_Quantifier = 1;
  385. static char32 Brace_Char;
  386. static char32 Default_Meta_Char [] = { '{', '.', '*', '+', '?', '[', '(', '|', ')', '^', '<', '>', '$', '\0' };
  387. static char32 *Meta_Char;
  388. typedef struct {
  389. long lower;
  390. long upper;
  391. } len_range;
  392. /* Forward declarations for functions used by `CompileRE'. */
  393. static char32 *alternative (int *flag_param, len_range *range_param);
  394. static char32 *back_ref (char32 *c, int *flag_param, int emit);
  395. static char32 *chunk (int paren, int *flag_param, len_range *range_param);
  396. static void emit_byte (char32 c);
  397. static void emit_class_byte (char32 c);
  398. static char32 *emit_node (int op_code);
  399. static char32 *emit_special (char32 op_code, unsigned long test_val, int index);
  400. static char32 literal_escape (char32 c);
  401. static char32 numeric_escape (char32 c, char32 **parse);
  402. static char32 *atom (int *flag_param, len_range *range_param);
  403. static void reg_error (const char32_t *str);
  404. static char32 *insert (char32 op, char32 *opnd, long min, long max, int index);
  405. static char32 *next_ptr (char32 *ptr);
  406. static void offset_tail (char32 *ptr, int offset, char32 *val);
  407. static void branch_tail (char32 *ptr, int offset, char32 *val);
  408. static char32 *piece (int *flag_param, len_range *range_param);
  409. static void tail (char32 *search_from, char32 *point_t);
  410. static char32 *shortcut_escape (char32 c, int *flag_param, int emit);
  411. /*----------------------------------------------------------------------*
  412. * CompileRE
  413. *
  414. * Compiles a regular expression into the internal format used by
  415. * `ExecRE'.
  416. *
  417. * The default behaviour wrt. case sensitivity and newline matching can
  418. * be controlled through the defaultFlags argument (Markus Schwarzenberg).
  419. * Future extensions are possible by using other flag bits.
  420. * Note that currently only the case sensitivity flag is effectively used.
  421. *
  422. * Beware that the optimization and preparation code in here knows about
  423. * some of the structure of the compiled regexp.
  424. *----------------------------------------------------------------------*/
  425. regexp *CompileRE_throwable (conststring32 exp, int defaultFlags) {
  426. conststring32 compileMessage;
  427. regexp *compiledRE = CompileRE (exp, & compileMessage, defaultFlags);
  428. if (compiledRE == NULL) {
  429. Melder_throw (U"Regular expression: ", compileMessage, U".");
  430. }
  431. return compiledRE;
  432. }
  433. regexp *CompileRE (conststring32 exp, conststring32 *errorText, int defaultFlags) {
  434. regexp *comp_regex = NULL;
  435. char32 *scan;
  436. int flags_local, pass;
  437. len_range range_local;
  438. if (Enable_Counting_Quantifier) {
  439. Brace_Char = '{';
  440. Meta_Char = &Default_Meta_Char [0];
  441. } else {
  442. Brace_Char = '*'; /* Bypass the '{' in */
  443. Meta_Char = &Default_Meta_Char [1]; /* Default_Meta_Char */
  444. }
  445. /* Set up errorText to receive failure reports. */
  446. Error_Ptr = errorText;
  447. *Error_Ptr = U"";
  448. if (exp == NULL) {
  449. REG_FAIL (U"NULL argument, `CompileRE\'");
  450. }
  451. Code_Emit_Ptr = &Compute_Size;
  452. Reg_Size = 0UL;
  453. /* We can't allocate space until we know how big the compiled form will be,
  454. but we can't compile it (and thus know how big it is) until we've got a
  455. place to put the code. So we cheat: we compile it twice, once with code
  456. generation turned off and size counting turned on, and once "for real".
  457. This also means that we don't allocate space until we are sure that the
  458. thing really will compile successfully, and we never have to move the
  459. code and thus invalidate pointers into it. (Note that it has to be in
  460. one piece because free() should be able to free it all.) */
  461. for (pass = 1; pass <= 2; pass++) {
  462. /*-------------------------------------------*
  463. * FIRST PASS: Determine size and legality. *
  464. * SECOND PASS: Emit code. *
  465. *-------------------------------------------*/
  466. /* Schwarzenberg:
  467. * If defaultFlags = 0 use standard defaults:
  468. * Is_Case_Insensitive: Case sensitive is the default
  469. * Match_Newline: Newlines are NOT matched by default
  470. * in character classes
  471. */
  472. Is_Case_Insensitive = ( (defaultFlags & REDFLT_CASE_INSENSITIVE) ? 1 : 0);
  473. Match_Newline = 0; /* ((defaultFlags & REDFLT_MATCH_NEWLINE) ? 1 : 0);
  474. Currently not used. Uncomment if needed. */
  475. Reg_Parse = (char32 *) exp;
  476. Total_Paren = 1;
  477. Num_Braces = 0;
  478. Closed_Parens = 0;
  479. Paren_Has_Width = 0;
  480. emit_byte (MAGIC);
  481. emit_byte ('%'); /* Placeholder for num of capturing parentheses. */
  482. emit_byte ('%'); /* Placeholder for num of general {m,n} constructs. */
  483. if (chunk (NO_PAREN, &flags_local, &range_local) == NULL) {
  484. return (NULL); /* Something went wrong */
  485. }
  486. if (pass == 1) {
  487. if (Reg_Size >= MAX_COMPILED_SIZE) {
  488. /* Too big for NEXT pointers NEXT_PTR_SIZE bytes long to span.
  489. This is a real issue since the first BRANCH node usually points
  490. to the end of the compiled regex code. */
  491. Melder_sprint (Error_Text,128, U"regexp > ", MAX_COMPILED_SIZE, U" bytes");
  492. REG_FAIL (Error_Text);
  493. }
  494. /* Allocate memory. */
  495. comp_regex = (regexp *) malloc (sizeof (regexp) + Reg_Size * sizeof (char32));
  496. if (comp_regex == NULL) {
  497. REG_FAIL (U"out of memory in `CompileRE\'");
  498. }
  499. Code_Emit_Ptr = (char32 *) comp_regex->program;
  500. }
  501. }
  502. comp_regex->program [1] = (char32) Total_Paren - 1;
  503. comp_regex->program [2] = (char32) Num_Braces;
  504. /*----------------------------------------*
  505. * Dig out information for optimizations. *
  506. *----------------------------------------*/
  507. comp_regex->match_start = '\0'; /* Worst-case defaults. */
  508. comp_regex->anchor = 0;
  509. /* First BRANCH. */
  510. scan = (char32 *) (comp_regex->program + REGEX_START_OFFSET);
  511. if (GET_OP_CODE (next_ptr (scan)) == END) { /* Only one top-level choice. */
  512. scan = OPERAND (scan);
  513. /* Starting-point info. */
  514. if (GET_OP_CODE (scan) == EXACTLY) {
  515. comp_regex->match_start = *OPERAND (scan);
  516. } else if (PLUS <= GET_OP_CODE (scan) &&
  517. GET_OP_CODE (scan) <= LAZY_PLUS) {
  518. /* Allow x+ or x+? at the start of the regex to be
  519. optimized. */
  520. if (GET_OP_CODE (scan + NODE_SIZE) == EXACTLY) {
  521. comp_regex->match_start = *OPERAND (scan + NODE_SIZE);
  522. }
  523. } else if (GET_OP_CODE (scan) == BOL) {
  524. comp_regex->anchor++;
  525. }
  526. }
  527. return (comp_regex);
  528. }
  529. /*----------------------------------------------------------------------*
  530. * chunk *
  531. * *
  532. * Process main body of regex or process a parenthesized "thing". *
  533. * *
  534. * Caller must absorb opening parenthesis. *
  535. * *
  536. * Combining parenthesis handling with the base level of regular *
  537. * expression is a trifle forced, but the need to tie the tails of the *
  538. * branches to what follows makes it hard to avoid. *
  539. *----------------------------------------------------------------------*/
  540. static char32 *chunk (int paren, int *flag_param, len_range *range_param) {
  541. char32 *ret_val = NULL;
  542. char32 *this_branch;
  543. char32 *ender = NULL;
  544. int this_paren = 0;
  545. int flags_local, first = 1, zero_width, i;
  546. int old_sensitive = Is_Case_Insensitive;
  547. int old_newline = Match_Newline;
  548. len_range range_local;
  549. int look_only = 0;
  550. char32 *emit_look_behind_bounds = NULL;
  551. *flag_param = HAS_WIDTH; /* Tentatively. */
  552. range_param->lower = 0; /* Idem */
  553. range_param->upper = 0;
  554. /* Make an OPEN node, if parenthesized. */
  555. if (paren == PAREN) {
  556. if (Total_Paren >= NSUBEXP) {
  557. Melder_sprint (Error_Text,128, U"number of ()'s > ", NSUBEXP);
  558. REG_FAIL (Error_Text)
  559. }
  560. this_paren = Total_Paren; Total_Paren++;
  561. ret_val = emit_node (OPEN + this_paren);
  562. } else if (paren == POS_AHEAD_OPEN || paren == NEG_AHEAD_OPEN) {
  563. *flag_param = WORST; /* Look ahead is zero width. */
  564. look_only = 1;
  565. ret_val = emit_node (paren);
  566. } else if (paren == POS_BEHIND_OPEN || paren == NEG_BEHIND_OPEN) {
  567. *flag_param = WORST; /* Look behind is zero width. */
  568. look_only = 1;
  569. /* We'll overwrite the zero length later on, so we save the ptr */
  570. ret_val = emit_special (paren, 0, 0);
  571. emit_look_behind_bounds = ret_val + NODE_SIZE;
  572. } else if (paren == INSENSITIVE) {
  573. Is_Case_Insensitive = 1;
  574. } else if (paren == SENSITIVE) {
  575. Is_Case_Insensitive = 0;
  576. } else if (paren == NEWLINE) {
  577. Match_Newline = 1;
  578. } else if (paren == NO_NEWLINE) {
  579. Match_Newline = 0;
  580. }
  581. /* Pick up the branches, linking them together. */
  582. do {
  583. this_branch = alternative (&flags_local, &range_local);
  584. if (this_branch == NULL) {
  585. return (NULL);
  586. }
  587. if (first) {
  588. first = 0;
  589. *range_param = range_local;
  590. if (ret_val == NULL) {
  591. ret_val = this_branch;
  592. }
  593. } else if (range_param->lower >= 0) {
  594. if (range_local.lower >= 0) {
  595. if (range_local.lower < range_param->lower) {
  596. range_param->lower = range_local.lower;
  597. }
  598. if (range_local.upper > range_param->upper) {
  599. range_param->upper = range_local.upper;
  600. }
  601. } else {
  602. range_param->lower = -1; /* Branches have different lengths */
  603. range_param->upper = -1;
  604. }
  605. }
  606. tail (ret_val, this_branch); /* Connect BRANCH -> BRANCH. */
  607. /* If any alternative could be zero width, consider the whole
  608. parenthisized thing to be zero width. */
  609. if (! (flags_local & HAS_WIDTH)) {
  610. *flag_param &= ~HAS_WIDTH;
  611. }
  612. /* Are there more alternatives to process? */
  613. if (*Reg_Parse != '|') {
  614. break;
  615. }
  616. Reg_Parse++;
  617. } while (1);
  618. /* Make a closing node, and hook it on the end. */
  619. if (paren == PAREN) {
  620. ender = emit_node (CLOSE + this_paren);
  621. } else if (paren == NO_PAREN) {
  622. ender = emit_node (END);
  623. } else if (paren == POS_AHEAD_OPEN || paren == NEG_AHEAD_OPEN) {
  624. ender = emit_node (LOOK_AHEAD_CLOSE);
  625. } else if (paren == POS_BEHIND_OPEN || paren == NEG_BEHIND_OPEN) {
  626. ender = emit_node (LOOK_BEHIND_CLOSE);
  627. } else {
  628. ender = emit_node (NOTHING);
  629. }
  630. tail (ret_val, ender);
  631. /* Hook the tails of the branch alternatives to the closing node. */
  632. for (this_branch = ret_val; this_branch != NULL;) {
  633. branch_tail (this_branch, NODE_SIZE, ender);
  634. this_branch = next_ptr (this_branch);
  635. }
  636. /* Check for proper termination. */
  637. if (paren != NO_PAREN && *Reg_Parse++ != ')') {
  638. REG_FAIL (U"missing right parenthesis \')\'");
  639. } else if (paren == NO_PAREN && *Reg_Parse != '\0') {
  640. if (*Reg_Parse == ')') {
  641. REG_FAIL (U"missing left parenthesis \'(\'");
  642. } else {
  643. REG_FAIL (U"junk on end"); /* "Can't happen" - NOTREACHED */
  644. }
  645. }
  646. /* Check whether look behind has a fixed size */
  647. if (emit_look_behind_bounds) {
  648. if (range_param->lower < 0) {
  649. REG_FAIL (U"look-behind does not have a bounded size");
  650. }
  651. if (range_param->upper > 65535L) {
  652. REG_FAIL (U"max. look-behind size is too large (>65535)")
  653. }
  654. if (Code_Emit_Ptr != &Compute_Size) {
  655. *emit_look_behind_bounds++ = PUT_OFFSET_L (range_param->lower);
  656. *emit_look_behind_bounds++ = PUT_OFFSET_R (range_param->lower);
  657. *emit_look_behind_bounds++ = PUT_OFFSET_L (range_param->upper);
  658. *emit_look_behind_bounds = PUT_OFFSET_R (range_param->upper);
  659. }
  660. }
  661. /* For look ahead/behind, the length should be set to zero again */
  662. if (look_only) {
  663. range_param->lower = 0;
  664. range_param->upper = 0;
  665. }
  666. zero_width = 0;
  667. /* Set a bit in Closed_Parens to let future calls to function `back_ref'
  668. know that we have closed this set of parentheses. */
  669. if (paren == PAREN && this_paren <= (int) sizeof (Closed_Parens) * CHAR_BIT) {
  670. SET_BIT (Closed_Parens, this_paren);
  671. /* Determine if a parenthesized expression is modified by a quantifier
  672. that can have zero width. */
  673. if (* (Reg_Parse) == '?' || * (Reg_Parse) == '*') {
  674. zero_width++;
  675. } else if (* (Reg_Parse) == '{' && Brace_Char == '{') {
  676. if (* (Reg_Parse + 1) == ',' || * (Reg_Parse + 1) == '}') {
  677. zero_width++;
  678. } else if (* (Reg_Parse + 1) == '0') {
  679. i = 2;
  680. while (* (Reg_Parse + i) == '0') {
  681. i++;
  682. }
  683. if (* (Reg_Parse + i) == ',') {
  684. zero_width++;
  685. }
  686. }
  687. }
  688. }
  689. /* If this set of parentheses is known to never match the empty string, set
  690. a bit in Paren_Has_Width to let future calls to function back_ref know
  691. that this set of parentheses has non-zero width. This will allow star
  692. (*) or question (?) quantifiers to be aplied to a back-reference that
  693. refers to this set of parentheses. */
  694. if ( (*flag_param & HAS_WIDTH) &&
  695. paren == PAREN &&
  696. !zero_width &&
  697. this_paren <= (int) (sizeof (Paren_Has_Width) * CHAR_BIT)) {
  698. SET_BIT (Paren_Has_Width, this_paren);
  699. }
  700. Is_Case_Insensitive = old_sensitive;
  701. Match_Newline = old_newline;
  702. return (ret_val);
  703. }
  704. /*----------------------------------------------------------------------*
  705. * alternative
  706. *
  707. * Processes one alternative of an '|' operator. Connects the NEXT
  708. * pointers of each regex atom together sequentialy.
  709. *----------------------------------------------------------------------*/
  710. static char32 *alternative (int *flag_param, len_range *range_param) {
  711. char32 *ret_val;
  712. char32 *chain;
  713. char32 *latest;
  714. int flags_local;
  715. len_range range_local;
  716. *flag_param = WORST; /* Tentatively. */
  717. range_param->lower = 0; /* Idem */
  718. range_param->upper = 0;
  719. ret_val = emit_node (BRANCH);
  720. chain = NULL;
  721. /* Loop until we hit the start of the next alternative, the end of this set
  722. of alternatives (end of parentheses), or the end of the regex. */
  723. while (*Reg_Parse != '|' && *Reg_Parse != ')' && *Reg_Parse != '\0') {
  724. latest = piece (&flags_local, &range_local);
  725. if (latest == NULL) {
  726. return (NULL); /* Something went wrong. */
  727. }
  728. *flag_param |= flags_local & HAS_WIDTH;
  729. if (range_local.lower < 0) {
  730. /* Not a fixed length */
  731. range_param->lower = -1;
  732. range_param->upper = -1;
  733. } else if (range_param->lower >= 0) {
  734. range_param->lower += range_local.lower;
  735. range_param->upper += range_local.upper;
  736. }
  737. if (chain != NULL) { /* Connect the regex atoms together sequentialy. */
  738. tail (chain, latest);
  739. }
  740. chain = latest;
  741. }
  742. if (chain == NULL) { /* Loop ran zero times. */
  743. (void) emit_node (NOTHING);
  744. }
  745. return (ret_val);
  746. }
  747. /*----------------------------------------------------------------------*
  748. * piece - something followed by possible '*', '+', '?', or "{m,n}"
  749. *
  750. * Note that the branching code sequences used for the general cases of
  751. * *, +. ?, and {m,n} are somewhat optimized: they use the same
  752. * NOTHING node as both the endmarker for their branch list and the
  753. * body of the last branch. It might seem that this node could be
  754. * dispensed with entirely, but the endmarker role is not redundant.
  755. *----------------------------------------------------------------------*/
  756. static char32 *piece (int *flag_param, len_range *range_param) {
  757. char32 *ret_val;
  758. char32 *next;
  759. char32 op_code;
  760. unsigned long min_max [2] = {REG_ZERO, REG_INFINITY};
  761. int flags_local, i, brace_present = 0;
  762. int lazy = 0, comma_present = 0;
  763. int digit_present [2] = {0, 0};
  764. len_range range_local;
  765. ret_val = atom (&flags_local, &range_local);
  766. if (ret_val == NULL) {
  767. return (NULL); /* Something went wrong. */
  768. }
  769. op_code = *Reg_Parse;
  770. if (!IS_QUANTIFIER (op_code)) {
  771. *flag_param = flags_local;
  772. *range_param = range_local;
  773. return (ret_val);
  774. } else if (op_code == '{') { /* {n,m} quantifier present */
  775. brace_present++;
  776. Reg_Parse++;
  777. /* This code will allow specifying a counting range in any of the
  778. following forms:
  779. {m,n} between m and n.
  780. {,n} same as {0,n} or between 0 and infinity.
  781. {m,} same as {m,0} or between m and infinity.
  782. {m} same as {m,m} or exactly m.
  783. {,} same as {0,0} or between 0 and infinity or just '*'.
  784. {} same as {0,0} or between 0 and infinity or just '*'.
  785. Note that specifying a max of zero, {m,0} is not allowed in the regex
  786. itself, but it is implemented internally that way to support '*', '+',
  787. and {min,} constructs and signals an unlimited number. */
  788. for (i = 0; i < 2; i++) {
  789. /* Look for digits of number and convert as we go. The numeric maximum
  790. value for max and min of 65,535 is due to using 2 bytes to store
  791. each value in the compiled regex code. */
  792. while (Melder_isAsciiDecimalNumber (*Reg_Parse)) {
  793. /* (6553 * 10 + 6) > 65535 (16 bit max) */
  794. if ( (min_max [i] == 6553UL && (*Reg_Parse - '0') <= 5) ||
  795. (min_max [i] <= 6552UL)) {
  796. min_max [i] = (min_max [i] * 10UL) +
  797. (unsigned long) (*Reg_Parse - '0');
  798. Reg_Parse++;
  799. digit_present [i]++;
  800. } else {
  801. if (i == 0) {
  802. Melder_sprint (Error_Text,128, U"min operand of {", min_max [0], *Reg_Parse, U",???} > 65535");
  803. } else {
  804. Melder_sprint (Error_Text,128, U"max operand of {", min_max [0], U",", min_max [1], *Reg_Parse, U"} > 65535");
  805. }
  806. REG_FAIL (Error_Text);
  807. }
  808. }
  809. if (!comma_present && *Reg_Parse == ',') {
  810. comma_present++;
  811. Reg_Parse++;
  812. }
  813. }
  814. /* A max of zero cannot be specified directly in the regex since it would
  815. signal a max of infinity. This code specifically disallows `{0,0}',
  816. `{,0}', and `{0}' which really means nothing to humans but would be
  817. interpreted as `{0,infinity}' or `*' if we didn't make this check. */
  818. if (digit_present [0] && (min_max [0] == REG_ZERO) && !comma_present) {
  819. REG_FAIL (U"{0} is an invalid range");
  820. } else if (digit_present [0] && (min_max [0] == REG_ZERO) &&
  821. digit_present [1] && (min_max [1] == REG_ZERO)) {
  822. REG_FAIL (U"{0,0} is an invalid range");
  823. } else if (digit_present [1] && (min_max [1] == REG_ZERO)) {
  824. if (digit_present [0]) {
  825. Melder_sprint (Error_Text,128, U"{", min_max [0], U",0} is an invalid range");
  826. REG_FAIL (Error_Text);
  827. } else {
  828. REG_FAIL (U"{,0} is an invalid range");
  829. }
  830. }
  831. if (!comma_present) {
  832. min_max [1] = min_max [0];
  833. } /* {x} means {x,x} */
  834. if (*Reg_Parse != '}') {
  835. REG_FAIL (U"{m,n} specification missing right \'}\'");
  836. } else if (min_max [1] != REG_INFINITY && min_max [0] > min_max [1]) {
  837. /* Disallow a backward range. */
  838. Melder_sprint (Error_Text,128, U"{", min_max [0], U",", min_max [1], U"} is an invalid range");
  839. REG_FAIL (Error_Text);
  840. }
  841. }
  842. Reg_Parse++;
  843. /* Check for a minimal matching (non-greedy or "lazy") specification. */
  844. if (*Reg_Parse == '?') {
  845. lazy = 1;
  846. Reg_Parse++;
  847. }
  848. /* Avoid overhead of counting if possible */
  849. if (op_code == '{') {
  850. if (min_max [0] == REG_ZERO && min_max [1] == REG_INFINITY) {
  851. op_code = '*';
  852. } else if (min_max [0] == REG_ONE && min_max [1] == REG_INFINITY) {
  853. op_code = '+';
  854. } else if (min_max [0] == REG_ZERO && min_max [1] == REG_ONE) {
  855. op_code = '?';
  856. } else if (min_max [0] == REG_ONE && min_max [1] == REG_ONE) {
  857. /* "x{1,1}" is the same as "x". No need to pollute the compiled
  858. regex with such nonsense. */
  859. *flag_param = flags_local;
  860. *range_param = range_local;
  861. return (ret_val);
  862. } else if (Num_Braces > (int) UCHAR_MAX) {
  863. Melder_sprint (Error_Text,128, U"number of {m,n} constructs > ", UCHAR_MAX);
  864. REG_FAIL (Error_Text);
  865. }
  866. }
  867. if (op_code == '+') {
  868. min_max [0] = REG_ONE;
  869. }
  870. if (op_code == '?') {
  871. min_max [1] = REG_ONE;
  872. }
  873. /* It is dangerous to apply certain quantifiers to a possibly zero width
  874. item. */
  875. if (! (flags_local & HAS_WIDTH)) {
  876. if (brace_present) {
  877. Melder_sprint (Error_Text,128, U"{", min_max [0], U",", min_max [1], U"} operand could be empty");
  878. } else {
  879. Melder_sprint (Error_Text,128, op_code, U" operand could be empty");
  880. }
  881. REG_FAIL (Error_Text);
  882. }
  883. *flag_param = (min_max [0] > REG_ZERO) ? (WORST | HAS_WIDTH) : WORST;
  884. if (range_local.lower >= 0) {
  885. if (min_max[1] != REG_INFINITY) {
  886. range_param->lower = range_local.lower * min_max[0];
  887. range_param->upper = range_local.upper * min_max[1];
  888. } else {
  889. range_param->lower = -1; /* Not a fixed-size length */
  890. range_param->upper = -1;
  891. }
  892. } else {
  893. range_param->lower = -1; /* Not a fixed-size length */
  894. range_param->upper = -1;
  895. }
  896. /*---------------------------------------------------------------------*
  897. * Symbol Legend For Node Structure Diagrams
  898. *---------------------------------------------------------------------*
  899. * (...) = general grouped thing
  900. * B = (B)ranch, K = bac(K), N = (N)othing
  901. * I = (I)nitialize count, C = Increment (C)ount
  902. * T~m = (T)est against mini(m)um- go to NEXT pointer if >= operand
  903. * T~x = (T)est against ma(x)imum- go to NEXT pointer if >= operand
  904. * '~' = NEXT pointer, \___| = forward pointer, |___/ = Backward pointer
  905. *---------------------------------------------------------------------*/
  906. if (op_code == '*' && (flags_local & SIMPLE)) {
  907. insert ( (lazy ? LAZY_STAR : STAR), ret_val, 0UL, 0UL, 0);
  908. } else if (op_code == '+' && (flags_local & SIMPLE)) {
  909. insert (lazy ? LAZY_PLUS : PLUS, ret_val, 0UL, 0UL, 0);
  910. } else if (op_code == '?' && (flags_local & SIMPLE)) {
  911. insert (lazy ? LAZY_QUESTION : QUESTION, ret_val, 0UL, 0UL, 0);
  912. } else if (op_code == '{' && (flags_local & SIMPLE)) {
  913. insert (lazy ? LAZY_BRACE : BRACE, ret_val, min_max [0], min_max [1], 0);
  914. } else if ( (op_code == '*' || op_code == '+') && lazy) {
  915. /* Node structure for (x)*? Node structure for (x)+? construct.
  916. * construct. (Same as (x)*? except for initial
  917. * forward jump into parenthesis.)
  918. *
  919. * ___6____
  920. * _______5_______ /________|______
  921. * | _4__ 1_\ /| ____ | _\
  922. * |/ | / |\ / |/ | | / |\
  923. * B~ N~ B~ (...)~ K~ N~ N~ B~ N~ B~ (...)~ K~ N~
  924. * \ \___2_______| \ \___________|
  925. * \_____3_______| \_____________|
  926. *
  927. */
  928. tail (ret_val, emit_node (BACK)); /* 1 */
  929. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 2,4 */
  930. (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 3 */
  931. next = emit_node (NOTHING); /* 2,3 */
  932. offset_tail (ret_val, NODE_SIZE, next); /* 2 */
  933. tail (ret_val, next); /* 3 */
  934. insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4,5 */
  935. tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 4 */
  936. offset_tail (ret_val, 3 * NODE_SIZE, ret_val); /* 5 */
  937. if (op_code == '+') {
  938. insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 6 */
  939. tail (ret_val, ret_val + (4 * NODE_SIZE)); /* 6 */
  940. }
  941. } else if (op_code == '*') {
  942. /* Node structure for (x)* construct.
  943. * ____1_____
  944. * | \
  945. * B~ (...)~ K~ B~ N~
  946. * \ \_|2 |\_|
  947. * \__3_______| 4
  948. */
  949. insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 1,3 */
  950. offset_tail (ret_val, NODE_SIZE, emit_node (BACK)); /* 2 */
  951. offset_tail (ret_val, NODE_SIZE, ret_val); /* 1 */
  952. tail (ret_val, emit_node (BRANCH)); /* 3 */
  953. tail (ret_val, emit_node (NOTHING)); /* 4 */
  954. } else if (op_code == '+') {
  955. /* Node structure for (x)+ construct.
  956. *
  957. * ____2_____
  958. * | \
  959. * (...)~ B~ K~ B~ N~
  960. * \_|\____|\_|
  961. * 1 3 4
  962. */
  963. next = emit_node (BRANCH); /* 1 */
  964. tail (ret_val, next); /* 1 */
  965. tail (emit_node (BACK), ret_val); /* 2 */
  966. tail (next, emit_node (BRANCH)); /* 3 */
  967. tail (ret_val, emit_node (NOTHING)); /* 4 */
  968. } else if (op_code == '?' && lazy) {
  969. /* Node structure for (x)?? construct.
  970. * _4__ 1_
  971. * / | / |
  972. * B~ N~ B~ (...)~ N~
  973. * \ \___2____|
  974. * \_____3____|
  975. */
  976. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 2,4 */
  977. (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 3 */
  978. next = emit_node (NOTHING); /* 1,2,3 */
  979. offset_tail (ret_val, 2 * NODE_SIZE, next); /* 1 */
  980. offset_tail (ret_val, NODE_SIZE, next); /* 2 */
  981. tail (ret_val, next); /* 3 */
  982. insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4 */
  983. tail (ret_val, (ret_val + (2 * NODE_SIZE))); /* 4 */
  984. } else if (op_code == '?') {
  985. /* Node structure for (x)? construct.
  986. * ___1____ _2
  987. * / |/ |
  988. * B~ (...)~ B~ N~
  989. * \__3_|
  990. */
  991. insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 1 */
  992. tail (ret_val, emit_node (BRANCH)); /* 1 */
  993. next = emit_node (NOTHING); /* 2,3 */
  994. tail (ret_val, next); /* 2 */
  995. offset_tail (ret_val, NODE_SIZE, next); /* 3 */
  996. } else if (op_code == '{' && min_max [0] == min_max [1]) {
  997. /* Node structure for (x){m}, (x){m}?, (x){m,m}, or (x){m,m}? constructs.
  998. * Note that minimal and maximal matching mean the same thing when we
  999. * specify the minimum and maximum to be the same value.
  1000. * _______3_____
  1001. * | 1_ _2 \
  1002. * | / |/ | \
  1003. * I~ (...)~ C~ T~m K~ N~
  1004. * \_| \_____|
  1005. * 5 4
  1006. */
  1007. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1008. tail (ret_val, emit_special (TEST_COUNT, min_max [0], Num_Braces));/* 2 */
  1009. tail (emit_node (BACK), ret_val); /* 3 */
  1010. tail (ret_val, emit_node (NOTHING)); /* 4 */
  1011. next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 5 */
  1012. tail (ret_val, next); /* 5 */
  1013. Num_Braces++;
  1014. } else if (op_code == '{' && lazy) {
  1015. if (min_max [0] == REG_ZERO && min_max [1] != REG_INFINITY) {
  1016. /* Node structure for (x){0,n}? or {,n}? construct.
  1017. * _________3____________
  1018. * 8_| _4__ 1_ _2 \
  1019. * / |/ | / |/ | \
  1020. * I~ B~ N~ B~ (...)~ C~ T~x K~ N~
  1021. * \ \ \__7__|
  1022. * \ \_________6_______|
  1023. * \______5____________|
  1024. */
  1025. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1026. next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2,7 */
  1027. tail (ret_val, next); /* 2 */
  1028. (void) insert (BRANCH, ret_val, 0UL, 0UL, Num_Braces); /* 4,6 */
  1029. (void) insert (NOTHING, ret_val, 0UL, 0UL, Num_Braces); /* 5 */
  1030. (void) insert (BRANCH, ret_val, 0UL, 0UL, Num_Braces); /* 3,4,8 */
  1031. tail (emit_node (BACK), ret_val); /* 3 */
  1032. tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 4 */
  1033. next = emit_node (NOTHING); /* 5,6,7 */
  1034. offset_tail (ret_val, NODE_SIZE, next); /* 5 */
  1035. offset_tail (ret_val, 2 * NODE_SIZE, next); /* 6 */
  1036. offset_tail (ret_val, 3 * NODE_SIZE, next); /* 7 */
  1037. next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 8 */
  1038. tail (ret_val, next); /* 8 */
  1039. } else if (min_max [0] > REG_ZERO && min_max [1] == REG_INFINITY) {
  1040. /* Node structure for (x){m,}? construct.
  1041. * ______8_________________
  1042. * | _______3_____ \
  1043. * | _7__ | 1_ _2 \ \
  1044. * |/ | | / |/ | \ \
  1045. * I~ B~ N~ B~ (...)~ C~ T~m K~ K~ N~
  1046. * \_____\__\_| \_4___| |
  1047. * 9 \ \_________5__________|
  1048. * \_______6______________|
  1049. */
  1050. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1051. next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2,4 */
  1052. tail (ret_val, next); /* 2 */
  1053. tail (emit_node (BACK), ret_val); /* 3 */
  1054. tail (ret_val, emit_node (BACK)); /* 4 */
  1055. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 5,7 */
  1056. (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 6 */
  1057. next = emit_node (NOTHING); /* 5,6 */
  1058. offset_tail (ret_val, NODE_SIZE, next); /* 5 */
  1059. tail (ret_val, next); /* 6 */
  1060. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 7,8 */
  1061. tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 7 */
  1062. offset_tail (ret_val, 3 * NODE_SIZE, ret_val); /* 8 */
  1063. (void) insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 9 */
  1064. tail (ret_val, ret_val + INDEX_SIZE + (4 * NODE_SIZE)); /* 9 */
  1065. } else {
  1066. /* Node structure for (x){m,n}? construct.
  1067. * ______9_____________________
  1068. * | _____________3___ \
  1069. * | __8_ | 1_ _2 \ \
  1070. * |/ | | / |/ | \ \
  1071. * I~ B~ N~ B~ (...)~ C~ T~x T~m K~ K~ N~
  1072. * \_____\__\_| \ \__4__| |
  1073. * 10 \ \ \_7_________|
  1074. * \ \_________6_____________|
  1075. * \_______5_________________|
  1076. */
  1077. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1078. next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,7 */
  1079. tail (ret_val, next); /* 2 */
  1080. next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 4 */
  1081. tail (emit_node (BACK), ret_val); /* 3 */
  1082. tail (next, emit_node (BACK)); /* 4 */
  1083. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 6,8 */
  1084. (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 5 */
  1085. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 8,9 */
  1086. next = emit_node (NOTHING); /* 5,6,7 */
  1087. offset_tail (ret_val, NODE_SIZE, next); /* 5 */
  1088. offset_tail (ret_val, 2 * NODE_SIZE, next); /* 6 */
  1089. offset_tail (ret_val, 3 * NODE_SIZE, next); /* 7 */
  1090. tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 8 */
  1091. offset_tail (next, -NODE_SIZE, ret_val); /* 9 */
  1092. insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 10 */
  1093. tail (ret_val, ret_val + INDEX_SIZE + (4 * NODE_SIZE)); /* 10 */
  1094. }
  1095. Num_Braces++;
  1096. } else if (op_code == '{') {
  1097. if (min_max [0] == REG_ZERO && min_max [1] != REG_INFINITY) {
  1098. /* Node structure for (x){0,n} or (x){,n} construct.
  1099. *
  1100. * ___3____________
  1101. * | 1_ _2 \ 5_
  1102. * | / |/ | \ / |
  1103. * I~ B~ (...)~ C~ T~x K~ B~ N~
  1104. * \_|\ \_6___|__|
  1105. * 7 \________4________|
  1106. */
  1107. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1108. next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,6 */
  1109. tail (ret_val, next); /* 2 */
  1110. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 3,4,7 */
  1111. tail (emit_node (BACK), ret_val); /* 3 */
  1112. next = emit_node (BRANCH); /* 4,5 */
  1113. tail (ret_val, next); /* 4 */
  1114. tail (next, emit_node (NOTHING)); /* 5,6 */
  1115. offset_tail (ret_val, NODE_SIZE, next); /* 6 */
  1116. next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 7 */
  1117. tail (ret_val, next); /* 7 */
  1118. } else if (min_max [0] > REG_ZERO && min_max [1] == REG_INFINITY) {
  1119. /* Node structure for (x){m,} construct.
  1120. * __________4________
  1121. * | __3__________ \
  1122. * _|___| 1_ _2 \ \ _7
  1123. * / | 8 | / |/ | \ \ / |
  1124. * I~ B~ (...)~ C~ T~m K~ K~ B~ N~
  1125. * \ \_5___| |
  1126. * \__________6__________|
  1127. */
  1128. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1129. next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2 */
  1130. tail (ret_val, next); /* 2 */
  1131. tail (emit_node (BACK), ret_val); /* 3 */
  1132. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4,6 */
  1133. next = emit_node (BACK); /* 4 */
  1134. tail (next, ret_val); /* 4 */
  1135. offset_tail (ret_val, NODE_SIZE, next); /* 5 */
  1136. tail (ret_val, emit_node (BRANCH)); /* 6 */
  1137. tail (ret_val, emit_node (NOTHING)); /* 7 */
  1138. insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 8 */
  1139. tail (ret_val, ret_val + INDEX_SIZE + (2 * NODE_SIZE)); /* 8 */
  1140. } else {
  1141. /* Node structure for (x){m,n} construct.
  1142. * _____6________________
  1143. * | _____________3___ \
  1144. * 9_|__| 1_ _2 \ \ _8
  1145. * / | | / |/ | \ \ / |
  1146. * I~ B~ (...)~ C~ T~x T~m K~ K~ B~ N~
  1147. * \ \ \__4__| | |
  1148. * \ \_7_________|__|
  1149. * \_________5_____________|
  1150. */
  1151. tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */
  1152. next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,4 */
  1153. tail (ret_val, next); /* 2 */
  1154. next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 4 */
  1155. tail (emit_node (BACK), ret_val); /* 3 */
  1156. tail (next, emit_node (BACK)); /* 4 */
  1157. (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 5,6 */
  1158. next = emit_node (BRANCH); /* 5,8 */
  1159. tail (ret_val, next); /* 5 */
  1160. offset_tail (next, -NODE_SIZE, ret_val); /* 6 */
  1161. next = emit_node (NOTHING); /* 7,8 */
  1162. offset_tail (ret_val, NODE_SIZE, next); /* 7 */
  1163. offset_tail (next, -NODE_SIZE, next); /* 8 */
  1164. (void) insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 9 */
  1165. tail (ret_val, ret_val + INDEX_SIZE + (2 * NODE_SIZE)); /* 9 */
  1166. }
  1167. Num_Braces++;
  1168. } else {
  1169. /* We get here if the IS_QUANTIFIER macro is not coordinated properly
  1170. with this function. */
  1171. REG_FAIL (U"internal error #2, `piece\'");
  1172. }
  1173. if (IS_QUANTIFIER (*Reg_Parse)) {
  1174. if (op_code == '{') {
  1175. Melder_sprint (Error_Text,128, U"nested quantifiers, {m,n}", *Reg_Parse);
  1176. } else {
  1177. Melder_sprint (Error_Text,128, U"nested quantifiers, ", op_code, *Reg_Parse);
  1178. }
  1179. REG_FAIL (Error_Text);
  1180. }
  1181. return (ret_val);
  1182. }
  1183. /*----------------------------------------------------------------------*
  1184. * atom
  1185. *
  1186. * Process one regex item at the lowest level
  1187. *
  1188. * OPTIMIZATION: Lumps a continuous sequence of ordinary characters
  1189. * together so that it can turn them into a single EXACTLY node, which
  1190. * is smaller to store and faster to run.
  1191. *----------------------------------------------------------------------*/
  1192. static char32 *atom (int *flag_param, len_range *range_param) {
  1193. char32 *ret_val;
  1194. char32 test;
  1195. int flags_local;
  1196. len_range range_local;
  1197. *flag_param = WORST; /* Tentatively. */
  1198. range_param->lower = 0; /* Idem */
  1199. range_param->upper = 0;
  1200. /* Process any regex comments, e.g. `(?# match next token->)'. The
  1201. terminating right parenthesis cannot be escaped. The comment stops at
  1202. the first right parenthesis encountered (or the end of the regex
  1203. string)... period. Handles multiple sequential comments,
  1204. e.g. `(?# one)(?# two)...' */
  1205. while (*Reg_Parse == '(' &&
  1206. * (Reg_Parse + 1) == '?' &&
  1207. * (Reg_Parse + 2) == '#') {
  1208. Reg_Parse += 3;
  1209. while (*Reg_Parse != ')' && *Reg_Parse != '\0') {
  1210. Reg_Parse++;
  1211. }
  1212. if (*Reg_Parse == ')') {
  1213. Reg_Parse++;
  1214. }
  1215. if (*Reg_Parse == ')' || *Reg_Parse == '|' || *Reg_Parse == '\0') {
  1216. /* Hit end of regex string or end of parenthesized regex; have to
  1217. return "something" (i.e. a NOTHING node) to avoid generating an
  1218. error. */
  1219. ret_val = emit_node (NOTHING);
  1220. return (ret_val);
  1221. }
  1222. }
  1223. switch (*Reg_Parse ++) {
  1224. case U'^':
  1225. ret_val = emit_node (BOL);
  1226. break;
  1227. case U'$':
  1228. ret_val = emit_node (EOL);
  1229. break;
  1230. case U'<':
  1231. ret_val = emit_node (BOWORD);
  1232. break;
  1233. case U'>':
  1234. ret_val = emit_node (EOWORD);
  1235. break;
  1236. case U'.':
  1237. if (Match_Newline) {
  1238. ret_val = emit_node (EVERY);
  1239. } else {
  1240. ret_val = emit_node (ANY);
  1241. }
  1242. *flag_param |= (HAS_WIDTH | SIMPLE);
  1243. range_param->lower = 1;
  1244. range_param->upper = 1;
  1245. break;
  1246. case U'(':
  1247. if (*Reg_Parse == U'?') { /* Special parenthetical expression */
  1248. Reg_Parse++;
  1249. range_local.lower = 0; /* Make sure it is always used */
  1250. range_local.upper = 0;
  1251. if (*Reg_Parse == U':') {
  1252. Reg_Parse ++;
  1253. ret_val = chunk (NO_CAPTURE, &flags_local, &range_local);
  1254. } else if (*Reg_Parse == U'=') {
  1255. Reg_Parse ++;
  1256. ret_val = chunk (POS_AHEAD_OPEN, &flags_local, &range_local);
  1257. } else if (*Reg_Parse == U'!') {
  1258. Reg_Parse ++;
  1259. ret_val = chunk (NEG_AHEAD_OPEN, &flags_local, &range_local);
  1260. } else if (*Reg_Parse == U'i') {
  1261. Reg_Parse ++;
  1262. ret_val = chunk (INSENSITIVE, &flags_local, &range_local);
  1263. } else if (*Reg_Parse == U'I') {
  1264. Reg_Parse ++;
  1265. ret_val = chunk (SENSITIVE, &flags_local, &range_local);
  1266. } else if (*Reg_Parse == U'n') {
  1267. Reg_Parse ++;
  1268. ret_val = chunk (NEWLINE, &flags_local, &range_local);
  1269. } else if (*Reg_Parse == U'N') {
  1270. Reg_Parse ++;
  1271. ret_val = chunk (NO_NEWLINE, &flags_local, &range_local);
  1272. } else if (*Reg_Parse == U'<') {
  1273. Reg_Parse ++;
  1274. if (*Reg_Parse == U'=') {
  1275. Reg_Parse ++;
  1276. ret_val = chunk (POS_BEHIND_OPEN, &flags_local, &range_local);
  1277. } else if (*Reg_Parse == U'!') {
  1278. Reg_Parse ++;
  1279. ret_val = chunk (NEG_BEHIND_OPEN, &flags_local, &range_local);
  1280. } else {
  1281. Melder_sprint (Error_Text,128, U"invalid look-behind syntax, \"(?<", *Reg_Parse, U"...)\"");
  1282. REG_FAIL (Error_Text)
  1283. }
  1284. } else {
  1285. Melder_sprint (Error_Text,128, U"invalid grouping syntax, \"(?", *Reg_Parse, U"...)\"");
  1286. REG_FAIL (Error_Text)
  1287. }
  1288. } else { /* Normal capturing parentheses */
  1289. ret_val = chunk (PAREN, & flags_local, & range_local);
  1290. }
  1291. if (! ret_val)
  1292. return nullptr; // something went wrong
  1293. /* Add HAS_WIDTH flag if it was set by call to chunk. */
  1294. *flag_param |= flags_local & HAS_WIDTH;
  1295. *range_param = range_local;
  1296. break;
  1297. case U'\0':
  1298. case U'|':
  1299. case U')':
  1300. REG_FAIL (U"internal error #3, `atom\'") // supposed to be caught earlier
  1301. case U'?':
  1302. case U'+':
  1303. case U'*':
  1304. Melder_sprint (Error_Text,128, * (Reg_Parse - 1), U" follows nothing");
  1305. REG_FAIL (Error_Text)
  1306. case U'{':
  1307. if (Enable_Counting_Quantifier) {
  1308. REG_FAIL (U"{m,n} follows nothing")
  1309. } else {
  1310. ret_val = emit_node (EXACTLY); /* Treat braces as literals. */
  1311. emit_byte (U'{');
  1312. emit_byte (U'\0');
  1313. range_param->lower = 1;
  1314. range_param->upper = 1;
  1315. }
  1316. break;
  1317. case U'[': {
  1318. char32 last_emit = U'\0';
  1319. /* Handle characters that can only occur at the start of a class. */
  1320. if (*Reg_Parse == U'^') { /* Complement of range. */
  1321. ret_val = emit_node (ANY_BUT);
  1322. Reg_Parse ++;
  1323. /* All negated classes include newline unless escaped with
  1324. a "(?n)" switch. */
  1325. if (!Match_Newline) {
  1326. emit_byte (U'\n');
  1327. }
  1328. } else {
  1329. ret_val = emit_node (ANY_OF);
  1330. }
  1331. if (*Reg_Parse == U']' || *Reg_Parse == U'-') {
  1332. /* If '-' or ']' is the first character in a class,
  1333. it is a literal character in the class. */
  1334. last_emit = *Reg_Parse;
  1335. emit_byte (*Reg_Parse);
  1336. Reg_Parse ++;
  1337. }
  1338. /* Handle the rest of the class characters. */
  1339. while (*Reg_Parse != U'\0' && *Reg_Parse != U']') {
  1340. if (*Reg_Parse == U'-') { /* Process a range, e.g [a-z]. */
  1341. Reg_Parse ++;
  1342. if (*Reg_Parse == U']' || *Reg_Parse == U'\0') {
  1343. /* If '-' is the last character in a class it is a literal
  1344. character. If `Reg_Parse' points to the end of the
  1345. regex string, an error will be generated later. */
  1346. emit_byte (U'-');
  1347. last_emit = U'-';
  1348. } else {
  1349. /* We must get the range starting character value from the
  1350. emitted code since it may have been an escaped
  1351. character. `second_value' is set one larger than the
  1352. just emitted character value. This is done since
  1353. `second_value' is used as the start value for the loop
  1354. that emits the values in the range. Since we have
  1355. already emitted the first character of the class, we do
  1356. not want to emit it again. */
  1357. char32 second_value = last_emit + 1, last_value;
  1358. if (*Reg_Parse == U'\\') {
  1359. /* Handle escaped characters within a class range.
  1360. Specifically disallow shortcut escapes as the end of
  1361. a class range. To allow this would be ambiguous
  1362. since shortcut escapes represent a set of characters,
  1363. and it would not be clear which character of the
  1364. class should be treated as the "last" character. */
  1365. Reg_Parse++;
  1366. if ((test = numeric_escape (*Reg_Parse, &Reg_Parse)) != U'\0') {
  1367. last_value = test;
  1368. } else if ((test = literal_escape (*Reg_Parse)) != U'\0') {
  1369. last_value = test;
  1370. } else if (shortcut_escape (*Reg_Parse, NULL, CHECK_CLASS_ESCAPE)) {
  1371. Melder_sprint (Error_Text, 128, U"\\", *Reg_Parse, U" is not allowed as range operand");
  1372. REG_FAIL (Error_Text)
  1373. } else {
  1374. Melder_sprint (Error_Text, 128, U"\\", *Reg_Parse, U" is an invalid char class escape sequence");
  1375. REG_FAIL (Error_Text)
  1376. }
  1377. } else {
  1378. last_value = U_CHAR_AT (Reg_Parse);
  1379. }
  1380. if (Is_Case_Insensitive) {
  1381. second_value = Melder_toLowerCase (second_value); // TODO: this should do casefolding
  1382. last_value = Melder_toLowerCase (last_value);
  1383. }
  1384. /* For case insensitive, something like [A-_] will
  1385. generate an error here since ranges are converted to
  1386. lower case. */
  1387. if (second_value - 1 > last_value)
  1388. REG_FAIL (U"invalid [] range")
  1389. /* If only one character in range (e.g [a-a]) then this
  1390. loop is not run since the first character of any range
  1391. was emitted by the previous iteration of while loop. */
  1392. for (; second_value <= last_value; second_value++)
  1393. emit_class_byte (second_value);
  1394. last_emit = (char32) last_value;
  1395. Reg_Parse ++;
  1396. } /* End class character range code. */
  1397. } else if (*Reg_Parse == '\\') {
  1398. Reg_Parse++;
  1399. if ( (test = numeric_escape (*Reg_Parse, &Reg_Parse)) != '\0') {
  1400. emit_class_byte (test);
  1401. last_emit = test;
  1402. } else if ( (test = literal_escape (*Reg_Parse)) != '\0') {
  1403. emit_byte (test);
  1404. last_emit = test;
  1405. } else if (shortcut_escape (*Reg_Parse,
  1406. NULL,
  1407. CHECK_CLASS_ESCAPE)) {
  1408. if (* (Reg_Parse + 1) == '-') {
  1409. /* Specifically disallow shortcut escapes as the start
  1410. of a character class range (see comment above.) */
  1411. Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" not allowed as range operand");
  1412. REG_FAIL (Error_Text);
  1413. } else {
  1414. /* Emit the bytes that are part of the shortcut
  1415. escape sequence's range (e.g. \d = 0123456789) */
  1416. Melder_sprint (Error_Text,128, U"Cannot have escape sequences such as \\", *Reg_Parse, U" inside a class");
  1417. }
  1418. } else {
  1419. Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" is an invalid char class escape sequence");
  1420. REG_FAIL (Error_Text);
  1421. }
  1422. Reg_Parse++;
  1423. /* End of class escaped sequence code */
  1424. } else {
  1425. emit_class_byte (*Reg_Parse); /* Ordinary class character. */
  1426. last_emit = *Reg_Parse;
  1427. Reg_Parse++;
  1428. }
  1429. } /* End of while (*Reg_Parse != U'\0' && *Reg_Parse != U']') */
  1430. if (*Reg_Parse != U']') {
  1431. REG_FAIL (U"missing right \']\'");
  1432. }
  1433. emit_byte (U'\0');
  1434. /* NOTE: it is impossible to specify an empty class. This is
  1435. because [] would be interpreted as "begin character class"
  1436. followed by a literal ']' character and no "end character class"
  1437. delimiter (']'). Because of this, it is always safe to assume
  1438. that a class HAS_WIDTH. */
  1439. Reg_Parse ++;
  1440. *flag_param |= HAS_WIDTH | SIMPLE;
  1441. range_param->lower = 1;
  1442. range_param->upper = 1;
  1443. }
  1444. break; /* End of character class code. */
  1445. case U'\\':
  1446. /* Force Error_Text to have a length of zero. This way we can tell if
  1447. either of the calls to shortcut_escape() or back_ref() fill
  1448. Error_Text with an error message. */
  1449. Error_Text [0] = U'\0';
  1450. if ( (ret_val = shortcut_escape (*Reg_Parse, flag_param, EMIT_NODE))) {
  1451. Reg_Parse ++;
  1452. range_param->lower = 1;
  1453. range_param->upper = 1;
  1454. break;
  1455. } else if ( (ret_val = back_ref (Reg_Parse, flag_param, EMIT_NODE))) {
  1456. /* Can't make any assumptions about a back-reference as to SIMPLE
  1457. or HAS_WIDTH. For example (^|<) is neither simple nor has
  1458. width. So we don't flip bits in flag_param here. */
  1459. Reg_Parse++;
  1460. /* Back-references always have an unknown length */
  1461. range_param->lower = -1;
  1462. range_param->upper = -1;
  1463. break;
  1464. }
  1465. if (Error_Text [0] != U'\0')
  1466. REG_FAIL (Error_Text)
  1467. /* At this point it is apparent that the escaped character is not a
  1468. shortcut escape or back-reference. Back up one character to allow
  1469. the default code to include it as an ordinary character. */
  1470. /* Fall through to Default case to handle literal escapes and numeric
  1471. escapes. */
  1472. default:
  1473. Reg_Parse --; /* If we fell through from the above code, we are now
  1474. pointing at the back slash (\) character. */
  1475. {
  1476. char32 *parse_save;
  1477. int len = 0;
  1478. if (Is_Case_Insensitive) {
  1479. ret_val = emit_node (SIMILAR);
  1480. } else {
  1481. ret_val = emit_node (EXACTLY);
  1482. }
  1483. /* Loop until we find a meta character, shortcut escape, back
  1484. reference, or end of regex string. */
  1485. for (; *Reg_Parse != '\0' && ! str32chr (Meta_Char, *Reg_Parse); len++) {
  1486. /* Save where we are in case we have to back
  1487. this character out. */
  1488. parse_save = Reg_Parse;
  1489. if (*Reg_Parse == U'\\') {
  1490. Reg_Parse ++; // point to escaped character
  1491. Error_Text [0] = U'\0'; // see comment above
  1492. if ( (test = numeric_escape (*Reg_Parse, &Reg_Parse))) {
  1493. if (Is_Case_Insensitive) {
  1494. emit_byte (Melder_toLowerCase (test));
  1495. } else {
  1496. emit_byte (test);
  1497. }
  1498. } else if ( (test = literal_escape (*Reg_Parse))) {
  1499. emit_byte (test);
  1500. } else if (back_ref (Reg_Parse, NULL, CHECK_ESCAPE)) {
  1501. /* Leave back reference for next `atom' call */
  1502. Reg_Parse --; break;
  1503. } else if (shortcut_escape (*Reg_Parse, NULL, CHECK_ESCAPE)) {
  1504. /* Leave shortcut escape for next `atom' call */
  1505. Reg_Parse --; break;
  1506. } else {
  1507. if (Error_Text [0] != U'\0') {
  1508. /* None of the above calls generated an error message
  1509. so generate our own here. */
  1510. Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" is an invalid escape sequence");
  1511. }
  1512. REG_FAIL (Error_Text)
  1513. }
  1514. Reg_Parse ++;
  1515. } else {
  1516. /* Ordinary character */
  1517. if (Is_Case_Insensitive) {
  1518. emit_byte (Melder_toLowerCase (*Reg_Parse));
  1519. } else {
  1520. emit_byte (*Reg_Parse);
  1521. }
  1522. Reg_Parse ++;
  1523. }
  1524. /* If next regex token is a quantifier (?, +. *, or {m,n}) and
  1525. our EXACTLY node so far is more than one character, leave the
  1526. last character to be made into an EXACTLY node one character
  1527. wide for the multiplier to act on. For example 'abcd* would
  1528. have an EXACTLY node with an 'abc' operand followed by a STAR
  1529. node followed by another EXACTLY node with a 'd' operand. */
  1530. if (IS_QUANTIFIER (*Reg_Parse) && len > 0) {
  1531. Reg_Parse = parse_save; /* Point to previous regex token. */
  1532. if (Code_Emit_Ptr == &Compute_Size) {
  1533. Reg_Size--;
  1534. } else {
  1535. Code_Emit_Ptr--; /* Write over previously emitted byte. */
  1536. }
  1537. break;
  1538. }
  1539. }
  1540. if (len <= 0)
  1541. REG_FAIL (U"internal error #4, `atom\'")
  1542. *flag_param |= HAS_WIDTH;
  1543. if (len == 1)
  1544. *flag_param |= SIMPLE;
  1545. range_param->lower = len;
  1546. range_param->upper = len;
  1547. emit_byte (U'\0');
  1548. }
  1549. } /* END switch (*Reg_Parse++) */
  1550. return (ret_val);
  1551. }
  1552. /*----------------------------------------------------------------------*
  1553. * emit_node
  1554. *
  1555. * Emit (if appropriate) the op code for a regex node atom.
  1556. *
  1557. * The NEXT pointer is initialized to NULL.
  1558. *
  1559. * Returns a pointer to the START of the emitted node.
  1560. *----------------------------------------------------------------------*/
  1561. static char32 *emit_node (int op_code) {
  1562. char32 *ret_val = Code_Emit_Ptr; /* Return address of start of node */
  1563. if (ret_val == & Compute_Size) {
  1564. Reg_Size += NODE_SIZE;
  1565. } else {
  1566. char32 *ptr = ret_val;
  1567. *ptr ++ = op_code;
  1568. *ptr ++ = U'\0'; // null "NEXT" pointer
  1569. *ptr ++ = U'\0';
  1570. Code_Emit_Ptr = ptr;
  1571. }
  1572. return ret_val;
  1573. }
  1574. /*----------------------------------------------------------------------*
  1575. * emit_byte
  1576. *
  1577. * Emit (if appropriate) a byte of code (usually part of an operand.)
  1578. *----------------------------------------------------------------------*/
  1579. static void emit_byte (char32 c) {
  1580. if (Code_Emit_Ptr == & Compute_Size) {
  1581. Reg_Size ++;
  1582. } else {
  1583. *Code_Emit_Ptr ++ = c;
  1584. }
  1585. }
  1586. /*----------------------------------------------------------------------*
  1587. * emit_class_byte
  1588. *
  1589. * Emit (if appropriate) a byte of code (usually part of a character
  1590. * class operand.)
  1591. *----------------------------------------------------------------------*/
  1592. static void emit_class_byte (char32 c) {
  1593. if (Code_Emit_Ptr == & Compute_Size) {
  1594. Reg_Size ++;
  1595. if (Is_Case_Insensitive && Melder_isLetter (c)) {
  1596. Reg_Size ++;
  1597. }
  1598. } else if (Is_Case_Insensitive && Melder_isLetter (c)) {
  1599. /* For case-insensitive character classes, emit both upper and lower case
  1600. versions of alphabetical characters. */
  1601. *Code_Emit_Ptr ++ = Melder_toLowerCase (c);
  1602. *Code_Emit_Ptr ++ = Melder_toUpperCase (c);
  1603. } else {
  1604. *Code_Emit_Ptr ++ = c;
  1605. }
  1606. }
  1607. /*----------------------------------------------------------------------*
  1608. * emit_special
  1609. *
  1610. * Emit nodes that need special processing.
  1611. *----------------------------------------------------------------------*/
  1612. static char32 *emit_special (
  1613. char32 op_code,
  1614. unsigned long test_val,
  1615. int index)
  1616. {
  1617. char32 *ret_val = & Compute_Size;
  1618. char32 *ptr;
  1619. if (Code_Emit_Ptr == & Compute_Size) {
  1620. switch (op_code) {
  1621. case POS_BEHIND_OPEN:
  1622. case NEG_BEHIND_OPEN:
  1623. Reg_Size += LENGTH_SIZE; /* Length of the look-behind match */
  1624. Reg_Size += NODE_SIZE; /* Make room for the node */
  1625. break;
  1626. case TEST_COUNT:
  1627. Reg_Size += NEXT_PTR_SIZE; /* Make room for a test value. */
  1628. // ppgb FALLTHROUGH (both test and inc require index)
  1629. case INC_COUNT:
  1630. Reg_Size += INDEX_SIZE; /* Make room for an index value. */
  1631. // ppgb FALLTHROUGH (everything requires node)
  1632. default:
  1633. Reg_Size += NODE_SIZE; /* Make room for the node. */
  1634. }
  1635. } else {
  1636. ret_val = emit_node (op_code); /* Return the address for start of node. */
  1637. ptr = Code_Emit_Ptr;
  1638. if (op_code == INC_COUNT || op_code == TEST_COUNT) {
  1639. *ptr ++ = (char32) index;
  1640. if (op_code == TEST_COUNT) {
  1641. *ptr ++ = PUT_OFFSET_L (test_val);
  1642. *ptr ++ = PUT_OFFSET_R (test_val);
  1643. }
  1644. } else if (op_code == POS_BEHIND_OPEN || op_code == NEG_BEHIND_OPEN) {
  1645. *ptr ++ = PUT_OFFSET_L (test_val);
  1646. *ptr ++ = PUT_OFFSET_R (test_val);
  1647. *ptr ++ = PUT_OFFSET_L (test_val);
  1648. *ptr ++ = PUT_OFFSET_R (test_val);
  1649. }
  1650. Code_Emit_Ptr = ptr;
  1651. }
  1652. return ret_val;
  1653. }
  1654. /*----------------------------------------------------------------------*
  1655. * insert
  1656. *
  1657. * Insert a node in front of already emitted node(s). Means relocating
  1658. * the operand. Code_Emit_Ptr points one byte past the just emitted
  1659. * node and operand. The parameter `insert_pos' points to the location
  1660. * where the new node is to be inserted.
  1661. *----------------------------------------------------------------------*/
  1662. static char32 *insert (
  1663. char32 op,
  1664. char32 *insert_pos,
  1665. long min,
  1666. long max,
  1667. int index) {
  1668. char32 *src;
  1669. char32 *dst;
  1670. char32 *place;
  1671. int insert_size = NODE_SIZE;
  1672. if (op == BRACE || op == LAZY_BRACE) {
  1673. /* Make room for the min and max values. */
  1674. insert_size += (2 * NEXT_PTR_SIZE);
  1675. } else if (op == INIT_COUNT) {
  1676. /* Make room for an index value . */
  1677. insert_size += INDEX_SIZE;
  1678. }
  1679. if (Code_Emit_Ptr == &Compute_Size) {
  1680. Reg_Size += insert_size;
  1681. return &Compute_Size;
  1682. }
  1683. src = Code_Emit_Ptr;
  1684. Code_Emit_Ptr += insert_size;
  1685. dst = Code_Emit_Ptr;
  1686. /* Relocate the existing emitted code to make room for the new node. */
  1687. while (src > insert_pos) {
  1688. *--dst = *--src;
  1689. }
  1690. place = insert_pos; /* Where operand used to be. */
  1691. *place++ = op; /* Inserted operand. */
  1692. *place++ = '\0'; /* NEXT pointer for inserted operand. */
  1693. *place++ = '\0';
  1694. if (op == BRACE || op == LAZY_BRACE) {
  1695. *place++ = PUT_OFFSET_L (min);
  1696. *place++ = PUT_OFFSET_R (min);
  1697. *place++ = PUT_OFFSET_L (max);
  1698. *place++ = PUT_OFFSET_R (max);
  1699. } else if (op == INIT_COUNT) {
  1700. *place++ = (char32) index;
  1701. }
  1702. return place; /* Return a pointer to the start of the code moved. */
  1703. }
  1704. /*----------------------------------------------------------------------*
  1705. * tail - Set the next-pointer at the end of a node chain.
  1706. *----------------------------------------------------------------------*/
  1707. static void tail (char32 *search_from, char32 *point_to) {
  1708. char32 *scan;
  1709. char32 *next;
  1710. int offset;
  1711. if (search_from == &Compute_Size) {
  1712. return;
  1713. }
  1714. /* Find the last node in the chain (node with a null NEXT pointer) */
  1715. scan = search_from;
  1716. for (;;) {
  1717. next = next_ptr (scan);
  1718. if (!next) {
  1719. break;
  1720. }
  1721. scan = next;
  1722. }
  1723. if (GET_OP_CODE (scan) == BACK) {
  1724. offset = scan - point_to;
  1725. } else {
  1726. offset = point_to - scan;
  1727. }
  1728. /* Set NEXT pointer */
  1729. * (scan + 1) = PUT_OFFSET_L (offset);
  1730. * (scan + 2) = PUT_OFFSET_R (offset);
  1731. }
  1732. /*--------------------------------------------------------------------*
  1733. * offset_tail
  1734. *
  1735. * Perform a tail operation on (ptr + offset).
  1736. *--------------------------------------------------------------------*/
  1737. static void offset_tail (char32 *ptr, int offset, char32 *val) {
  1738. if (ptr == & Compute_Size || ! ptr)
  1739. return;
  1740. tail (ptr + offset, val);
  1741. }
  1742. /*--------------------------------------------------------------------*
  1743. * branch_tail
  1744. *
  1745. * Perform a tail operation on (ptr + offset) but only if `ptr' is a
  1746. * BRANCH node.
  1747. *--------------------------------------------------------------------*/
  1748. static void branch_tail (char32 *ptr, int offset, char32 *val) {
  1749. if (ptr == & Compute_Size || ! ptr || GET_OP_CODE (ptr) != BRANCH)
  1750. return;
  1751. tail (ptr + offset, val);
  1752. }
  1753. /*--------------------------------------------------------------------*
  1754. * shortcut_escape
  1755. *
  1756. * Implements convenient escape sequences that represent entire
  1757. * character classes or special location assertions (similar to escapes
  1758. * supported by Perl)
  1759. * _
  1760. * \d Digits [0-9] |
  1761. * \D NOT a digit [^0-9] | (Examples
  1762. * \l Letters [a-zA-Z] | at left
  1763. * \L NOT a Letter [^a-zA-Z] | are
  1764. * \s Whitespace [ \t\n\r\f\v] | for
  1765. * \S NOT Whitespace [^ \t\n\r\f\v] | ASCII)
  1766. * \w "Word" character [a-zA-Z0-9_] |
  1767. * \W NOT a "Word" character [^a-zA-Z0-9_] _|
  1768. *
  1769. * \B Matches any character that is NOT a word-delimiter
  1770. *
  1771. * Codes for the "emit" parameter:
  1772. *
  1773. * EMIT_NODE
  1774. * Emit a shortcut node. Shortcut nodes have an implied set of
  1775. * class characters. This helps keep the compiled regex string
  1776. * small.
  1777. *
  1778. * CHECK_ESCAPE
  1779. * Only verify that this is a valid shortcut escape.
  1780. *
  1781. * CHECK_CLASS_ESCAPE
  1782. * Same as CHECK_ESCAPE but only allows characters valid within
  1783. * a klas.
  1784. *
  1785. *--------------------------------------------------------------------*/
  1786. static char32 *shortcut_escape (
  1787. char32 c,
  1788. int *flag_param,
  1789. int emit) {
  1790. char32 *klas = NULL;
  1791. static const conststring32 codes = U"ByYwWdDlLsS";
  1792. char32 *ret_val = (char32 *) 1; // assume success
  1793. conststring32 valid_codes;
  1794. if (emit == CHECK_CLASS_ESCAPE) {
  1795. valid_codes = codes + 5; /* \B, \y, \Y, \w and \W are not allowed in classes */
  1796. } else {
  1797. valid_codes = codes;
  1798. }
  1799. if (! str32chr (valid_codes, c)) {
  1800. return nullptr; // not a valid shortcut escape sequence
  1801. } else if (emit == CHECK_ESCAPE || emit == CHECK_CLASS_ESCAPE) {
  1802. return ret_val; // just checking if this is a valid shortcut escape
  1803. }
  1804. switch (c) {
  1805. case U'd':
  1806. case U'D':
  1807. if (emit == EMIT_NODE)
  1808. ret_val = (iswlower ((int) c) ? emit_node (DIGIT) : emit_node (NOT_DIGIT));
  1809. break;
  1810. case U'l':
  1811. case U'L':
  1812. if (emit == EMIT_NODE)
  1813. ret_val = (iswlower ((int) c) ? emit_node (LETTER) : emit_node (NOT_LETTER));
  1814. break;
  1815. case U's':
  1816. case U'S':
  1817. if (emit == EMIT_NODE) {
  1818. if (Match_Newline) {
  1819. ret_val = (iswlower ((int) c) ? emit_node (SPACE_NL) : emit_node (NOT_SPACE_NL));
  1820. } else {
  1821. ret_val = (iswlower ((int) c) ? emit_node (SPACE) : emit_node (NOT_SPACE));
  1822. }
  1823. }
  1824. break;
  1825. case U'w':
  1826. case U'W':
  1827. if (emit == EMIT_NODE) {
  1828. ret_val = (iswlower ((int) c) ? emit_node (WORD_CHAR) : emit_node (NOT_WORD_CHAR));
  1829. } else {
  1830. REG_FAIL (U"internal error #105 `shortcut_escape\'");
  1831. }
  1832. break;
  1833. /*
  1834. Since the delimiter table is not available at regex compile time,
  1835. \B, \y and \Y can only generate a node. At run time, the delimiter table
  1836. will be available for these nodes to use.
  1837. */
  1838. case 'y':
  1839. if (emit == EMIT_NODE) {
  1840. ret_val = emit_node (IS_DELIM);
  1841. } else {
  1842. REG_FAIL (U"internal error #5 `shortcut_escape\'");
  1843. }
  1844. break;
  1845. case 'Y':
  1846. if (emit == EMIT_NODE) {
  1847. ret_val = emit_node (NOT_DELIM);
  1848. } else {
  1849. REG_FAIL (U"internal error #6 `shortcut_escape\'");
  1850. }
  1851. break;
  1852. case 'B':
  1853. if (emit == EMIT_NODE) {
  1854. ret_val = emit_node (NOT_BOUNDARY);
  1855. } else {
  1856. REG_FAIL (U"internal error #7 `shortcut_escape\'");
  1857. }
  1858. break;
  1859. default:
  1860. /*
  1861. We get here if there isn't a case for every character in the string "codes".
  1862. */
  1863. REG_FAIL (U"internal error #8 `shortcut_escape\'");
  1864. }
  1865. if (emit == EMIT_NODE && c != 'B') {
  1866. *flag_param |= (HAS_WIDTH | SIMPLE);
  1867. }
  1868. if (klas) {
  1869. /*
  1870. Emit bytes within a character class operand.
  1871. */
  1872. while (*klas != U'\0')
  1873. emit_byte (*klas ++);
  1874. }
  1875. return ret_val;
  1876. }
  1877. /*--------------------------------------------------------------------*
  1878. * numeric_escape
  1879. *
  1880. * Implements hex and octal numeric escape sequence syntax.
  1881. *
  1882. * Hexadecimal Escape: \x## Max of two digits Must have leading 'x'.
  1883. * Octal Escape: \0### Max of three digits and not greater
  1884. * than 377 octal. Must have leading zero.
  1885. *
  1886. * Returns the actual character value or NULL if not a valid hex or
  1887. * octal escape. REG_FAIL is called if \x0, \x00, \0, \00, \000, or
  1888. * \0000 is specified.
  1889. *--------------------------------------------------------------------*/
  1890. static char32 numeric_escape (
  1891. char32 c,
  1892. char32 **parse) {
  1893. static char32 digits [] = { 'f', 'e', 'd', 'c', 'b', 'a', 'F', 'E', 'D', 'C', 'B', 'A', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '\0' };
  1894. static unsigned int digit_val [] = {
  1895. 15, 14, 13, 12, 11, 10, /* Lower case Hex digits */
  1896. 15, 14, 13, 12, 11, 10, /* Upper case Hex digits */
  1897. 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
  1898. }; /* Decimal Digits */
  1899. char32 *scan;
  1900. char32 *pos_ptr;
  1901. char32 *digit_str;
  1902. unsigned int value = 0;
  1903. unsigned int radix = 8;
  1904. int width = 3; /* Can not be bigger than \0377 */
  1905. int pos_delta = 14;
  1906. int i, pos;
  1907. switch (c) {
  1908. case U'0':
  1909. digit_str = digits + pos_delta; /* Only use Octal digits, i.e. 0-7. */
  1910. break;
  1911. case U'x':
  1912. case U'X':
  1913. width = 2; /* Can not be bigger than \0377 */
  1914. radix = 16;
  1915. pos_delta = 0;
  1916. digit_str = digits; /* Use all of the digit characters. */
  1917. break;
  1918. default:
  1919. return U'\0'; /* Not a numeric escape */
  1920. }
  1921. scan = *parse; scan ++; /* Only change *parse on success. */
  1922. pos_ptr = str32chr (digit_str, *scan);
  1923. for (i = 0; pos_ptr && i < width; i++) {
  1924. pos = (pos_ptr - digit_str) + pos_delta;
  1925. value = (value * radix) + digit_val [pos];
  1926. /* If this digit makes the value over 255, treat this digit as a literal
  1927. character instead of part of the numeric escape. For example, \0777
  1928. will be processed as \077 (an 'M') and a literal '7' character, NOT
  1929. 511 decimal which is > 255. */
  1930. if (value > 255) {
  1931. /* Back out calculations for last digit processed. */
  1932. value -= digit_val [pos];
  1933. value /= radix;
  1934. break; /* Note that scan will not be incremented and still points to
  1935. the digit that caused overflow. It will be decremented by
  1936. the "else" below to point to the last character that is
  1937. considered to be part of the octal escape. */
  1938. }
  1939. scan ++;
  1940. pos_ptr = str32chr (digit_str, *scan);
  1941. }
  1942. /* Handle the case of "\0" i.e. trying to specify a NULL character. */
  1943. if (value == 0) {
  1944. if (c == U'0') {
  1945. Melder_sprint (Error_Text,128, U"\\00 is an invalid octal escape");
  1946. } else {
  1947. Melder_sprint (Error_Text,128, U"\\", c, U"0 is an invalid hexadecimal escape");
  1948. }
  1949. } else {
  1950. /* Point to the last character of the number on success. */
  1951. scan --;
  1952. *parse = scan;
  1953. }
  1954. return value;
  1955. }
  1956. /*--------------------------------------------------------------------*
  1957. * literal_escape
  1958. *
  1959. * Recognize escaped literal characters (prefixed with backslash),
  1960. * and translate them into the corresponding character.
  1961. *
  1962. * Returns the proper character value or NULL if not a valid literal
  1963. * escape.
  1964. *--------------------------------------------------------------------*/
  1965. static char32 literal_escape (char32 c) {
  1966. static char32 valid_escape [] = {
  1967. 'a', 'b',
  1968. 'e',
  1969. 'f', 'n', 'r', 't', 'v', '(', ')', '-', '[', ']',
  1970. '<', '>', '{', '}', '.', '\\', '|', '^', '$', '*',
  1971. '+', '?', '&', '\0'
  1972. };
  1973. static char32 value [] = {
  1974. '\a', '\b',
  1975. 0x1B, /* Escape character in Unicode character set. */
  1976. '\f', '\n', '\r', '\t', '\v', '(', ')', '-', '[', ']',
  1977. '<', '>', '{', '}', '.', '\\', '|', '^', '$', '*',
  1978. '+', '?', '&', '\0'
  1979. };
  1980. for (int i = 0; valid_escape [i] != '\0'; i++) {
  1981. if (c == valid_escape [i]) {
  1982. return value [i];
  1983. }
  1984. }
  1985. return '\0';
  1986. }
  1987. /*--------------------------------------------------------------------*
  1988. * back_ref
  1989. *
  1990. * Process a request to match a previous parenthesized thing.
  1991. * Parenthetical entities are numbered beginning at 1 by counting
  1992. * opening parentheses from left to to right. \0 would represent
  1993. * whole match, but would confuse numeric_escape as an octal escape,
  1994. * so it is forbidden.
  1995. *
  1996. * Constructs of the form \~1, \~2, etc. are cross-regex back
  1997. * references and are used in syntax highlighting patterns to match
  1998. * text previously matched by another regex. *** IMPLEMENT LATER ***
  1999. *--------------------------------------------------------------------*/
  2000. static char32 *back_ref (
  2001. char32 *c,
  2002. int *flag_param,
  2003. int emit) {
  2004. int paren_no, c_offset = 0, is_cross_regex = 0;
  2005. char32 *ret_val;
  2006. /* Implement cross regex backreferences later. */
  2007. /* if (*c == (regularExp_CHAR) ('~')) {
  2008. c_offset++;
  2009. is_cross_regex++;
  2010. } */
  2011. paren_no = (int) (* (c + c_offset) - (char32) ('0'));
  2012. if (! Melder_isAsciiDecimalNumber (* (c + c_offset)) || /* Only \1, \2, ... \9 are supported. */
  2013. paren_no == 0) { /* Should be caught by numeric_escape. */
  2014. return NULL;
  2015. }
  2016. /* Make sure parentheses for requested back-reference are complete. */
  2017. if (! is_cross_regex && ! TEST_BIT (Closed_Parens, paren_no)) {
  2018. Melder_sprint (Error_Text,128, U"\\", paren_no, U" is an illegal back reference");
  2019. return NULL;
  2020. }
  2021. if (emit == EMIT_NODE) {
  2022. if (is_cross_regex) {
  2023. Reg_Parse ++; /* Skip past the '~' in a cross regex back reference.
  2024. We only do this if we are emitting code. */
  2025. if (Is_Case_Insensitive) {
  2026. ret_val = emit_node (X_REGEX_BR_CI);
  2027. } else {
  2028. ret_val = emit_node (X_REGEX_BR);
  2029. }
  2030. } else {
  2031. if (Is_Case_Insensitive) {
  2032. ret_val = emit_node (BACK_REF_CI);
  2033. } else {
  2034. ret_val = emit_node (BACK_REF);
  2035. }
  2036. }
  2037. emit_byte ((char32) paren_no);
  2038. if (is_cross_regex || TEST_BIT (Paren_Has_Width, paren_no)) {
  2039. *flag_param |= HAS_WIDTH;
  2040. }
  2041. } else if (emit == CHECK_ESCAPE) {
  2042. ret_val = (char32 *) 1;
  2043. } else {
  2044. ret_val = nullptr;
  2045. }
  2046. return ret_val;
  2047. }
  2048. /*======================================================================*
  2049. * Regex execution related code
  2050. *======================================================================*/
  2051. /* Global work variables for `ExecRE'. */
  2052. static char32 *Reg_Input; /* String-input pointer. */
  2053. static const char32 *Start_Of_String; /* Beginning of input, for ^ */
  2054. /* and < checks. */
  2055. static const char32 *End_Of_String; /* Logical end of input (if supplied, till \0 otherwise) */
  2056. static const char32 *Look_Behind_To; /* Position till were look behind can safely check back */
  2057. static char32 **Start_Ptr_Ptr; /* Pointer to `startp' array. */
  2058. static char32 **End_Ptr_Ptr; /* Ditto for `endp'. */
  2059. static char32 *Extent_Ptr_FW; /* Forward extent pointer */
  2060. static char32 *Extent_Ptr_BW; /* Backward extent pointer */
  2061. static char32 *Back_Ref_Start [10]; /* Back_Ref_Start [0] and */
  2062. static char32 *Back_Ref_End [10]; /* Back_Ref_End [0] are not */
  2063. /* used. This simplifies */
  2064. /* indexing. */
  2065. /*
  2066. * Measured recursion limits:
  2067. * Linux: +/- 40 000 (up to 110 000)
  2068. * Solaris: +/- 85 000
  2069. * HP-UX 11: +/- 325 000
  2070. *
  2071. * So 10 000 ought to be safe.
  2072. */
  2073. #define REGEX_RECURSION_LIMIT 10000
  2074. static int Recursion_Count; /* Recursion counter */
  2075. static int Recursion_Limit_Exceeded; /* Recursion limit exceeded flag */
  2076. #define AT_END_OF_STRING(X) (*(X) == U'\0' || (End_Of_String != NULL && (X) >= End_Of_String))
  2077. /* static regexp *Cross_Regex_Backref; */
  2078. static bool Prev_Is_BOL;
  2079. static bool Succ_Is_EOL;
  2080. static bool Prev_Is_Delim;
  2081. static bool Succ_Is_Delim;
  2082. /* Define a pointer to an array to hold general (...){m,n} counts. */
  2083. typedef struct brace_counts {
  2084. unsigned long count [1]; /* More unwarranted chumminess with compiler. */
  2085. } brace_counts;
  2086. static struct brace_counts *Brace;
  2087. /* Forward declarations of functions used by `ExecRE' */
  2088. static int attempt (regexp *, char32 *);
  2089. static int match (char32 *, int *);
  2090. static unsigned long greedy (char32 *, long);
  2091. static void adjustcase (char32 *, int, char32);
  2092. /*
  2093. * ExecRE - match a `regexp' structure against a string
  2094. *
  2095. * If `end' is non-NULL, matches may not BEGIN past end, but may extend past
  2096. * it. If reverse is true, `end' should be specified, and searching begins at
  2097. * `end'. "isbol" should be set to true if the beginning of the string is the
  2098. * actual beginning of a line (since `ExecRE' can't look backwards from the
  2099. * beginning to find whether there was a newline before). Likewise, "isbow"
  2100. * asks whether the string is preceded by a word delimiter. End of string is
  2101. * always treated as a word and line boundary (there may be cases where it
  2102. * shouldn't be, in which case, this should be changed).
  2103. * Look_behind_to indicates the position till where it is safe to
  2104. * perform look-behind matches. If set, it should be smaller than or equal
  2105. * to the start position of the search (pointed at by string). If it is NULL,
  2106. * it defaults to the start position.
  2107. * Finally, match_to indicates the logical end of the string, till where
  2108. * matches are allowed to extend. Note that look-ahead patterns may look
  2109. * past that boundary. If match_to is set to NULL, the terminating \0 is
  2110. * assumed to correspond to the logical boundary. Match_to, if set, should be
  2111. * larger than or equal to end, if set.
  2112. */
  2113. int ExecRE (
  2114. regexp *prog,
  2115. regexp *cross_regex_backref,
  2116. conststring32 string,
  2117. const char32 *end,
  2118. int reverse,
  2119. char32 prev_char,
  2120. char32 succ_char,
  2121. conststring32 look_behind_to,
  2122. conststring32 match_to) {
  2123. char32 *str;
  2124. char32 **s_ptr;
  2125. char32 **e_ptr;
  2126. int ret_val = 0;
  2127. int i;
  2128. (void) cross_regex_backref;
  2129. s_ptr = (char32 **) prog->startp;
  2130. e_ptr = (char32 **) prog->endp;
  2131. /* Check for valid parameters. */
  2132. if (! prog || ! string) {
  2133. reg_error (U"NULL parameter to `ExecRE\'");
  2134. goto SINGLE_RETURN;
  2135. }
  2136. /* Check validity of program. */
  2137. if (U_CHAR_AT (prog->program) != MAGIC) {
  2138. reg_error (U"corrupted program");
  2139. goto SINGLE_RETURN;
  2140. }
  2141. /* Remember the logical end of the string. */
  2142. End_Of_String = match_to;
  2143. if (reverse && ! end) {
  2144. for (end = string; ! AT_END_OF_STRING (end); end ++) { }
  2145. succ_char = U'\n';
  2146. } else if (! end) {
  2147. succ_char = U'\n';
  2148. }
  2149. /* Remember the beginning of the string for matching BOL */
  2150. Start_Of_String = string;
  2151. Look_Behind_To = look_behind_to ? look_behind_to : string;
  2152. Prev_Is_BOL = ( prev_char == U'\n' || prev_char == U'\0' );
  2153. Succ_Is_EOL = ( succ_char == U'\n' || succ_char == U'\0' );
  2154. Prev_Is_Delim = ! Melder_isWordCharacter (prev_char);
  2155. Succ_Is_Delim = ! Melder_isWordCharacter (succ_char);
  2156. Total_Paren = (int) (prog->program [1]);
  2157. Num_Braces = (int) (prog->program [2]);
  2158. /* Reset the recursion detection flag */
  2159. Recursion_Limit_Exceeded = 0;
  2160. /* Cross_Regex_Backref = cross_regex_backref; */
  2161. /* Allocate memory for {m,n} construct counting variables if need be. */
  2162. if (Num_Braces > 0) {
  2163. Brace =
  2164. (brace_counts *) malloc (sizeof (brace_counts) * (size_t) Num_Braces);
  2165. if (Brace == NULL) {
  2166. reg_error (U"out of memory in `ExecRE\'");
  2167. goto SINGLE_RETURN;
  2168. }
  2169. } else {
  2170. Brace = NULL;
  2171. }
  2172. /* Initialize the first nine (9) capturing parentheses start and end
  2173. pointers to point to the start of the search string. This is to prevent
  2174. crashes when later trying to reference captured parens that do not exist
  2175. in the compiled regex. We only need to do the first nine since users
  2176. can only specify \1, \2, ... \9. */
  2177. for (i = 9; i > 0; i--) {
  2178. *s_ptr++ = (char32 *) string;
  2179. *e_ptr++ = (char32 *) string;
  2180. }
  2181. if (!reverse) { /* Forward Search */
  2182. if (prog->anchor) {
  2183. /* Search is anchored at BOL */
  2184. if (attempt (prog, (char32 *) string)) {
  2185. ret_val = 1;
  2186. goto SINGLE_RETURN;
  2187. }
  2188. for (str = (char32 *) string;
  2189. !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded;
  2190. str++) {
  2191. if (*str == '\n') {
  2192. if (attempt (prog, str + 1)) {
  2193. ret_val = 1;
  2194. break;
  2195. }
  2196. }
  2197. }
  2198. goto SINGLE_RETURN;
  2199. } else if (prog->match_start != '\0') {
  2200. /* We know what char match must start with. */
  2201. for (str = (char32 *) string;
  2202. !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded;
  2203. str++) {
  2204. if (*str == (char32) prog->match_start) {
  2205. if (attempt (prog, str)) {
  2206. ret_val = 1;
  2207. break;
  2208. }
  2209. }
  2210. }
  2211. goto SINGLE_RETURN;
  2212. } else {
  2213. /* General case */
  2214. for (str = (char32 *) string;
  2215. !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded;
  2216. str++) {
  2217. if (attempt (prog, str)) {
  2218. ret_val = 1;
  2219. break;
  2220. }
  2221. }
  2222. /* Beware of a single $ matching \0 */
  2223. if (!Recursion_Limit_Exceeded && !ret_val && AT_END_OF_STRING (str) && str != (char32 *) end) {
  2224. if (attempt (prog, str)) {
  2225. ret_val = 1;
  2226. }
  2227. }
  2228. goto SINGLE_RETURN;
  2229. }
  2230. } else { /* Search reverse, same as forward, but loops run backward */
  2231. /* Make sure that we don't start matching beyond the logical end */
  2232. if (End_Of_String != NULL && (char32 *) end > End_Of_String) {
  2233. end = (const char32 *) End_Of_String;
  2234. }
  2235. if (prog->anchor) {
  2236. /* Search is anchored at BOL */
  2237. for (str = (char32 *) (end - 1); str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) {
  2238. if (*str == '\n') {
  2239. if (attempt (prog, str + 1)) {
  2240. ret_val = 1;
  2241. goto SINGLE_RETURN;
  2242. }
  2243. }
  2244. }
  2245. if (!Recursion_Limit_Exceeded && attempt (prog, (char32 *) string)) {
  2246. ret_val = 1;
  2247. goto SINGLE_RETURN;
  2248. }
  2249. goto SINGLE_RETURN;
  2250. } else if (prog->match_start != '\0') {
  2251. /* We know what char match must start with. */
  2252. for (str = (char32 *) end; str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) {
  2253. if (*str == (char32) prog->match_start) {
  2254. if (attempt (prog, str)) {
  2255. ret_val = 1;
  2256. break;
  2257. }
  2258. }
  2259. }
  2260. goto SINGLE_RETURN;
  2261. } else {
  2262. /* General case */
  2263. for (str = (char32 *) end; str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) {
  2264. if (attempt (prog, str)) {
  2265. ret_val = 1;
  2266. break;
  2267. }
  2268. }
  2269. }
  2270. }
  2271. SINGLE_RETURN: if (Brace) {
  2272. free (Brace);
  2273. }
  2274. if (Recursion_Limit_Exceeded) {
  2275. return (0);
  2276. }
  2277. return (ret_val);
  2278. }
  2279. static int attempt (regexp *prog, char32 *string) {
  2280. int i;
  2281. char32 **s_ptr;
  2282. char32 **e_ptr;
  2283. int branch_index = 0; /* Must be set to zero ! */
  2284. Reg_Input = string;
  2285. Start_Ptr_Ptr = (char32 **) prog->startp;
  2286. End_Ptr_Ptr = (char32 **) prog->endp;
  2287. s_ptr = (char32 **) prog->startp;
  2288. e_ptr = (char32 **) prog->endp;
  2289. /* Reset the recursion counter. */
  2290. Recursion_Count = 0;
  2291. /* Overhead due to capturing parentheses. */
  2292. Extent_Ptr_BW = string;
  2293. Extent_Ptr_FW = nullptr;
  2294. for (i = Total_Paren + 1; i > 0; i--) {
  2295. *s_ptr ++ = nullptr;
  2296. *e_ptr ++ = nullptr;
  2297. }
  2298. if (match ( (char32 *) (prog->program + REGEX_START_OFFSET),
  2299. &branch_index)) {
  2300. prog->startp [0] = (char32 *) string;
  2301. prog->endp [0] = (char32 *) Reg_Input; /* <-- One char AFTER */
  2302. prog->extentpBW = (char32 *) Extent_Ptr_BW; /* matched string! */
  2303. prog->extentpFW = (char32 *) Extent_Ptr_FW;
  2304. prog->top_branch = branch_index;
  2305. return 1;
  2306. } else {
  2307. return 0;
  2308. }
  2309. }
  2310. /*----------------------------------------------------------------------*
  2311. * match - main matching routine
  2312. *
  2313. * Conceptually the strategy is simple: check to see whether the
  2314. * current node matches, call self recursively to see whether the rest
  2315. * matches, and then act accordingly. In practice we make some effort
  2316. * to avoid recursion, in particular by going through "ordinary" nodes
  2317. * (that don't need to know whether the rest of the match failed) by a
  2318. * loop instead of by recursion. Returns 0 failure, 1 success.
  2319. *----------------------------------------------------------------------*/
  2320. #define MATCH_RETURN(X)\
  2321. { --Recursion_Count; return (X); }
  2322. #define CHECK_RECURSION_LIMIT\
  2323. if (Recursion_Limit_Exceeded) MATCH_RETURN (0);
  2324. static int match (char32 *prog, int *branch_index_param) {
  2325. char32 *scan; /* Current node. */
  2326. char32 *next; /* Next node. */
  2327. int next_ptr_offset; /* Used by the NEXT_PTR () macro */
  2328. if (++ Recursion_Count > REGEX_RECURSION_LIMIT) {
  2329. if (! Recursion_Limit_Exceeded) { /* Prevent duplicate errors */
  2330. reg_error (U"recursion limit exceeded, please respecify expression");
  2331. }
  2332. Recursion_Limit_Exceeded = 1;
  2333. MATCH_RETURN (0)
  2334. }
  2335. scan = prog;
  2336. while (scan) {
  2337. NEXT_PTR (scan, next);
  2338. switch (GET_OP_CODE (scan)) {
  2339. case BRANCH: {
  2340. char32 *save;
  2341. int branch_index_local = 0;
  2342. if (GET_OP_CODE (next) != BRANCH) { /* No choice. */
  2343. next = OPERAND (scan); /* Avoid recursion. */
  2344. } else {
  2345. do {
  2346. save = Reg_Input;
  2347. if (match (OPERAND (scan), NULL)) {
  2348. if (branch_index_param)
  2349. *branch_index_param = branch_index_local;
  2350. MATCH_RETURN (1)
  2351. }
  2352. CHECK_RECURSION_LIMIT
  2353. ++branch_index_local;
  2354. Reg_Input = save; /* Backtrack. */
  2355. NEXT_PTR (scan, scan);
  2356. } while (scan != NULL && GET_OP_CODE (scan) == BRANCH);
  2357. MATCH_RETURN (0) // NOT REACHED
  2358. }
  2359. }
  2360. break;
  2361. case EXACTLY: {
  2362. char32 *opnd = OPERAND (scan);
  2363. /* Inline the first character, for speed. */
  2364. if (*opnd != *Reg_Input)
  2365. MATCH_RETURN (0)
  2366. int len = str32len (opnd);
  2367. if (End_Of_String != NULL && Reg_Input + len > End_Of_String)
  2368. MATCH_RETURN (0)
  2369. if (len > 1 && str32ncmp (opnd, Reg_Input, len) != 0)
  2370. MATCH_RETURN (0)
  2371. Reg_Input += len;
  2372. }
  2373. break;
  2374. case SIMILAR: {
  2375. char32 *opnd = OPERAND (scan);
  2376. char32 test;
  2377. /* Note: the SIMILAR operand was converted to lower case during
  2378. regex compile. */
  2379. while ((test = *opnd++) != U'\0') {
  2380. if (AT_END_OF_STRING (Reg_Input) || Melder_toLowerCase (*Reg_Input++) != test)
  2381. MATCH_RETURN (0)
  2382. }
  2383. }
  2384. break;
  2385. case BOL: /* `^' (beginning of line anchor) */
  2386. if (Reg_Input == Start_Of_String) {
  2387. if (Prev_Is_BOL)
  2388. break;
  2389. } else if (* (Reg_Input - 1) == U'\n') {
  2390. break;
  2391. }
  2392. MATCH_RETURN (0)
  2393. case EOL: /* `$' anchor matches end of line and end of string */
  2394. if (*Reg_Input == U'\n' || (AT_END_OF_STRING (Reg_Input) && Succ_Is_EOL))
  2395. break;
  2396. MATCH_RETURN (0)
  2397. case BOWORD: /* `<' (beginning of word anchor) */
  2398. /* Check to see if the current character is not a delimiter
  2399. and the preceding character is. */
  2400. {
  2401. bool prev_is_delim;
  2402. if (Reg_Input == Start_Of_String) {
  2403. prev_is_delim = Prev_Is_Delim;
  2404. } else {
  2405. prev_is_delim = ! Melder_isWordCharacter (*(Reg_Input - 1));
  2406. }
  2407. if (prev_is_delim) {
  2408. bool current_is_delim;
  2409. if (AT_END_OF_STRING (Reg_Input)) {
  2410. current_is_delim = Succ_Is_Delim;
  2411. } else {
  2412. current_is_delim = ! Melder_isWordCharacter (*Reg_Input);
  2413. }
  2414. if (! current_is_delim)
  2415. break;
  2416. }
  2417. }
  2418. MATCH_RETURN (0)
  2419. case EOWORD: /* `>' (end of word anchor) */
  2420. /* Check to see if the current character is a delimiter
  2421. and the preceding character is not. */
  2422. {
  2423. bool prev_is_delim;
  2424. if (Reg_Input == Start_Of_String) {
  2425. prev_is_delim = Prev_Is_Delim;
  2426. } else {
  2427. prev_is_delim = ! Melder_isWordCharacter (*(Reg_Input - 1));
  2428. }
  2429. if (! prev_is_delim) {
  2430. bool current_is_delim;
  2431. if (AT_END_OF_STRING (Reg_Input)) {
  2432. current_is_delim = Succ_Is_Delim;
  2433. } else {
  2434. current_is_delim = ! Melder_isWordCharacter (*Reg_Input);
  2435. }
  2436. if (current_is_delim)
  2437. break;
  2438. }
  2439. }
  2440. MATCH_RETURN (0)
  2441. case NOT_BOUNDARY: { /* \B (NOT a word boundary) */
  2442. bool prev_is_delim;
  2443. bool current_is_delim;
  2444. if (Reg_Input == Start_Of_String) {
  2445. prev_is_delim = Prev_Is_Delim;
  2446. } else {
  2447. prev_is_delim = ! Melder_isWordCharacter (*(Reg_Input - 1));
  2448. }
  2449. if (AT_END_OF_STRING (Reg_Input)) {
  2450. current_is_delim = Succ_Is_Delim;
  2451. } else {
  2452. current_is_delim = ! Melder_isWordCharacter (*Reg_Input);
  2453. }
  2454. if (! (prev_is_delim ^ current_is_delim))
  2455. break;
  2456. }
  2457. MATCH_RETURN (0)
  2458. case IS_DELIM: /* \y (A word delimiter character.) */
  2459. if (! Melder_isWordCharacter (*Reg_Input) && ! AT_END_OF_STRING (Reg_Input)) {
  2460. Reg_Input++; break;
  2461. }
  2462. MATCH_RETURN (0)
  2463. case NOT_DELIM: /* \Y (NOT a word delimiter character.) */
  2464. if (Melder_isWordCharacter (*Reg_Input) && ! AT_END_OF_STRING (Reg_Input)) {
  2465. Reg_Input ++;
  2466. break;
  2467. }
  2468. MATCH_RETURN (0)
  2469. case WORD_CHAR: /* \w (word character; alpha-numeric or underscore) */
  2470. if (Melder_isWordCharacter (*Reg_Input) && ! AT_END_OF_STRING (Reg_Input)) {
  2471. Reg_Input ++;
  2472. break;
  2473. }
  2474. MATCH_RETURN (0)
  2475. case NOT_WORD_CHAR:/* \W (NOT a word character) */
  2476. if (Melder_isWordCharacter (*Reg_Input) || *Reg_Input == U'\n' || AT_END_OF_STRING (Reg_Input))
  2477. MATCH_RETURN (0)
  2478. Reg_Input ++;
  2479. break;
  2480. case ANY: /* `.' (matches any character EXCEPT newline) */
  2481. if (AT_END_OF_STRING (Reg_Input) || *Reg_Input == U'\n')
  2482. MATCH_RETURN (0)
  2483. Reg_Input ++;
  2484. break;
  2485. case EVERY: /* `.' (matches any character INCLUDING newline) */
  2486. if (AT_END_OF_STRING (Reg_Input))
  2487. MATCH_RETURN (0)
  2488. Reg_Input ++;
  2489. break;
  2490. case DIGIT: /* \d; for ASCII, use [0-9] */
  2491. if (! Melder_isDecimalNumber (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2492. MATCH_RETURN (0)
  2493. Reg_Input ++;
  2494. break;
  2495. case NOT_DIGIT: /* \D; for ASCII, use [^0-9] */
  2496. if (Melder_isDecimalNumber (*Reg_Input) || *Reg_Input == U'\n' || AT_END_OF_STRING (Reg_Input))
  2497. MATCH_RETURN (0)
  2498. Reg_Input ++;
  2499. break;
  2500. case LETTER: /* \l; for ASCII, use [a-zA-Z] */
  2501. if (! Melder_isLetter (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2502. MATCH_RETURN (0)
  2503. Reg_Input ++;
  2504. break;
  2505. case NOT_LETTER: /* \L; for ASCII, use [^a-zA-Z] */
  2506. if (Melder_isLetter (*Reg_Input) || *Reg_Input == '\n' || AT_END_OF_STRING (Reg_Input))
  2507. MATCH_RETURN (0)
  2508. Reg_Input ++;
  2509. break;
  2510. case SPACE: /* \s; for ASCII, use [ \t] */
  2511. if (! Melder_isHorizontalSpace (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2512. MATCH_RETURN (0)
  2513. Reg_Input ++;
  2514. break;
  2515. case SPACE_NL: /* \s; for ASCII, use [\n \t\r\f\v] */
  2516. if (! Melder_isHorizontalOrVerticalSpace (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2517. MATCH_RETURN (0)
  2518. Reg_Input ++;
  2519. break;
  2520. case NOT_SPACE: /* \S; for ASCII, use [^\n \t\r\f\v] */
  2521. if (Melder_isHorizontalOrVerticalSpace (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2522. MATCH_RETURN (0)
  2523. Reg_Input ++;
  2524. break;
  2525. case NOT_SPACE_NL: /* \S; for ASCII, use [^ \t\r\f\v] */
  2526. if (Melder_isHorizontalSpace (*Reg_Input) || AT_END_OF_STRING (Reg_Input))
  2527. MATCH_RETURN (0)
  2528. Reg_Input ++;
  2529. break;
  2530. case ANY_OF: /* [...] character class. */
  2531. if (AT_END_OF_STRING (Reg_Input))
  2532. MATCH_RETURN (0)
  2533. /* Needed because strchr ()
  2534. considers \0 as a member
  2535. of the character set. */
  2536. if (! str32chr (OPERAND (scan), *Reg_Input))
  2537. MATCH_RETURN (0)
  2538. Reg_Input ++;
  2539. break;
  2540. case ANY_BUT: /* [^...] Negated character class-- does NOT normally
  2541. match newline (\n added usually to operand at compile
  2542. time.) */
  2543. if (AT_END_OF_STRING (Reg_Input)) {
  2544. MATCH_RETURN (0); /* See comment for ANY_OF. */
  2545. }
  2546. if (str32chr (OPERAND (scan), *Reg_Input) != nullptr)
  2547. MATCH_RETURN (0)
  2548. Reg_Input ++;
  2549. break;
  2550. case NOTHING:
  2551. case BACK:
  2552. break;
  2553. case STAR:
  2554. case PLUS:
  2555. case QUESTION:
  2556. case BRACE:
  2557. case LAZY_STAR:
  2558. case LAZY_PLUS:
  2559. case LAZY_QUESTION:
  2560. case LAZY_BRACE: {
  2561. unsigned long num_matched = REG_ZERO;
  2562. unsigned long min = ULONG_MAX, max = REG_ZERO;
  2563. char32 *save;
  2564. char32 next_char;
  2565. char32 *next_op;
  2566. int lazy = 0;
  2567. /* Lookahead (when possible) to avoid useless match attempts
  2568. when we know what character comes next. */
  2569. if (GET_OP_CODE (next) == EXACTLY) {
  2570. next_char = *OPERAND (next);
  2571. } else {
  2572. next_char = U'\0';/* i.e. Don't know what next character is. */
  2573. }
  2574. next_op = OPERAND (scan);
  2575. switch (GET_OP_CODE (scan)) {
  2576. case LAZY_STAR:
  2577. lazy = 1;
  2578. case STAR:
  2579. min = REG_ZERO;
  2580. max = ULONG_MAX;
  2581. break;
  2582. case LAZY_PLUS:
  2583. lazy = 1;
  2584. case PLUS:
  2585. min = REG_ONE;
  2586. max = ULONG_MAX;
  2587. break;
  2588. case LAZY_QUESTION:
  2589. lazy = 1;
  2590. case QUESTION:
  2591. min = REG_ZERO;
  2592. max = REG_ONE;
  2593. break;
  2594. case LAZY_BRACE:
  2595. lazy = 1;
  2596. case BRACE:
  2597. min = (unsigned long)
  2598. GET_OFFSET (scan + NEXT_PTR_SIZE);
  2599. max = (unsigned long)
  2600. GET_OFFSET (scan + (2 * NEXT_PTR_SIZE));
  2601. if (max <= REG_INFINITY) {
  2602. max = ULONG_MAX;
  2603. }
  2604. next_op = OPERAND (scan + (2 * NEXT_PTR_SIZE));
  2605. }
  2606. save = Reg_Input;
  2607. if (lazy) {
  2608. if (min > REG_ZERO) {
  2609. num_matched = greedy (next_op, min);
  2610. }
  2611. } else {
  2612. num_matched = greedy (next_op, max);
  2613. }
  2614. while (min <= num_matched && num_matched <= max) {
  2615. if (next_char == U'\0' || next_char == *Reg_Input) {
  2616. if (match (next, NULL)) {
  2617. MATCH_RETURN (1);
  2618. }
  2619. CHECK_RECURSION_LIMIT
  2620. }
  2621. /* Couldn't or didn't match. */
  2622. if (lazy) {
  2623. if (!greedy (next_op, 1)) {
  2624. MATCH_RETURN (0);
  2625. }
  2626. num_matched ++; /* Inch forward. */
  2627. } else if (num_matched > REG_ZERO) {
  2628. num_matched --; /* Back up. */
  2629. } else if (min == REG_ZERO && num_matched == REG_ZERO) {
  2630. break;
  2631. }
  2632. Reg_Input = save + num_matched;
  2633. }
  2634. MATCH_RETURN (0);
  2635. }
  2636. break;
  2637. case END:
  2638. if (Extent_Ptr_FW == NULL || (Reg_Input - Extent_Ptr_FW) > 0) {
  2639. Extent_Ptr_FW = Reg_Input;
  2640. }
  2641. MATCH_RETURN (1) // Success!
  2642. break;
  2643. case INIT_COUNT:
  2644. Brace->count [*OPERAND (scan)] = REG_ZERO;
  2645. break;
  2646. case INC_COUNT:
  2647. Brace->count [*OPERAND (scan)] ++;
  2648. break;
  2649. case TEST_COUNT:
  2650. if (Brace->count [*OPERAND (scan)] <
  2651. (unsigned long) GET_OFFSET (scan + NEXT_PTR_SIZE + INDEX_SIZE)) {
  2652. next = scan + NODE_SIZE + INDEX_SIZE + NEXT_PTR_SIZE;
  2653. }
  2654. break;
  2655. case BACK_REF:
  2656. case BACK_REF_CI:
  2657. /* case X_REGEX_BR: */
  2658. /* case X_REGEX_BR_CI: *** IMPLEMENT LATER */
  2659. {
  2660. char32 *captured, *finish;
  2661. int paren_no;
  2662. paren_no = (int) * OPERAND (scan);
  2663. /* if (GET_OP_CODE (scan) == X_REGEX_BR ||
  2664. GET_OP_CODE (scan) == X_REGEX_BR_CI) {
  2665. if (Cross_Regex_Backref == NULL) MATCH_RETURN (0);
  2666. captured =
  2667. (regularExp_CHAR *) Cross_Regex_Backref->startp [paren_no];
  2668. finish =
  2669. (regularExp_CHAR *) Cross_Regex_Backref->endp [paren_no];
  2670. } else { */
  2671. captured = Back_Ref_Start [paren_no];
  2672. finish = Back_Ref_End [paren_no];
  2673. /* } */
  2674. if (captured && finish) {
  2675. if (captured > finish) {
  2676. MATCH_RETURN (0);
  2677. }
  2678. if (GET_OP_CODE (scan) == BACK_REF_CI /* ||
  2679. GET_OP_CODE (scan) == X_REGEX_BR_CI*/) {
  2680. while (captured < finish) {
  2681. if (AT_END_OF_STRING (Reg_Input) || Melder_toLowerCase (*captured++) != Melder_toLowerCase (*Reg_Input++)) // TODO: should casefold
  2682. MATCH_RETURN (0)
  2683. }
  2684. } else {
  2685. while (captured < finish) {
  2686. if (AT_END_OF_STRING (Reg_Input) || *captured++ != *Reg_Input++)
  2687. MATCH_RETURN (0)
  2688. }
  2689. }
  2690. break;
  2691. } else {
  2692. MATCH_RETURN (0)
  2693. }
  2694. }
  2695. case POS_AHEAD_OPEN:
  2696. case NEG_AHEAD_OPEN:
  2697. {
  2698. char32 *save = Reg_Input;
  2699. /* Temporarily ignore the logical end of the string, to allow
  2700. lookahead past the end. */
  2701. const char32 *saved_end = End_Of_String;
  2702. End_Of_String = NULL;
  2703. int answer = match (next, NULL); /* Does the look-ahead regex match? */
  2704. CHECK_RECURSION_LIMIT
  2705. if ( (GET_OP_CODE (scan) == POS_AHEAD_OPEN) ? answer : ! answer) {
  2706. /* Remember the last (most to the right) character position
  2707. that we consume in the input for a successful match. This
  2708. is info that may be needed should an attempt be made to
  2709. match the exact same text at the exact same place. Since
  2710. look-aheads backtrack, a regex with a trailing look-ahead
  2711. may need more text than it matches to accomplish a
  2712. re-match. */
  2713. if (Extent_Ptr_FW == NULL || (Reg_Input - Extent_Ptr_FW) > 0) {
  2714. Extent_Ptr_FW = Reg_Input;
  2715. }
  2716. Reg_Input = save; /* Backtrack to look-ahead start. */
  2717. End_Of_String = saved_end; /* Restore logical end. */
  2718. /* Jump to the node just after the (?=...) or (?!...)
  2719. Construct. */
  2720. next = next_ptr (OPERAND (scan)); /* Skip 1st branch */
  2721. /* Skip the chain of branches inside the look-ahead */
  2722. while (GET_OP_CODE (next) == BRANCH) {
  2723. next = next_ptr (next);
  2724. }
  2725. next = next_ptr (next); /* Skip the LOOK_AHEAD_CLOSE */
  2726. } else {
  2727. Reg_Input = save; /* Backtrack to look-ahead start. */
  2728. End_Of_String = saved_end; /* Restore logical end. */
  2729. MATCH_RETURN (0)
  2730. }
  2731. }
  2732. break;
  2733. case POS_BEHIND_OPEN:
  2734. case NEG_BEHIND_OPEN: {
  2735. char32 *save;
  2736. int answer;
  2737. int offset, upper;
  2738. int lower;
  2739. int found = 0;
  2740. const char32 *saved_end;
  2741. save = Reg_Input;
  2742. saved_end = End_Of_String;
  2743. /* Prevent overshoot (greedy matching could end past the
  2744. current position) by tightening the matching boundary.
  2745. Lookahead inside lookbehind can still cross that boundary. */
  2746. End_Of_String = Reg_Input;
  2747. lower = GET_LOWER (scan);
  2748. upper = GET_UPPER (scan);
  2749. /* Start with the shortest match first. This is the most
  2750. efficient direction in general.
  2751. Note! Negative look behind is _very_ tricky when the length
  2752. is not constant: we have to make sure the expression doesn't
  2753. match for _any_ of the starting positions. */
  2754. for (offset = lower; offset <= upper; ++offset) {
  2755. Reg_Input = save - offset;
  2756. if (Reg_Input < Look_Behind_To) {
  2757. /* No need to look any further */
  2758. break;
  2759. }
  2760. answer = match (next, NULL); /* Does the look-behind regex match? */
  2761. CHECK_RECURSION_LIMIT
  2762. /* The match must have ended at the current position;
  2763. otherwise it is invalid */
  2764. if (answer && Reg_Input == save) {
  2765. /* It matched, exactly far enough */
  2766. found = 1;
  2767. /* Remember the last (most to the left) character position
  2768. that we consume in the input for a successful match.
  2769. This is info that may be needed should an attempt be
  2770. made to match the exact same text at the exact same
  2771. place. Since look-behind backtracks, a regex with a
  2772. leading look-behind may need more text than it matches
  2773. to accomplish a re-match. */
  2774. if (Extent_Ptr_BW == NULL ||
  2775. (Extent_Ptr_BW - (save - offset)) > 0) {
  2776. Extent_Ptr_BW = save - offset;
  2777. }
  2778. break;
  2779. }
  2780. }
  2781. /* Always restore the position and the logical string end. */
  2782. Reg_Input = save;
  2783. End_Of_String = saved_end;
  2784. if ( (GET_OP_CODE (scan) == POS_BEHIND_OPEN) ? found : !found) {
  2785. /* The look-behind matches, so we must jump to the next
  2786. node. The look-behind node is followed by a chain of
  2787. branches (contents of the look-behind expression), and
  2788. terminated by a look-behind-close node. */
  2789. next = next_ptr (OPERAND (scan) + LENGTH_SIZE); /* 1st branch */
  2790. /* Skip the chained branches inside the look-ahead */
  2791. while (GET_OP_CODE (next) == BRANCH) {
  2792. next = next_ptr (next);
  2793. }
  2794. next = next_ptr (next); /* Skip LOOK_BEHIND_CLOSE */
  2795. } else {
  2796. /* Not a match */
  2797. MATCH_RETURN (0)
  2798. }
  2799. }
  2800. break;
  2801. case LOOK_AHEAD_CLOSE:
  2802. case LOOK_BEHIND_CLOSE:
  2803. MATCH_RETURN (1); /* We have reached the end of the look-ahead or
  2804. look-behind which implies that we matched it,
  2805. so return `true`. */
  2806. default:
  2807. if ( (GET_OP_CODE (scan) > OPEN) &&
  2808. (GET_OP_CODE (scan) < OPEN + NSUBEXP)) {
  2809. int no;
  2810. char32 *save;
  2811. no = GET_OP_CODE (scan) - OPEN;
  2812. save = Reg_Input;
  2813. if (no < 10) {
  2814. Back_Ref_Start [no] = save;
  2815. Back_Ref_End [no] = NULL;
  2816. }
  2817. if (match (next, NULL)) {
  2818. /* Do not set `Start_Ptr_Ptr' if some later invocation (think
  2819. recursion) of the same parentheses already has. */
  2820. if (Start_Ptr_Ptr [no] == NULL) {
  2821. Start_Ptr_Ptr [no] = save;
  2822. }
  2823. MATCH_RETURN (1)
  2824. } else {
  2825. MATCH_RETURN (0)
  2826. }
  2827. } else if ( (GET_OP_CODE (scan) > CLOSE) &&
  2828. (GET_OP_CODE (scan) < CLOSE + NSUBEXP)) {
  2829. int no;
  2830. char32 *save;
  2831. no = GET_OP_CODE (scan) - CLOSE;
  2832. save = Reg_Input;
  2833. if (no < 10) {
  2834. Back_Ref_End [no] = save;
  2835. }
  2836. if (match (next, NULL)) {
  2837. /* Do not set `End_Ptr_Ptr' if some later invocation of the
  2838. same parentheses already has. */
  2839. if (End_Ptr_Ptr [no] == NULL) {
  2840. End_Ptr_Ptr [no] = save;
  2841. }
  2842. MATCH_RETURN (1)
  2843. } else {
  2844. MATCH_RETURN (0)
  2845. }
  2846. } else {
  2847. reg_error (U"memory corruption, `match\'");
  2848. MATCH_RETURN (0)
  2849. }
  2850. break;
  2851. }
  2852. scan = next;
  2853. }
  2854. /* We get here only if there's trouble -- normally "case END" is
  2855. the terminating point. */
  2856. reg_error (U"corrupted pointers, `match\'");
  2857. MATCH_RETURN (0)
  2858. }
  2859. /*----------------------------------------------------------------------*
  2860. * greedy
  2861. *
  2862. * Repeatedly match something simple up to "max" times. If max <= 0
  2863. * then match as much as possible (max = infinity). Uses unsigned long
  2864. * variables to maximize the amount of text matchable for unbounded
  2865. * qualifiers like '*' and '+'. This will allow at least 4,294,967,295
  2866. * matches (4 Gig!) for an ANSI C compliant compiler. If you are
  2867. * applying a regex to something bigger than that, you shouldn't be
  2868. * using NEdit!
  2869. *
  2870. * Returns the actual number of matches.
  2871. *----------------------------------------------------------------------*/
  2872. static unsigned long greedy (char32 *p, long max) {
  2873. char32 *input_str;
  2874. char32 *operand;
  2875. unsigned long count = REG_ZERO;
  2876. unsigned long max_cmp;
  2877. input_str = Reg_Input;
  2878. operand = OPERAND (p); /* Literal char or start of class characters. */
  2879. max_cmp = (max > 0) ? (unsigned long) max : ULONG_MAX;
  2880. switch (GET_OP_CODE (p))
  2881. {
  2882. case ANY: /* Race to the end of the line or string. Dot DOESN'T match newline. */
  2883. while (count < max_cmp && *input_str != '\n' && ! AT_END_OF_STRING (input_str)) {
  2884. count ++;
  2885. input_str ++;
  2886. }
  2887. break;
  2888. case EVERY: /* Race to the end of the line or string. Dot DOES match newline. */
  2889. while (count < max_cmp && ! AT_END_OF_STRING (input_str)) {
  2890. count ++;
  2891. input_str ++;
  2892. }
  2893. break;
  2894. case EXACTLY: /* Count occurrences of single character operand. */
  2895. while (count < max_cmp && *operand == *input_str && ! AT_END_OF_STRING (input_str)) {
  2896. count ++;
  2897. input_str ++;
  2898. }
  2899. break;
  2900. case SIMILAR: /* Case-insensitive version of EXACTLY */
  2901. while (count < max_cmp && *operand == Melder_toLowerCase (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2902. count ++;
  2903. input_str ++;
  2904. }
  2905. break;
  2906. case ANY_OF: /* [...] character class. */
  2907. while (count < max_cmp && str32chr (operand, *input_str) != NULL && ! AT_END_OF_STRING (input_str)) {
  2908. count ++;
  2909. input_str ++;
  2910. }
  2911. break;
  2912. case ANY_BUT: /* [^...] Negated character class- does NOT normally
  2913. match newline (\n added usually to operand at compile
  2914. time.) */
  2915. while (count < max_cmp && str32chr (operand, *input_str) == NULL && ! AT_END_OF_STRING (input_str)) {
  2916. count ++;
  2917. input_str ++;
  2918. }
  2919. break;
  2920. case IS_DELIM: /* \y (not a word delimiter char)
  2921. NOTE: '\n' and '\0' are always word delimiters. */
  2922. while (count < max_cmp && ! Melder_isWordCharacter (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2923. count ++;
  2924. input_str ++;
  2925. }
  2926. break;
  2927. case NOT_DELIM: /* \Y (not a word delimiter char)
  2928. NOTE: '\n' and '\0' are always word delimiters. */
  2929. while (count < max_cmp && Melder_isWordCharacter (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2930. count ++;
  2931. input_str ++;
  2932. }
  2933. break;
  2934. case WORD_CHAR: /* \w (a word character: letter, number, mark or connector punctuation) */
  2935. while (count < max_cmp && Melder_isWordCharacter (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2936. count ++;
  2937. input_str ++;
  2938. }
  2939. break;
  2940. case NOT_WORD_CHAR: /* \W (NOT a word character) */
  2941. while (count < max_cmp && ! Melder_isWordCharacter (*input_str) && *input_str != U'\n' && ! AT_END_OF_STRING (input_str)) {
  2942. count ++;
  2943. input_str ++;
  2944. }
  2945. break;
  2946. case DIGIT: /* for ASCII, use [0-9] */
  2947. while (count < max_cmp && Melder_isDecimalNumber (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2948. count ++;
  2949. input_str ++;
  2950. }
  2951. break;
  2952. case NOT_DIGIT: /* for ASCII, use [^0-9] */
  2953. while (count < max_cmp && ! Melder_isDecimalNumber (*input_str) && *input_str != U'\n' && ! AT_END_OF_STRING (input_str)) {
  2954. count ++;
  2955. input_str ++;
  2956. }
  2957. break;
  2958. case SPACE: /* for ASCII, use [ \t\r\f\v]-- doesn't match newline. */
  2959. while (count < max_cmp && Melder_isHorizontalSpace (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2960. count ++;
  2961. input_str ++;
  2962. }
  2963. break;
  2964. case SPACE_NL: /* for ASCII, use [\n \t\r\f\v]-- matches newline. */
  2965. while (count < max_cmp && Melder_isHorizontalOrVerticalSpace (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2966. count ++;
  2967. input_str ++;
  2968. }
  2969. break;
  2970. case NOT_SPACE: /* for ASCII, use [^\n \t\r\f\v]-- doesn't match newline. */
  2971. while (count < max_cmp && ! Melder_isHorizontalOrVerticalSpace (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2972. count ++;
  2973. input_str ++;
  2974. }
  2975. break;
  2976. case NOT_SPACE_NL: /* for ASCII, use [^ \t\r\f\v]-- matches newline. */
  2977. while (count < max_cmp && ! Melder_isHorizontalSpace (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2978. count ++;
  2979. input_str ++;
  2980. }
  2981. break;
  2982. case LETTER: /* for ASCII, use [a-zA-Z] */
  2983. while (count < max_cmp && Melder_isLetter (*input_str) && ! AT_END_OF_STRING (input_str)) {
  2984. count ++;
  2985. input_str ++;
  2986. }
  2987. break;
  2988. case NOT_LETTER: /* for ASCII, use [^a-zA-Z] */
  2989. while (count < max_cmp && ! Melder_isLetter (*input_str) && *input_str != '\n' && ! AT_END_OF_STRING (input_str)) {
  2990. count ++;
  2991. input_str ++;
  2992. }
  2993. break;
  2994. default:
  2995. /* Called inappropriately. Only atoms that are SIMPLE should
  2996. generate a call to greedy. The above cases should cover
  2997. all the atoms that are SIMPLE. */
  2998. reg_error (U"internal error #10 `greedy\'");
  2999. count = 0U; /* Best we can do. */
  3000. }
  3001. /* Point to character just after last matched character. */
  3002. Reg_Input = input_str;
  3003. return (count);
  3004. }
  3005. /*----------------------------------------------------------------------*
  3006. * next_ptr - compute the address of a node's "NEXT" pointer.
  3007. * Note: a simplified inline version is available via the NEXT_PTR() macro,
  3008. * but that one is only to be used at time-critical places (see the
  3009. * description of the macro).
  3010. *----------------------------------------------------------------------*/
  3011. static char32 *next_ptr (char32 *ptr) {
  3012. if (ptr == & Compute_Size)
  3013. return nullptr;
  3014. int offset = GET_OFFSET (ptr);
  3015. if (offset == 0)
  3016. return nullptr;
  3017. if (GET_OP_CODE (ptr) == BACK) {
  3018. return ptr - offset;
  3019. } else {
  3020. return ptr + offset;
  3021. }
  3022. }
  3023. /*
  3024. ** SubstituteRE - Perform substitutions after a `regexp' match.
  3025. **
  3026. ** This function cleanly shortens results of more than max length to max.
  3027. ** To give the caller a chance to react to this the function returns False
  3028. ** on any error. The substitution will still be executed.
  3029. */
  3030. int SubstituteRE (const regexp *prog, conststring32 source, mutablestring32 dest, int max, int *errorType) {
  3031. const char32 *src;
  3032. const char32 *src_alias;
  3033. char32 *dst;
  3034. char32 c;
  3035. char32 test;
  3036. int paren_no;
  3037. int len;
  3038. char32 chgcase;
  3039. bool anyWarnings = false;
  3040. *errorType = 0;
  3041. if (! prog || ! source || ! dest) {
  3042. reg_error (U"NULL parm to `SubstituteRE\'");
  3043. *errorType = 2;
  3044. return false;
  3045. }
  3046. if (U_CHAR_AT (prog->program) != MAGIC) {
  3047. *errorType = 3;
  3048. reg_error (U"damaged regexp passed to `SubstituteRE\'");
  3049. return false;
  3050. }
  3051. src = source;
  3052. dst = dest;
  3053. while ( (c = *src++) != U'\0') {
  3054. chgcase = U'\0';
  3055. paren_no = -1;
  3056. if (c == U'\\') {
  3057. /* Process any case-altering tokens, i.e \u, \U, \l, \L. */
  3058. if (*src == U'u' || *src == U'U' || *src == U'l' || *src == U'L') {
  3059. chgcase = *src;
  3060. src ++;
  3061. c = *src ++;
  3062. if (c == U'\0')
  3063. break;
  3064. }
  3065. }
  3066. if (c == U'&') {
  3067. paren_no = 0;
  3068. } else if (c == U'\\') {
  3069. /* Can not pass register variable `&src' to function `numeric_escape'
  3070. so make a non-register copy that we can take the address of. */
  3071. src_alias = src;
  3072. if (U'1' <= *src && *src <= U'9') {
  3073. paren_no = (int) * src++ - (int) '0';
  3074. } else if ( (test = literal_escape (*src)) != U'\0') {
  3075. c = test; src++;
  3076. } else if ( (test = numeric_escape (*src, (char32 **) &src_alias)) != U'\0') {
  3077. c = test;
  3078. src = src_alias;
  3079. src ++;
  3080. /* NOTE: if an octal escape for zero is attempted (e.g. \000), it
  3081. will be treated as a literal string. */
  3082. } else if (*src == U'\0') {
  3083. /* If '\' is the last character of the replacement string, it is
  3084. interpreted as a literal backslash. */
  3085. c = U'\\';
  3086. } else {
  3087. c = *src ++; /* Allow any escape sequence (This is */
  3088. } /* INCONSISTENT with the `CompileRE' */
  3089. } /* mind set of issuing an error! */
  3090. if (paren_no < 0) { /* Ordinary character. */
  3091. if ( (dst - dest) >= (max - 1)) {
  3092. *errorType = 1;
  3093. reg_error (U"replacing expression in `SubstituteRE\' too long; truncating");
  3094. anyWarnings = true;
  3095. break;
  3096. } else {
  3097. *dst++ = c;
  3098. }
  3099. } else if (prog->startp [paren_no] != NULL &&
  3100. prog->endp [paren_no] != NULL) {
  3101. len = prog->endp [paren_no] - prog->startp [paren_no];
  3102. if ( (dst + len - dest) >= max - 1) {
  3103. *errorType = 1;
  3104. reg_error (U"replacing expression in `SubstituteRE\' too long; truncating");
  3105. anyWarnings = true;
  3106. len = max - (dst - dest) - 1;
  3107. }
  3108. (void) str32ncpy (dst, prog->startp [paren_no], len);
  3109. if (chgcase != U'\0') {
  3110. adjustcase (dst, len, chgcase);
  3111. }
  3112. dst += len;
  3113. if (len != 0 && * (dst - 1) == U'\0') { /* strncpy hit NUL. */
  3114. *errorType = 3;
  3115. reg_error (U"damaged match string in `SubstituteRE\'");
  3116. anyWarnings = true;
  3117. }
  3118. }
  3119. }
  3120. *dst = U'\0';
  3121. return ! anyWarnings;
  3122. }
  3123. static void adjustcase (char32 *str, int len, char32 chgcase) {
  3124. char32 *string = str;
  3125. /* The tokens \u and \l only modify the first character while the tokens
  3126. \U and \L modify the entire string. */
  3127. if (iswlower ((int) chgcase) && len > 0)
  3128. len = 1;
  3129. switch (chgcase) {
  3130. case U'u':
  3131. case U'U':
  3132. for (integer i = 0; i < len; i ++)
  3133. * (string + i) = Melder_toUpperCase (* (string + i));
  3134. break;
  3135. case U'l':
  3136. case U'L':
  3137. for (integer i = 0; i < len; i ++)
  3138. * (string + i) = Melder_toLowerCase (* (string + i));
  3139. break;
  3140. }
  3141. }
  3142. /*----------------------------------------------------------------------*
  3143. * reg_error
  3144. *----------------------------------------------------------------------*/
  3145. static void reg_error (conststring32 str) {
  3146. Melder_appendError (U"Internal error processing regular expression: ", str);
  3147. }
  3148. void EnableCountingQuantifier (int is_enabled) {
  3149. Enable_Counting_Quantifier = is_enabled;
  3150. }
  3151. /* End of file regularExp.cpp */