123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041 |
- /*
- *********************************************************************************************************
- * uC/LIB
- * CUSTOM LIBRARY MODULES
- *
- * (c) Copyright 2004-2014; Micrium, Inc.; Weston, FL
- *
- * All rights reserved. Protected by international copyright laws.
- *
- * uC/LIB is provided in source form to registered licensees ONLY. It is
- * illegal to distribute this source code to any third party unless you receive
- * written permission by an authorized Micrium representative. Knowledge of
- * the source code may NOT be used to develop a similar product.
- *
- * Please help us continue to provide the Embedded community with the finest
- * software available. Your honesty is greatly appreciated.
- *
- * You can find our product's user manual, API reference, release notes and
- * more information at: https://doc.micrium.com
- *
- * You can contact us at: http://www.micrium.com
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- *
- * ASCII STRING MANAGEMENT
- *
- * Filename : lib_str.c
- * Version : V1.38.01
- * Programmer(s) : ITJ
- * BAN
- * JDH
- *********************************************************************************************************
- * Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
- *
- * (a) ALL standard library functions are implemented in the custom library modules :
- *
- * (1) \<Custom Library Directory>\lib_*.*
- *
- * (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
- *
- * where
- * <Custom Library Directory> directory path for custom library software
- * <cpu> directory name for specific processor (CPU)
- * <compiler> directory name for specific compiler
- *
- * (b) Product-specific library functions are implemented in individual products.
- *
- *********************************************************************************************************
- * Notice(s) : (1) The Institute of Electrical and Electronics Engineers and The Open Group, have given
- * us permission to reprint portions of their documentation. Portions of this text are
- * reprinted and reproduced in electronic form from the IEEE Std 1003.1, 2004 Edition,
- * Standard for Information Technology -- Portable Operating System Interface (POSIX),
- * The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute
- * of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any
- * discrepancy between these versions and the original IEEE and The Open Group Standard,
- * the original IEEE and The Open Group Standard is the referee document. The original
- * Standard can be obtained online at http://www.opengroup.org/unix/online.html.
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * INCLUDE FILES
- *********************************************************************************************************
- */
- #define MICRIUM_SOURCE
- #define LIB_STR_MODULE
- #include <lib_str.h>
- /*
- *********************************************************************************************************
- * LOCAL DEFINES
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * LOCAL CONSTANTS
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * LOCAL DATA TYPES
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * LOCAL TABLES
- *********************************************************************************************************
- */
- static const CPU_INT32U Str_MultOvfThTbl_Int32U[] = {
- (CPU_INT32U) DEF_INT_32U_MAX_VAL, /* Invalid base 0. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 1u), /* Invalid base 1. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 2u), /* 32-bit mult ovf th for base 2. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 3u), /* 32-bit mult ovf th for base 3. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 4u), /* 32-bit mult ovf th for base 4. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 5u), /* 32-bit mult ovf th for base 5. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 6u), /* 32-bit mult ovf th for base 6. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 7u), /* 32-bit mult ovf th for base 7. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 8u), /* 32-bit mult ovf th for base 8. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 9u), /* 32-bit mult ovf th for base 9. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 10u), /* 32-bit mult ovf th for base 10. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 11u), /* 32-bit mult ovf th for base 11. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 12u), /* 32-bit mult ovf th for base 12. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 13u), /* 32-bit mult ovf th for base 13. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 14u), /* 32-bit mult ovf th for base 14. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 15u), /* 32-bit mult ovf th for base 15. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 16u), /* 32-bit mult ovf th for base 16. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 17u), /* 32-bit mult ovf th for base 17. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 18u), /* 32-bit mult ovf th for base 18. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 19u), /* 32-bit mult ovf th for base 19. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 20u), /* 32-bit mult ovf th for base 20. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 21u), /* 32-bit mult ovf th for base 21. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 22u), /* 32-bit mult ovf th for base 22. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 23u), /* 32-bit mult ovf th for base 23. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 24u), /* 32-bit mult ovf th for base 24. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 25u), /* 32-bit mult ovf th for base 25. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 26u), /* 32-bit mult ovf th for base 26. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 27u), /* 32-bit mult ovf th for base 27. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 28u), /* 32-bit mult ovf th for base 28. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 29u), /* 32-bit mult ovf th for base 29. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 30u), /* 32-bit mult ovf th for base 30. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 31u), /* 32-bit mult ovf th for base 31. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 32u), /* 32-bit mult ovf th for base 32. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 33u), /* 32-bit mult ovf th for base 33. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 34u), /* 32-bit mult ovf th for base 34. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 35u), /* 32-bit mult ovf th for base 35. */
- (CPU_INT32U)(DEF_INT_32U_MAX_VAL / 36u) /* 32-bit mult ovf th for base 36. */
- };
- /*
- *********************************************************************************************************
- * LOCAL GLOBAL VARIABLES
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * LOCAL FUNCTION PROTOTYPES
- *********************************************************************************************************
- */
- static CPU_CHAR *Str_FmtNbr_Int32 ( CPU_INT32U nbr,
- CPU_INT08U nbr_dig,
- CPU_INT08U nbr_base,
- CPU_BOOLEAN nbr_neg,
- CPU_CHAR lead_char,
- CPU_BOOLEAN lower_case,
- CPU_BOOLEAN nul,
- CPU_CHAR *pstr);
- static CPU_INT32U Str_ParseNbr_Int32(const CPU_CHAR *pstr,
- CPU_CHAR **pstr_next,
- CPU_INT08U nbr_base,
- CPU_BOOLEAN nbr_signed,
- CPU_BOOLEAN *pnbr_neg);
- /*
- *********************************************************************************************************
- * LOCAL CONFIGURATION ERRORS
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * Str_Len()
- *
- * Description : Calculate length of a string.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * Return(s) : Length of string; number of characters in string before terminating NULL character
- * (see Note #2b1).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strlen() : DESCRIPTION' states that :
- *
- * (1) "The strlen() function shall compute the number of bytes in the string to
- * which 's' ('pstr') points," ...
- * (2) "not including the terminating null byte."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strlen() : RETURN VALUE' states that :
- *
- * (1) "The strlen() function shall return the length of 's' ('pstr');" ...
- * (2) "no return value shall be reserved to indicate an error."
- *
- * (3) String length calculation terminates when :
- *
- * (a) String pointer points to NULL.
- * (1) String buffer overlaps with NULL address.
- * (2) String length calculated for string up to but NOT beyond or including
- * the NULL address.
- *
- * (b) Terminating NULL character found.
- * (1) String length calculated for string up to but NOT including
- * the NULL character (see Note #2a2).
- *********************************************************************************************************
- */
- CPU_SIZE_T Str_Len (const CPU_CHAR *pstr)
- {
- CPU_SIZE_T len;
- len = Str_Len_N(pstr,
- DEF_INT_CPU_U_MAX_VAL);
- return (len);
- }
- /*
- *********************************************************************************************************
- * Str_Len_N()
- *
- * Description : Calculate length of a string, up to a maximum number of characters.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * len_max Maximum number of characters to search (see Note #3c).
- *
- * Return(s) : Length of string; number of characters in string before terminating NULL character,
- * if terminating NULL character found (see Note #2b1).
- *
- * Requested maximum number of characters to search,
- * if terminating NULL character NOT found (see Note #3c).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strlen() : DESCRIPTION' states that :
- *
- * (1) "The strlen() function shall compute the number of bytes in the string to
- * which 's' ('pstr') points," ...
- * (2) "not including the terminating null byte."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strlen() : RETURN VALUE' states that :
- *
- * (1) "The strlen() function shall return the length of 's' ('pstr');" ...
- * (2) "no return value shall be reserved to indicate an error."
- *
- * (3) String length calculation terminates when :
- *
- * (a) String pointer points to NULL.
- * (1) String buffer overlaps with NULL address.
- * (2) String length calculated for string up to but NOT beyond or including
- * the NULL address.
- *
- * (b) Terminating NULL character found.
- * (1) String length calculated for string up to but NOT including
- * the NULL character (see Note #2a2).
- *
- * (c) 'len_max' number of characters searched.
- * (1) 'len_max' number of characters does NOT include the terminating NULL character.
- *********************************************************************************************************
- */
- CPU_SIZE_T Str_Len_N (const CPU_CHAR *pstr,
- CPU_SIZE_T len_max)
- {
- const CPU_CHAR *pstr_len;
- CPU_SIZE_T len;
- pstr_len = pstr;
- len = 0u;
- while (( pstr_len != (const CPU_CHAR *) 0 ) && /* Calc str len until NULL ptr (see Note #3a) ... */
- (*pstr_len != ( CPU_CHAR )'\0') && /* ... or NULL char found (see Note #3b) ... */
- ( len < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars srch'd (see Note #3c). */
- pstr_len++;
- len++;
- }
- return (len); /* Rtn str len (see Note #3b1). */
- }
- /*
- *********************************************************************************************************
- * Str_Copy()
- *
- * Description : Copy source string to destination string buffer.
- *
- * Argument(s) : pstr_dest Pointer to destination string buffer to receive source string copy (see Note #1a).
- *
- * pstr_src Pointer to source string to copy into destination string buffer (see Note #1b).
- *
- * Return(s) : Pointer to destination string, if NO error(s) [see Note #2b1].
- *
- * Pointer to NULL, otherwise (see Note #2b2A).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (1) Destination buffer size MUST be large enough to accommodate the entire source
- * string size including the terminating NULL character.
- *
- * (b) Source buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strcpy() : DESCRIPTION' states that :
- *
- * (1) "The strcpy() function shall copy the string pointed to by 's2' ('pstr_src')
- * ... into the array pointed to by 's1' ('pstr_dest')" ...
- * (2) "(including the terminating null byte)."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strcpy() : RETURN VALUE' states that :
- *
- * (1) "The strcpy() function shall return 's1' ('pstr_dest');" ...
- * (2) "no return value is reserved to indicate an error."
- * (A) #### This requirement is intentionally NOT implemented in order to return
- * NULL for any error(s).
- *
- * (c) IEEE Std 1003.1, 2004 Edition, Section 'strcpy() : DESCRIPTION' states that "if
- * copying takes place between objects that overlap, the behavior is undefined".
- *
- * (3) String copy terminates when :
- *
- * (a) Destination/Source string pointer(s) are passed NULL pointers.
- * (1) No string copy performed; NULL pointer returned.
- *
- * (b) Destination/Source string pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Source string's terminating NULL character found.
- * (1) Entire source string copied into destination string buffer (see Note #2a).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Copy ( CPU_CHAR *pstr_dest,
- const CPU_CHAR *pstr_src)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Copy_N(pstr_dest,
- pstr_src,
- DEF_INT_CPU_U_MAX_VAL);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Copy_N()
- *
- * Description : Copy source string to destination string buffer, up to a maximum number of characters.
- *
- * Argument(s) : pstr_dest Pointer to destination string buffer to receive source string copy (see Note #1a).
- *
- * pstr_src Pointer to source string to copy into destination string buffer (see Note #1b).
- *
- * len_max Maximum number of characters to copy (see Notes #2a2 & #3d).
- *
- * Return(s) : Pointer to destination string, if NO error(s) [see Note #2b1].
- *
- * Pointer to NULL, otherwise (see Note #2b2A).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (1) Destination buffer size MUST be large enough to accommodate the entire source
- * string size including the terminating NULL character.
- *
- * (b) Source string buffer NOT modified.
- *
- * (2) (a) (1) IEEE Std 1003.1, 2004 Edition, Section 'strncpy() : DESCRIPTION' states that :
- *
- * (A) "The strncpy() function shall copy ... the array pointed to by 's2'
- * ('pstr_src') to the array pointed to by 's1' ('pstr_dest')"; ...
- * (B) but "not more than 'n' ('len_max') bytes" ...
- * (C) & "(bytes that follow a null byte are not copied)".
- *
- * (2) (A) IEEE Std 1003.1, 2004 Edition, Section 'strncpy() : DESCRIPTION' adds that
- * "if the array pointed to by 's2' ('pstr_src') is a string that is shorter
- * than 'n' ('len_max') bytes, null bytes shall be appended to the copy in
- * the array pointed to by 's1' ('pstr_dest'), until 'n' ('len_max') bytes
- * in all are written."
- *
- * (1) #### Since Str_Copy() limits the maximum number of characters to copy
- * via Str_Copy_N() by the CPU's maximum number of addressable characters,
- * this requirement is intentionally NOT implemented to avoid appending
- * a potentially large number of unnecessary terminating NULL characters.
- *
- * (B) IEEE Std 1003.1, 2004 Edition, Section 'strncpy() : APPLICATION USAGE' also
- * states that "if there is no null byte in the first 'n' ('len_max') bytes of
- * the array pointed to by 's2' ('pstr_src'), the result is not null-terminated".
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strncpy() : RETURN VALUE' states that :
- *
- * (1) "The strncpy() function shall return 's1' ('pstr_dest');" ...
- * (2) "no return value is reserved to indicate an error."
- * (A) #### This requirement is intentionally ignored in order to return NULL
- * for any error(s).
- *
- * (c) IEEE Std 1003.1, 2004 Edition, Section 'strncpy() : DESCRIPTION' states that "if
- * copying takes place between objects that overlap, the behavior is undefined".
- *
- * (3) String copy terminates when :
- *
- * (a) Destination/Source string pointer(s) are passed NULL pointers.
- * (1) No string copy performed; NULL pointer returned.
- *
- * (b) Destination/Source string pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Source string's terminating NULL character found.
- * (1) Entire source string copied into destination string buffer (see Note #2a1A).
- *
- * (d) 'len_max' number of characters copied.
- * (1) 'len_max' number of characters MAY include the terminating NULL character
- * (see Note #2a1C).
- * (2) Null copies allowed (i.e. zero-length copies).
- * (A) No string copy performed; destination string returned (see Note #2b1).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Copy_N ( CPU_CHAR *pstr_dest,
- const CPU_CHAR *pstr_src,
- CPU_SIZE_T len_max)
- {
- CPU_CHAR *pstr_copy_dest;
- const CPU_CHAR *pstr_copy_src;
- CPU_SIZE_T len_copy;
- /* Rtn NULL if str ptr(s) NULL (see Note #3a1). */
- if (pstr_dest == (CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- if (pstr_src == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- pstr_copy_dest = pstr_dest;
- pstr_copy_src = pstr_src;
- len_copy = 0u;
- while (( pstr_copy_dest != ( CPU_CHAR *) 0 ) && /* Copy str until NULL ptr(s) [see Note #3b] ... */
- ( pstr_copy_src != (const CPU_CHAR *) 0 ) &&
- (*pstr_copy_src != ( CPU_CHAR )'\0') && /* ... or NULL char found (see Note #3c); ... */
- ( len_copy < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars copied (see Note #3d). */
- *pstr_copy_dest = *pstr_copy_src;
- pstr_copy_dest++;
- pstr_copy_src++;
- len_copy++;
- }
- /* Rtn NULL if NULL ptr(s) found (see Note #3b1). */
- if ((pstr_copy_dest == ( CPU_CHAR *)0) ||
- (pstr_copy_src == (const CPU_CHAR *)0)) {
- return ((CPU_CHAR *)0);
- }
- if (len_copy < len_max) { /* If copy str len < max buf len (see Note #2a2A), ... */
- *pstr_copy_dest = (CPU_CHAR)'\0'; /* ... copy NULL char (see Note #3c1). */
- }
- return (pstr_dest); /* Rtn ptr to dest str (see Note #2b1). */
- }
- /*
- *********************************************************************************************************
- * Str_Cat()
- *
- * Description : Append concatenation string to destination string.
- *
- * Argument(s) : pstr_dest Pointer to destination string to append concatenation string (see Note #1a).
- *
- * pstr_cat Pointer to concatenation string to append to destination string (see Note #1b).
- *
- * Return(s) : Pointer to destination string, if NO error(s) [see Note #2b1].
- *
- * Pointer to NULL, otherwise (see Note #2b2A).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (1) Destination buffer size MUST be large enough to accommodate the entire
- * concatenated string size including the terminating NULL character.
- *
- * (b) Concatenation string buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strcat() : DESCRIPTION' states that :
- *
- * (1) "The strcat() function shall append a copy of the string pointed to by 's2'
- * ('pstr_cat') ... to the end of the string pointed to by 's1' ('pstr_dest')."
- *
- * (2) (A) "The initial byte of 's2' ('pstr_cat') overwrites the null byte at the
- * end of 's1' ('pstr_dest')."
- * (B) A "terminating null byte" is appended at the end of the concatenated
- * destination strings.
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strcat() : RETURN VALUE' states that :
- *
- * (1) "The strcat() function shall return 's1' ('pstr_dest');" ...
- * (2) "no return value shall be reserved to indicate an error."
- * (A) #### This requirement is intentionally NOT implemented in order to return
- * NULL for any error(s).
- *
- * (c) IEEE Std 1003.1, 2004 Edition, Section 'strcat() : DESCRIPTION' states that "if
- * copying takes place between objects that overlap, the behavior is undefined."
- *
- * (3) String concatenation terminates when :
- *
- * (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
- * (1) No string concatenation performed; NULL pointer returned.
- *
- * (b) Destination/Concatenation string pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Concatenation string's terminating NULL character found.
- * (1) Entire concatenation string appended to destination string (see Note #2a1).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Cat ( CPU_CHAR *pstr_dest,
- const CPU_CHAR *pstr_cat)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Cat_N(pstr_dest,
- pstr_cat,
- DEF_INT_CPU_U_MAX_VAL);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Cat_N()
- *
- * Description : Append concatenation string to destination string, up to a maximum number of characters.
- *
- * Argument(s) : pstr_dest Pointer to destination string to append concatenation string (see Note #1a).
- *
- * pstr_cat Pointer to concatenation string to append to destination string (see Note #1b).
- *
- * len_max Maximum number of characters to concatenate (see Notes #2a1B & #3d).
- *
- * Return(s) : Pointer to destination string, if NO error(s) [see Note #2b1].
- *
- * Pointer to NULL, otherwise (see Note #2b2A).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (1) Destination buffer size MUST be large enough to accommodate the entire
- * concatenated string size including the terminating NULL character.
- *
- * (b) Concatenation string buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strncat() : DESCRIPTION' states that :
- *
- * (1) (A) "The strncat() function shall append ... the array pointed to by 's2'
- * ('pstr_cat') to the end of the string pointed to by 's1' ('pstr_dest')" ...
- * (B) but "not more than 'n' ('len_max') bytes".
- *
- * (2) (A) "The initial byte of 's2' ('pstr_cat') overwrites the null byte at the
- * end of 's1' ('pstr_dest')."
- * (B) "(a null byte and bytes that follow it are not appended)."
- * (C) "A terminating null byte is always appended to the result."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strncat() : RETURN VALUE' states that :
- *
- * (1) "The strncat() function shall return 's1' ('pstr_dest');" ...
- * (2) "no return value shall be reserved to indicate an error."
- * (A) #### This requirement is intentionally NOT implemented in order to return
- * NULL for any error(s).
- *
- * (c) IEEE Std 1003.1, 2004 Edition, Section 'strncat() : DESCRIPTION' states that "if
- * copying takes place between objects that overlap, the behavior is undefined."
- *
- * (3) String concatenation terminates when :
- *
- * (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
- * (1) No string concatenation performed; NULL pointer returned.
- *
- * (b) Destination/Concatenation string pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Concatenation string's terminating NULL character found.
- * (1) Entire concatenation string appended to destination string (see Note #2a1A).
- *
- * (d) 'len_max' number of characters concatenated.
- *
- * (1) 'len_max' number of characters does NOT include the terminating NULL character
- * (see Note #2a2).
- *
- * (2) Null concatenations allowed (i.e. zero-length concatenations).
- * (A) No string concatenation performed; destination string returned
- * (see Note #2b1).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Cat_N ( CPU_CHAR *pstr_dest,
- const CPU_CHAR *pstr_cat,
- CPU_SIZE_T len_max)
- {
- CPU_CHAR *pstr_cat_dest;
- const CPU_CHAR *pstr_cat_src;
- CPU_SIZE_T len_cat;
- /* Rtn NULL if str ptr(s) NULL (see Note #3a1). */
- if (pstr_dest == (CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- if (pstr_cat == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- if (len_max < 1) { /* Rtn dest str if cat len = 0 (see Note #3d2A). */
- return ((CPU_CHAR *)pstr_dest);
- }
- pstr_cat_dest = pstr_dest;
- while (( pstr_cat_dest != (CPU_CHAR *) 0 ) && /* Adv to end of cur dest str until NULL ptr ... */
- (*pstr_cat_dest != (CPU_CHAR )'\0')) { /* ... or NULL char found.. */
- pstr_cat_dest++;
- }
- if (pstr_cat_dest == (CPU_CHAR *)0) { /* Rtn NULL if NULL ptr found (see Note #3b1). */
- return ((CPU_CHAR *)0);
- }
- pstr_cat_src = pstr_cat;
- len_cat = 0u;
- while (( pstr_cat_dest != ( CPU_CHAR *) 0 ) && /* Cat str until NULL ptr(s) [see Note #3b] ... */
- ( pstr_cat_src != (const CPU_CHAR *) 0 ) &&
- (*pstr_cat_src != ( CPU_CHAR )'\0') && /* ... or NULL char found (see Note #3c); ... */
- ( len_cat < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars cat'd (see Note #3d). */
- *pstr_cat_dest = *pstr_cat_src;
- pstr_cat_dest++;
- pstr_cat_src++;
- len_cat++;
- }
- /* Rtn NULL if NULL ptr(s) found (see Note #3b1). */
- if ((pstr_cat_dest == ( CPU_CHAR *)0) ||
- (pstr_cat_src == (const CPU_CHAR *)0)) {
- return ((CPU_CHAR *)0);
- }
- *pstr_cat_dest = (CPU_CHAR)'\0'; /* Append NULL char (see Note #2a2C). */
- return (pstr_dest); /* Rtn ptr to dest str (see Note #2b1). */
- }
- /*
- *********************************************************************************************************
- * Str_Cmp()
- *
- * Description : Determine if two strings are identical.
- *
- * Argument(s) : p1_str Pointer to first string (see Note #1).
- *
- * p2_str Pointer to second string (see Note #1).
- *
- * Return(s) : 0, if strings are identical (see Notes #3a1A, #3a2A, & #3b).
- *
- * Negative value, if 'p1_str' is less than 'p2_str' (see Notes #3a1B1, #3a2B1, & #3c).
- *
- * Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #3a1B2, #3a2B2, & #3c).
- *
- * See also Note #2b.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strcmp() : DESCRIPTION' states that "the
- * strcmp() function shall compare the string pointed to by 's1' ('p1_str') to the
- * string pointed to by 's2' ('p2_str)".
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strcmp() : RETURN VALUE' states that
- * "upon successful completion, strcmp() shall return an integer greater than,
- * equal to, or less than 0".
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strcmp() : DESCRIPTION' adds that "the
- * sign of a non-zero return value shall be determined by the sign of the difference
- * between the values of the first pair of bytes ... that differ in the strings
- * being compared".
- *
- * (3) String comparison terminates when :
- *
- * (a) (1) (A) BOTH string pointer(s) are passed NULL pointers.
- * (1) NULL strings identical; 0 returned.
- *
- * (B) (1) 'p1_str' passed a NULL pointer.
- * (a) Return negative value of character pointed to by 'p2_str'.
- *
- * (2) 'p2_str' passed a NULL pointer.
- * (a) Return positive value of character pointed to by 'p1_str'.
- *
- * (2) (A) BOTH strings point to NULL.
- * (1) Strings overlap with NULL address.
- * (2) Strings identical up to but NOT beyond or including the NULL address;
- * 0 returned.
- *
- * (B) (1) 'p1_str_cmp_next' points to NULL.
- * (a) 'p1_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return negative value of character pointed to by 'p2_str_cmp_next'.
- *
- * (2) 'p2_str_cmp_next' points to NULL.
- * (a) 'p2_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return positive value of character pointed to by 'p1_str_cmp_next'.
- *
- * (b) Terminating NULL character found in both strings.
- * (1) Strings identical; 0 returned.
- * (2) Only one NULL character test required in conditional since previous condition
- * tested character equality.
- *
- * (c) Non-matching characters found.
- * (1) Return signed-integer difference of the character pointed to by 'p2_str'
- * from the character pointed to by 'p1_str'.
- *
- * (4) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
- * return value, 'CPU_CHAR' native data type size MUST be 8-bit.
- *********************************************************************************************************
- */
- CPU_INT16S Str_Cmp (const CPU_CHAR *p1_str,
- const CPU_CHAR *p2_str)
- {
- CPU_INT16S cmp_val;
- cmp_val = Str_Cmp_N(p1_str,
- p2_str,
- DEF_INT_CPU_U_MAX_VAL);
- return (cmp_val);
- }
- /*
- *********************************************************************************************************
- * Str_Cmp_N()
- *
- * Description : Determine if two strings are identical for up to a maximum number of characters.
- *
- * Argument(s) : p1_str Pointer to first string (see Note #1).
- *
- * p2_str Pointer to second string (see Note #1).
- *
- * len_max Maximum number of characters to compare (see Note #3d).
- *
- * Return(s) : 0, if strings are identical (see Notes #3a1A, #3a2A, #3b, & #3d).
- *
- * Negative value, if 'p1_str' is less than 'p2_str' (see Notes #3a1B1, #3a2B1, & #3c).
- *
- * Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #3a1B2, #3a2B2, & #3c).
- *
- * See also Note #2b.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strncmp() : DESCRIPTION' states that :
- *
- * (1) "The strncmp() function shall compare ... the array pointed to by 's1' ('p1_str')
- * to the array pointed to by 's2' ('p2_str)" ...
- * (2) but "not more than 'n' ('len_max') bytes" of either array.
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strncmp() : RETURN VALUE' states that
- * "upon successful completion, strncmp() shall return an integer greater than,
- * equal to, or less than 0".
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strncmp() : DESCRIPTION' adds that
- * "the sign of a non-zero return value is determined by the sign of the difference
- * between the values of the first pair of bytes ... that differ in the strings
- * being compared".
- *
- * (3) String comparison terminates when :
- *
- * (a) (1) (A) BOTH string pointer(s) are passed NULL pointers.
- * (1) NULL strings identical; 0 returned.
- *
- * (B) (1) 'p1_str' passed a NULL pointer.
- * (a) Return negative value of character pointed to by 'p2_str'.
- *
- * (2) 'p2_str' passed a NULL pointer.
- * (a) Return positive value of character pointed to by 'p1_str'.
- *
- * (2) (A) BOTH strings point to NULL.
- * (1) Strings overlap with NULL address.
- * (2) Strings identical up to but NOT beyond or including the NULL address;
- * 0 returned.
- *
- * (B) (1) 'p1_str_cmp_next' points to NULL.
- * (a) 'p1_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return negative value of character pointed to by 'p2_str_cmp_next'.
- *
- * (2) 'p2_str_cmp_next' points to NULL.
- * (a) 'p2_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return positive value of character pointed to by 'p1_str_cmp_next'.
- *
- * (b) Terminating NULL character found in both strings.
- * (1) Strings identical; 0 returned.
- * (2) Only one NULL character test required in conditional since previous condition
- * tested character equality.
- *
- * (c) Non-matching characters found.
- * (1) Return signed-integer difference of the character pointed to by 'p2_str'
- * from the character pointed to by 'p1_str'.
- *
- * (d) (1) 'len_max' passed a zero length.
- * (A) Zero-length strings identical; 0 returned.
- *
- * (2) First 'len_max' number of characters identical.
- * (A) Strings identical; 0 returned.
- *
- * See also Note #2a2.
- *
- * (4) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
- * return value, 'CPU_CHAR' native data type size MUST be 8-bit.
- *********************************************************************************************************
- */
- CPU_INT16S Str_Cmp_N (const CPU_CHAR *p1_str,
- const CPU_CHAR *p2_str,
- CPU_SIZE_T len_max)
- {
- const CPU_CHAR *p1_str_cmp;
- const CPU_CHAR *p2_str_cmp;
- const CPU_CHAR *p1_str_cmp_next;
- const CPU_CHAR *p2_str_cmp_next;
- CPU_INT16S cmp_val;
- CPU_SIZE_T cmp_len;
- if (len_max < 1) { /* If cmp len = 0, rtn 0 (see Note #3d1A). */
- return (0);
- }
- if (p1_str == (const CPU_CHAR *)0) {
- if (p2_str == (const CPU_CHAR *)0) {
- return (0); /* If BOTH str ptrs NULL, rtn 0 (see Note #3a1A). */
- }
- cmp_val = (CPU_INT16S)((CPU_INT16S)0 - (CPU_INT16S)(*p2_str));
- return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #3a1B1).*/
- }
- if (p2_str == (const CPU_CHAR *)0) {
- cmp_val = (CPU_INT16S)(*p1_str);
- return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #3a1B2).*/
- }
- p1_str_cmp = p1_str;
- p2_str_cmp = p2_str;
- p1_str_cmp_next = p1_str_cmp;
- p2_str_cmp_next = p2_str_cmp;
- p1_str_cmp_next++;
- p2_str_cmp_next++;
- cmp_len = 0u;
- while ((*p1_str_cmp == *p2_str_cmp) && /* Cmp strs until non-matching chars (see Note #3c) ... */
- (*p1_str_cmp != ( CPU_CHAR )'\0') && /* ... or NULL chars (see Note #3b) ... */
- ( p1_str_cmp_next != (const CPU_CHAR *) 0 ) && /* ... or NULL ptr(s) found (see Note #3a2). */
- ( p2_str_cmp_next != (const CPU_CHAR *) 0 ) &&
- ( cmp_len < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars cmp'd (see Note #3d2). */
- p1_str_cmp++;
- p2_str_cmp++;
- p1_str_cmp_next++;
- p2_str_cmp_next++;
- cmp_len++;
- }
- if (cmp_len == len_max) { /* If strs identical for max len nbr of chars, ... */
- return (0); /* ... rtn 0 (see Note #3d2A). */
- }
- if (*p1_str_cmp != *p2_str_cmp) { /* If strs NOT identical, ... */
- /* ... calc & rtn char diff (see Note #3c1). */
- cmp_val = (CPU_INT16S)((CPU_INT16S)(*p1_str_cmp) - (CPU_INT16S)(*p2_str_cmp));
- } else if (*p1_str_cmp == (CPU_CHAR)'\0') { /* If NULL char(s) found, ... */
- cmp_val = (CPU_INT16S)0; /* ... strs identical; rtn 0 (see Note #3b). */
- } else {
- if (p1_str_cmp_next == (const CPU_CHAR *)0) {
- if (p2_str_cmp_next == (const CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */
- cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #3a2A). */
- } else { /* If p1_str_cmp_next NULL, ... */
- /* ... rtn neg p2_str_cmp_next val (see Note #3a2B1). */
- cmp_val = (CPU_INT16S)((CPU_INT16S)0 - (CPU_INT16S)(*p2_str_cmp_next));
- }
- } else { /* If p2_str_cmp_next NULL, ... */
- cmp_val = (CPU_INT16S)(*p1_str_cmp_next); /* ... rtn pos p1_str_cmp_next val (see Note #3a2B2). */
- }
- }
- return (cmp_val);
- }
- /*
- *********************************************************************************************************
- * Str_CmpIgnoreCase()
- *
- * Description : Determine if two strings are identical, ignoring case.
- *
- * Argument(s) : p1_str Pointer to first string (see Note #1).
- *
- * p2_str Pointer to second string (see Note #1).
- *
- * Return(s) : 0, if strings are identical (see Notes #3a1A, #3a2A, & #3b).
- *
- * Negative value, if 'p1_str' is less than 'p2_str' (see Notes #3a1B1, #3a2B1, & #3c).
- *
- * Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #3a1B2, #3a2B2, & #3c).
- *
- * See also Note #2b.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strcasecmp() : DESCRIPTION' states that :
- *
- * (1) (A) "The strcasecmp() function shall compare ... the string pointed to by 's1'
- * ('p1_str') to the string pointed to by 's2' ('p2_str')" ...
- * (B) "ignoring differences in case".
- *
- * (2) "strcasecmp() ... shall behave as if the strings had been converted to lowercase
- * and then a byte comparison performed."
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strcasecmp() : RETURN VALUE' states that
- * "upon successful completion, strcasecmp() shall return an integer greater than,
- * equal to, or less than 0".
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strcmp() : DESCRIPTION' adds that "the
- * sign of a non-zero return value shall be determined by the sign of the difference
- * between the values of the first pair of bytes ... that differ in the strings
- * being compared".
- *
- * (3) String comparison terminates when :
- *
- * (a) (1) (A) BOTH string pointer(s) are passed NULL pointers.
- * (1) NULL strings identical; 0 returned.
- *
- * (B) (1) 'p1_str' passed a NULL pointer.
- * (a) Return negative value of character pointed to by 'p2_str', converted
- * to lower case (see Note #2a2).
- *
- * (2) 'p2_str' passed a NULL pointer.
- * (a) Return positive value of character pointed to by 'p1_str', converted
- * to lower case (see Note #2a2).
- *
- * (2) (A) BOTH strings point to NULL.
- * (1) Strings overlap with NULL address.
- * (2) Strings identical up to but NOT beyond or including the NULL address;
- * 0 returned.
- *
- * (B) (1) 'p1_str_cmp_next' points to NULL.
- * (a) 'p1_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return negative value of character pointed to by 'p2_str_cmp_next',
- * converted to lower case (see Note #2a2).
- *
- * (2) 'p2_str_cmp_next' points to NULL.
- * (a) 'p2_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return positive value of character pointed to by 'p1_str_cmp_next',
- * converted to lower case (see Note #2a2).
- *
- * (b) Terminating NULL character found in both strings.
- * (1) Strings identical; 0 returned.
- * (2) Only one NULL character test required in conditional since previous condition
- * tested character equality.
- *
- * (c) Non-matching characters found.
- * (1) Return signed-integer difference of the character pointed to by 'p2_str',
- * converted to lower case, from the character pointed to by 'p1_str', converted
- * to lower case.
- *
- * (4) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
- * return value, 'CPU_CHAR' native data type size MUST be 8-bit.
- *********************************************************************************************************
- */
- CPU_INT16S Str_CmpIgnoreCase (const CPU_CHAR *p1_str,
- const CPU_CHAR *p2_str)
- {
- CPU_INT16S cmp_val;
- cmp_val = Str_CmpIgnoreCase_N(p1_str,
- p2_str,
- DEF_INT_CPU_U_MAX_VAL);
- return (cmp_val);
- }
- /*
- *********************************************************************************************************
- * Str_CmpIgnoreCase_N()
- *
- * Description : Determine if two strings are identical for up to a maximum number of characters,
- * ignoring case.
- *
- * Argument(s) : p1_str Pointer to first string (see Note #1).
- *
- * p2_str Pointer to second string (see Note #1).
- *
- * len_max Maximum number of characters to compare (see Note #3d).
- *
- * Return(s) : 0, if strings are identical (see Notes #3a1A, #3a2A, #3b, & #3d).
- *
- * Negative value, if 'p1_str' is less than 'p2_str' (see Notes #3a1B1, #3a2B1, & #3c).
- *
- * Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #3a1B2, #3a2B2, & #3c).
- *
- * See also Note #2b.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strncasecmp() : DESCRIPTION' states that :
- *
- * (1) (A) "The strncasecmp() function shall compare ... the string pointed to by 's1'
- * ('p1_str') to the string pointed to by 's2' ('p2_str')" ...
- * (B) "ignoring differences in case" ...
- * (C) but "not more than 'n' ('len_max') bytes" of either string.
- *
- * (2) "strncasecmp() shall behave as if the strings had been converted to lowercase
- * and then a byte comparison performed."
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strncasecmp() : RETURN VALUE' states that
- * "upon successful completion, strncasecmp() shall return an integer greater than,
- * equal to, or less than 0".
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strcmp() : DESCRIPTION' adds that "the
- * sign of a non-zero return value shall be determined by the sign of the difference
- * between the values of the first pair of bytes ... that differ in the strings
- * being compared".
- *
- * (3) String comparison terminates when :
- *
- * (a) (1) (A) BOTH string pointer(s) are passed NULL pointers.
- * (1) NULL strings identical; 0 returned.
- *
- * (B) (1) 'p1_str' passed a NULL pointer.
- * (a) Return negative value of character pointed to by 'p2_str', converted
- * to lower case (see Note #2a2).
- *
- * (2) 'p2_str' passed a NULL pointer.
- * (a) Return positive value of character pointed to by 'p1_str', converted
- * to lower case (see Note #2a2).
- *
- * (2) (A) BOTH strings point to NULL.
- * (1) Strings overlap with NULL address.
- * (2) Strings identical up to but NOT beyond or including the NULL address;
- * 0 returned.
- *
- * (B) (1) 'p1_str_cmp_next' points to NULL.
- * (a) 'p1_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return negative value of character pointed to by 'p2_str_cmp_next',
- * converted to lower case (see Note #2a2).
- *
- * (2) 'p2_str_cmp_next' points to NULL.
- * (a) 'p2_str' overlaps with NULL address.
- * (b) Strings compared up to but NOT beyond or including the NULL address.
- * (c) Return positive value of character pointed to by 'p1_str_cmp_next',
- * converted to lower case (see Note #2a2).
- *
- * (b) Terminating NULL character found in both strings.
- * (1) Strings identical; 0 returned.
- * (2) Only one NULL character test required in conditional since previous condition
- * tested character equality.
- *
- * (c) Non-matching characters found.
- * (1) Return signed-integer difference of the character pointed to by 'p2_str',
- * converted to lower case, from the character pointed to by 'p1_str', converted
- * to lower case.
- *
- * (d) (1) 'len_max' passed a zero length.
- * (A) Zero-length strings identical; 0 returned.
- *
- * (2) First 'len_max' number of characters identical.
- * (A) Strings identical; 0 returned.
- *
- * See also Note #2a1C.
- *$PAGE*
- * (4) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
- * return value, 'CPU_CHAR' native data type size MUST be 8-bit.
- *********************************************************************************************************
- */
- CPU_INT16S Str_CmpIgnoreCase_N (const CPU_CHAR *p1_str,
- const CPU_CHAR *p2_str,
- CPU_SIZE_T len_max)
- {
- const CPU_CHAR *p1_str_cmp;
- const CPU_CHAR *p2_str_cmp;
- const CPU_CHAR *p1_str_cmp_next;
- const CPU_CHAR *p2_str_cmp_next;
- CPU_CHAR char_1;
- CPU_CHAR char_2;
- CPU_INT16S cmp_val;
- CPU_SIZE_T cmp_len;
- if (len_max < 1) { /* If cmp len = 0, rtn 0 (see Note #3d1A). */
- return (0);
- }
- if (p1_str == (const CPU_CHAR *)0) {
- if (p2_str == (const CPU_CHAR *)0) {
- return (0); /* If BOTH str ptrs NULL, rtn 0 (see Note #3a1A). */
- }
- char_2 = ASCII_ToLower(*p2_str);
- cmp_val = (CPU_INT16S)((CPU_INT16S)0 - (CPU_INT16S)char_2);
- return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #3a1B1).*/
- }
- if (p2_str == (const CPU_CHAR *)0) {
- char_1 = ASCII_ToLower(*p1_str);
- cmp_val = (CPU_INT16S)char_1;
- return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #3a1B2).*/
- }
- p1_str_cmp = p1_str;
- p2_str_cmp = p2_str;
- p1_str_cmp_next = p1_str_cmp;
- p2_str_cmp_next = p2_str_cmp;
- p1_str_cmp_next++;
- p2_str_cmp_next++;
- char_1 = ASCII_ToLower(*p1_str_cmp);
- char_2 = ASCII_ToLower(*p2_str_cmp);
- cmp_len = 0u;
- while (( char_1 == char_2) && /* Cmp strs until non-matching chars (see Note #3c) ... */
- (*p1_str_cmp != ( CPU_CHAR )'\0') && /* ... or NULL chars (see Note #3b) ... */
- ( p1_str_cmp_next != (const CPU_CHAR *) 0 ) && /* ... or NULL ptr(s) found (see Note #3a2). */
- ( p2_str_cmp_next != (const CPU_CHAR *) 0 ) &&
- ( cmp_len < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars cmp'd (see Note #3d2). */
- p1_str_cmp++;
- p2_str_cmp++;
- p1_str_cmp_next++;
- p2_str_cmp_next++;
- cmp_len++;
- char_1 = ASCII_ToLower(*p1_str_cmp);
- char_2 = ASCII_ToLower(*p2_str_cmp);
- }
- if (cmp_len == len_max) { /* If strs identical for max len nbr of chars, ... */
- return (0); /* ... rtn 0 (see Note #3d2A). */
- }
- if (char_1 != char_2) { /* If strs NOT identical, ... */
- /* ... calc & rtn char diff (see Note #3c1). */
- cmp_val = (CPU_INT16S)((CPU_INT16S)char_1 - (CPU_INT16S)char_2);
- } else if (char_1 == (CPU_CHAR)'\0') { /* If NULL char(s) found, ... */
- cmp_val = (CPU_INT16S)0; /* ... strs identical; rtn 0 (see Note #3b). */
- } else {
- if (p1_str_cmp_next == (const CPU_CHAR *)0) {
- if (p2_str_cmp_next == (const CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */
- cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #3a2A). */
- } else { /* If p1_str_cmp_next NULL, ... */
- char_2 = ASCII_ToLower(*p2_str_cmp_next);
- /* ... rtn neg p2_str_cmp_next val (see Note #3a2B1). */
- cmp_val = (CPU_INT16S)((CPU_INT16S)0 - (CPU_INT16S)char_2);
- }
- } else { /* If p2_str_cmp_next NULL, ... */
- char_1 = ASCII_ToLower(*p1_str_cmp_next);
- cmp_val = (CPU_INT16S)char_1; /* ... rtn pos p1_str_cmp_next val (see Note #3a2B2). */
- }
- }
- return (cmp_val);
- }
- /*
- *********************************************************************************************************
- * Str_Char()
- *
- * Description : Search string for first occurrence of specific character.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * srch_char Search character.
- *
- * Return(s) : Pointer to first occurrence of search character in string, if any (see Note #2b1).
- *
- * Pointer to NULL, otherwise (see Note #2b2).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strchr() : DESCRIPTION' states that :
- *
- * (1) "The strchr() function shall locate the first occurrence of 'c' ('srch_char')
- * ... in the string pointed to by 's' ('pstr')."
- * (2) "The terminating null byte is considered to be part of the string."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strchr() : RETURN VALUE' states that
- * "upon completion, strchr() shall return" :
- *
- * (1) "a pointer to the byte," ...
- * (2) "or a null pointer if the byte was not found."
- * (A) #### Although NO strchr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (3) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String's terminating NULL character found.
- * (1) Search character NOT found in search string; NULL pointer returned
- * (see Note #2b2).
- * (2) Applicable even if search character is the terminating NULL character
- * (see Note #2a2).
- *
- * (d) Search character found.
- * (1) Return pointer to first occurrence of search character in search string
- * (see Note #2a1).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char (const CPU_CHAR *pstr,
- CPU_CHAR srch_char)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Char_N(pstr,
- DEF_INT_CPU_U_MAX_VAL,
- srch_char);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Char_N()
- *
- * Description : Search string for first occurrence of specific character, up to a maximum number
- * of characters.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * len_max Maximum number of characters to search (see Notes #2c & #3e).
- *
- * srch_char Search character.
- *
- * Return(s) : Pointer to first occurrence of search character in string, if any (see Note #2b1).
- *
- * Pointer to NULL, otherwise (see Note #2b2).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strchr() : DESCRIPTION' states that :
- *
- * (1) "The strchr() function shall locate the first occurrence of 'c' ('srch_char')
- * ... in the string pointed to by 's' ('pstr')."
- * (2) "The terminating null byte is considered to be part of the string."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strchr() : RETURN VALUE' states that
- * "upon completion, strchr() shall return" :
- *
- * (1) "a pointer to the byte," ...
- * (2) "or a null pointer if the byte was not found."
- * (A) #### Although NO strchr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (c) Ideally, the 'len_max' argument would be the last argument in this function's
- * argument list for consistency with all other custom string library functions.
- * However, the 'len_max' argument is sequentially ordered as the second argument
- * to comply with most standard library's strnchr() argument list.
- *
- * (3) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String's terminating NULL character found.
- * (1) Search character NOT found in search string; NULL pointer returned
- * (see Note #2b2).
- * (2) Applicable even if search character is the terminating NULL character
- * (see Note #2a2).
- *
- * (d) Search character found.
- * (1) Return pointer to first occurrence of search character in search string
- * (see Note #2a1).
- *
- * (e) 'len_max' number of characters searched.
- * (1) Search character NOT found in search string within first 'len_max' number
- * of characters; NULL pointer returned.
- * (2) 'len_max' number of characters MAY include terminating NULL character
- * (see Note #2a2).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char_N (const CPU_CHAR *pstr,
- CPU_SIZE_T len_max,
- CPU_CHAR srch_char)
- {
- const CPU_CHAR *pstr_char;
- CPU_SIZE_T len_srch;
- if (pstr == (const CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #3a1). */
- return ((CPU_CHAR *)0);
- }
- if (len_max < 1) { /* Rtn NULL if srch len = 0 (see Note #3e1). */
- return ((CPU_CHAR *)0);
- }
- pstr_char = pstr;
- len_srch = 0u;
- while (( pstr_char != (const CPU_CHAR *) 0 ) && /* Srch str until NULL ptr [see Note #3b] ... */
- (*pstr_char != ( CPU_CHAR )'\0') && /* ... or NULL char (see Note #3c) ... */
- (*pstr_char != ( CPU_CHAR )srch_char) && /* ... or srch char found (see Note #3d); ... */
- ( len_srch < ( CPU_SIZE_T)len_max)) { /* ... or max nbr chars srch'd (see Note #3e). */
- pstr_char++;
- len_srch++;
- }
- if (pstr_char == (const CPU_CHAR *)0) { /* Rtn NULL if NULL ptr found (see Note #3b1). */
- return ((CPU_CHAR *)0);
- }
- if (len_srch >= len_max) { /* Rtn NULL if srch char NOT found ... */
- return ((CPU_CHAR *)0); /* ... within max nbr of chars (see Note #3e1). */
- }
- if (*pstr_char != srch_char) { /* Rtn NULL if srch char NOT found (see Note #3c1). */
- return ((CPU_CHAR *)0);
- }
- return ((CPU_CHAR *)pstr_char); /* Else rtn ptr to found srch char (see Note #3d1). */
- }
- /*
- *********************************************************************************************************
- * Str_Char_Last()
- *
- * Description : Search string for last occurrence of specific character.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * srch_char Search character.
- *
- * Return(s) : Pointer to last occurrence of search character in string, if any (see Note #2b1).
- *
- * Pointer to NULL, otherwise (see Note #2b2).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strrchr() : DESCRIPTION' states that :
- *
- * (1) "The strrchr() function shall locate the last occurrence of 'c' ('srch_char')
- * ... in the string pointed to by 's' ('pstr')."
- * (2) "The terminating null byte is considered to be part of the string."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strrchr() : RETURN VALUE' states that
- * "upon successful completion, strrchr() shall return" :
- *
- * (1) "a pointer to the byte" ...
- * (2) "or a null pointer if 'c' ('srch_char') does not occur in the string."
- * (A) #### Although NO strrchr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (3) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String searched from end to beginning.
- * (1) Search character NOT found in search string; NULL pointer returned.
- * (2) Applicable even if search character is the terminating NULL character
- * (see Note #2a2).
- *
- * (d) Search character found.
- * (1) Return pointer to last occurrence of search character in search string
- * (see Note #2a1).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char_Last (const CPU_CHAR *pstr,
- CPU_CHAR srch_char)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Char_Last_N(pstr,
- DEF_INT_CPU_U_MAX_VAL,
- srch_char);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Char_Last_N()
- *
- * Description : Search string for last occurrence of specific character, up to a maximum number
- * of characters.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * len_max Maximum number of characters to search (see Notes #2c & #3e).
- *
- * srch_char Search character.
- *
- * Return(s) : Pointer to last occurrence of search character in string, if any (see Note #2b1).
- *
- * Pointer to NULL, otherwise (see Note #2b2).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strrchr() : DESCRIPTION' states that :
- *
- * (1) "The strrchr() function shall locate the last occurrence of 'c' ('srch_char')
- * ... in the string pointed to by 's' ('pstr')."
- * (2) "The terminating null byte is considered to be part of the string."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strrchr() : RETURN VALUE' states that
- * "upon successful completion, strrchr() shall return" :
- *
- * (1) "a pointer to the byte" ...
- * (2) "or a null pointer if 'c' ('srch_char') does not occur in the string."
- * (A) #### Although NO strrchr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (c) Ideally, the 'len_max' argument would be the last argument in this function's
- * argument list for consistency with all other custom string library functions.
- * However, the 'len_max' argument is sequentially ordered as the second argument
- * to comply with most standard library's strnrchr() argument list.
- *
- * See also 'Str_Char_N() Note #2c'.
- *
- * (3) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String searched from end to beginning.
- * (1) Search character NOT found in search string; NULL pointer returned
- * (see Note #2b2).
- * (2) Applicable even if search character is the terminating NULL character
- * (see Note #2a2).
- *
- * (d) Search character found.
- * (1) Return pointer to last occurrence of search character in search string
- * (see Note #2a1).
- *
- * (e) 'len_max' number of characters searched.
- * (1) Search character NOT found in search string within last 'len_max' number
- * of characters; NULL pointer returned.
- * (2) 'len_max' number of characters MAY include terminating NULL character
- * (see Note #2a2).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char_Last_N (const CPU_CHAR *pstr,
- CPU_SIZE_T len_max,
- CPU_CHAR srch_char)
- {
- const CPU_CHAR *pstr_char;
- CPU_SIZE_T str_len_max;
- CPU_SIZE_T str_len;
- if (pstr == (const CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #3a1). */
- return ((CPU_CHAR *)0);
- }
- if (len_max < 1) { /* Rtn NULL if srch len = 0 (see Note #3e1). */
- return ((CPU_CHAR *)0);
- }
- pstr_char = pstr;
- str_len_max = len_max - sizeof((CPU_CHAR)'\0'); /* Str len adj'd for NULL char len. */
- str_len = Str_Len_N(pstr_char, str_len_max);
- pstr_char += str_len;
- if (pstr_char == (const CPU_CHAR *)0) { /* Rtn NULL if NULL ptr found (see Note #3b1). */
- return ((CPU_CHAR *)0);
- }
- while (( pstr_char != pstr) && /* Srch str from end until beginning (see Note #3c) ... */
- (*pstr_char != srch_char)) { /* ... until srch char found (see Note #3d). */
- pstr_char--;
- }
- if (*pstr_char != srch_char) { /* Rtn NULL if srch char NOT found (see Note #3c1). */
- return ((CPU_CHAR *)0);
- }
- return ((CPU_CHAR *)pstr_char); /* Else rtn ptr to found srch char (see Note #3d1). */
- }
- /*
- *********************************************************************************************************
- * Str_Char_Replace()
- *
- * Description : Search string for specific character and replace it by another specific character.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * char_srch Search character.
- *
- * char_replace Replace character.
- *
- * Return(s) : Pointer to string, if NO error(s).
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer modified.
- *
- * (2) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String's terminating NULL character found.
- * (1) Search character NOT found in search string; NULL pointer returned
- * (2) Applicable even if search character is the terminating NULL character
- *
- * (d) Search character found.
- * (1) Replace character found by the specified character.
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char_Replace (CPU_CHAR *pstr,
- CPU_CHAR char_srch,
- CPU_CHAR char_replace)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Char_Replace_N(pstr,
- char_srch,
- char_replace,
- DEF_INT_CPU_U_MAX_VAL);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Char_Replace_N()
- *
- * Description : Search string for specific character and replace it by another specific character, up to
- * a maximum number of characters.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * char_srch Search character.
- *
- * char_replace Replace character.
- *
- * len_max Maximum number of characters to search (see Notes #2c & #3e).
- *
- * Return(s) : Pointer to string, if NO error(s).
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer modified.
- *
- * (2) String search terminates when :
- *
- * (a) String pointer passed a NULL pointer.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer points to NULL.
- * (1) String overlaps with NULL address; NULL pointer returned.
- *
- * (c) String's terminating NULL character found.
- * (1) Search character NOT found in search string; NULL pointer returned
- * (2) Applicable even if search character is the terminating NULL character
- *
- * (d) Search character found.
- * (1) Replace character found by the specified character.
- *
- * (e) 'len_max' number of characters searched.
- * (1) Search character NOT found in search string within first 'len_max' number
- * of characters; NULL pointer returned.
- * (2) 'len_max' number of characters MAY include terminating NULL character
- * (see Note #2a2).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Char_Replace_N (CPU_CHAR *pstr,
- CPU_CHAR char_srch,
- CPU_CHAR char_replace,
- CPU_SIZE_T len_max)
- {
- CPU_CHAR *pstr_char;
- CPU_SIZE_T len;
- if (pstr == (const CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a1). */
- return ((CPU_CHAR *)0);
- }
- if (len_max < 1) { /* Rtn NULL if srch len = 0 (see Note #2e1). */
- return ((CPU_CHAR *)0);
- }
- pstr_char = pstr;
- len = len_max;
- while (( pstr_char != (const CPU_CHAR *)0) && /* Srch str until NULL ptr [see Note #2b] ... */
- (*pstr_char != ASCII_CHAR_NULL ) && /* ... or NULL char (see Note #2c) ... */
- ( len > 0)) { /* ... or max nbr chars srch'd (see Note #2e). */
- if (*pstr_char == char_srch) {
- *pstr_char = char_replace; /* Replace char if srch char is found. */
- }
- pstr_char++;
- len--;
- }
- return (pstr);
- }
- /*
- *********************************************************************************************************
- * Str_Str()
- *
- * Description : Search string for first occurence of a specific search string.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * pstr_srch Pointer to search string (see Note #1).
- *
- * Return(s) : Pointer to first occurrence of search string in string, if any (see Note #2b1A).
- *
- * Pointer to string, if NULL search string (see Note #2b2).
- *
- * Pointer to NULL, otherwise (see Note #2b1B).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strstr() : DESCRIPTION' states that :
- *
- * (1) "The strstr() function shall locate the first occurrence in the string
- * pointed to by 's1' ('pstr') of the sequence of bytes ... in the string
- * pointed to by 's2' ('pstr_srch')" ...
- * (2) "(excluding the terminating null byte)."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strstr() : RETURN VALUE' states that :
- *
- * (1) "Upon successful completion, strstr() shall return" :
- * (A) "a pointer to the located string" ...
- * (B) "or a null pointer if the string is not found."
- * (1) #### Although NO strstr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (2) "If 's2' ('pstr_srch') points to a string with zero length, the function
- * shall return 's1' ('pstr')."
- *
- * (3) String search terminates when :
- *
- * (a) String pointer(s) are passed NULL pointers.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Search string length equal to zero.
- * (1) No string search performed; string pointer returned (see Note #2b2).
- *
- * (d) Search string length greater than string length.
- * (1) No string search performed; NULL pointer returned (see Note #2b1B).
- *
- * (e) Entire string has been searched.
- * (1) Search string not found; NULL pointer returned (see Note #2b1B).
- *
- * (f) Search string found.
- * (1) Return pointer to first occurrence of search string in string (see Note #2b1A).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Str (const CPU_CHAR *pstr,
- const CPU_CHAR *pstr_srch)
- {
- CPU_CHAR *pstr_rtn;
- pstr_rtn = Str_Str_N(pstr,
- pstr_srch,
- DEF_INT_CPU_U_MAX_VAL);
- return (pstr_rtn);
- }
- /*
- *********************************************************************************************************
- * Str_Str_N()
- *
- * Description : Search string for first occurence of a specific search string, up to a maximum number
- * of characters.
- *
- * Argument(s) : pstr Pointer to string (see Note #1).
- *
- * pstr_srch Pointer to search string (see Note #1).
- *
- * len_max Maximum number of characters to search (see Note #3g).
- *
- * Return(s) : Pointer to first occurrence of search string in string, if any (see Note #2b1A).
- *
- * Pointer to string, if NULL search string (see Note #2b2).
- *
- * Pointer to NULL, otherwise (see Note #2b1B).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffers NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strstr() : DESCRIPTION' states that :
- *
- * (1) "The strstr() function shall locate the first occurrence in the string
- * pointed to by 's1' ('pstr') of the sequence of bytes ... in the string
- * pointed to by 's2' ('pstr_srch')" ...
- * (2) "(excluding the terminating null byte)."
- *
- * (b) IEEE Std 1003.1, 2004 Edition, Section 'strstr() : RETURN VALUE' states that :
- *
- * (1) "Upon successful completion, strstr() shall return" :
- * (A) "a pointer to the located string" ...
- * (B) "or a null pointer if the string is not found."
- * (1) #### Although NO strstr() specification states to return NULL for
- * any other reason(s), NULL is also returned for any error(s).
- *
- * (2) "If 's2' ('pstr_srch') points to a string with zero length, the function
- * shall return 's1' ('pstr')."
- *
- * (3) String search terminates when :
- *
- * (a) String pointer(s) are passed NULL pointers.
- * (1) No string search performed; NULL pointer returned.
- *
- * (b) String pointer(s) point to NULL.
- * (1) String buffer(s) overlap with NULL address; NULL pointer returned.
- *
- * (c) Search string length equal to zero.
- * (1) No string search performed; string pointer returned (see Note #2b2).
- *
- * (d) Search string length greater than string length.
- * (1) No string search performed; NULL pointer returned (see Note #2b1B).
- *
- * (e) Entire string has been searched.
- * (1) Search string not found; NULL pointer returned (see Note #2b1B).
- * (2) Maximum size of the search is defined as the subtraction of the
- * search string length from the string length.
- *
- * (f) Search string found.
- * (1) Return pointer to first occurrence of search string in string (see Note #2b1A).
- * (2) Search string found via Str_Cmp_N().
- *
- * (g) 'len_max' number of characters searched.
- * (1) 'len_max' number of characters does NOT include terminating NULL character
- * (see Note #2a2).
- *********************************************************************************************************
- */
- CPU_CHAR *Str_Str_N (const CPU_CHAR *pstr,
- const CPU_CHAR *pstr_srch,
- CPU_SIZE_T len_max)
- {
- CPU_SIZE_T str_len;
- CPU_SIZE_T str_len_srch;
- CPU_SIZE_T len_max_srch;
- CPU_SIZE_T srch_len;
- CPU_SIZE_T srch_ix;
- CPU_BOOLEAN srch_done;
- CPU_INT16S srch_cmp;
- const CPU_CHAR *pstr_str;
- const CPU_CHAR *pstr_srch_ix;
- /* Rtn NULL if str ptr(s) NULL (see Note #3a). */
- if (pstr == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- if (pstr_srch == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- if (len_max < 1) { /* Rtn NULL if srch len = 0 (see Note #3g). */
- return ((CPU_CHAR *)0);
- }
- /* Lim max srch str len (to chk > str len). */
- len_max_srch = (len_max < DEF_INT_CPU_U_MAX_VAL)
- ? (len_max + 1u) : DEF_INT_CPU_U_MAX_VAL;
- str_len = Str_Len_N(pstr, len_max);
- str_len_srch = Str_Len_N(pstr_srch, len_max_srch);
- if (str_len_srch < 1) { /* Rtn ptr to str if srch str len = 0 (see Note #2b2). */
- return ((CPU_CHAR *)pstr);
- }
- if (str_len_srch > str_len) { /* Rtn NULL if srch str len > str len (see Note #3d). */
- return ((CPU_CHAR *)0);
- }
- /* Rtn NULL if NULL ptr found (see Note #3b1). */
- pstr_str = pstr + str_len;
- if (pstr_str == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- pstr_str = pstr_srch + str_len_srch;
- if (pstr_str == (const CPU_CHAR *)0) {
- return ((CPU_CHAR *)0);
- }
- srch_len = str_len - str_len_srch; /* Calc srch len (see Note #3e2). */
- srch_ix = 0u;
- srch_done = DEF_NO;
- do {
- pstr_srch_ix = (const CPU_CHAR *)(pstr + srch_ix);
- srch_cmp = Str_Cmp_N(pstr_srch_ix, pstr_srch, str_len_srch);
- srch_done = (srch_cmp == 0) ? DEF_YES : DEF_NO;
- srch_ix++;
- } while ((srch_done == DEF_NO) && (srch_ix <= srch_len));
- if (srch_cmp != 0) { /* Rtn NULL if srch str NOT found (see Note #3e2). */
- return ((CPU_CHAR *)0);
- }
- return ((CPU_CHAR *)pstr_srch_ix); /* Else rtn ptr to found srch str (see Note #3f1). */
- }
- /*
- *********************************************************************************************************
- * Str_FmtNbr_Int32U()
- *
- * Description : Format 32-bit unsigned integer into a multi-digit character string.
- *
- * Argument(s) : nbr Number to format.
- *
- * nbr_dig Number of digits to format (see Note #1).
- *
- * The following may be used to specify the number of digits to format :
- *
- * DEF_INT_32U_NBR_DIG_MIN Minimum number of 32-bit unsigned digits
- * DEF_INT_32U_NBR_DIG_MAX Maximum number of 32-bit unsigned digits
- *
- * nbr_base Base of number to format (see Note #2).
- *
- * The following may be used to specify the number base :
- *
- * DEF_NBR_BASE_BIN Base 2
- * DEF_NBR_BASE_OCT Base 8
- * DEF_NBR_BASE_DEC Base 10
- * DEF_NBR_BASE_HEX Base 16
- *
- * lead_char Prepend leading character (see Note #3) :
- *
- * '\0' Do NOT prepend leading character to string.
- * Printable character Prepend leading character to string.
- * Unprintable character Format invalid string (see Note #6).
- *
- * lower_case Format alphabetic characters (if any) in lower case :
- *
- * DEF_NO Format alphabetic characters in upper case.
- * DEF_YES Format alphabetic characters in lower case.
- *
- * nul Append terminating NULL-character (see Note #4) :
- *
- * DEF_NO Do NOT append terminating NULL-character to string.
- * DEF_YES Append terminating NULL-character to string.
- *
- * pstr Pointer to character array to return formatted number string (see Note #5).
- *
- * Return(s) : Pointer to formatted string, if NO error(s).
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) If the number of digits to format ('nbr_dig') is zero; then NO formatting
- * is performed except possible NULL-termination of the string (see Note #4).
- *
- * Example :
- *
- * nbr = 23456
- * nbr_dig = 0
- * nbr_base = 10
- *
- * pstr = "" See Note #6a
- *
- * (b) If the number of digits to format ('nbr_dig') is less than the number of
- * significant integer digits of the number to format ('nbr'); then an invalid
- * string is formatted instead of truncating any significant integer digits.
- *
- * Example :
- *
- * nbr = 23456
- * nbr_dig = 3
- * nbr_base = 10
- *
- * pstr = "???" See Note #6b
- *
- * (2) The number's base MUST be between 2 & 36, inclusive.
- *$PAGE*
- * (3) Leading character option prepends leading characters prior to the first non-zero digit.
- *
- * (a) (1) Leading character MUST be a printable ASCII character.
- *
- * (2) (A) Leading character MUST NOT be a number base digit, ...
- * (B) with the exception of '0'.
- *
- * (b) The number of leading characters is such that the total number of significant
- * integer digits plus the number of leading characters is equal to the requested
- * number of integer digits to format ('nbr_dig').
- *
- * Example :
- *
- * nbr = 23456
- * nbr_dig = 7
- * nbr_base = 10
- * lead_char = ' '
- *
- * pstr = " 23456"
- *
- * (c) (1) If the value of the number to format is zero ...
- * (2) ... & the number of digits to format is non-zero, ...
- * (3) ... but NO leading character available; ...
- * (4) ... then one digit of '0' value is formatted.
- *
- * This is NOT a leading character; but a single integer digit of '0' value.
- *
- * (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
- * array formatting.
- *
- * (b) WARNING: Unless 'pstr' character array is pre-/post-terminated, NULL-character
- * terminate option DISABLED will cause character string run-on.
- *
- * (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (b) To prevent character buffer overrun :
- *
- * Character array size MUST be >= ('nbr_dig' +
- * 1 'NUL' terminator) characters
- *
- * (6) For any unsuccessful string format or error(s), an invalid string of question marks
- * ('?') will be formatted, where the number of question marks is determined by the
- * number of digits to format ('nbr_dig') :
- *
- * Invalid string's { (a) 0 (NULL string) , if 'nbr_dig' = 0
- * number of = {
- * question marks { (b) 'nbr_dig' , if 'nbr_dig' > 0
- *
- *********************************************************************************************************
- */
- CPU_CHAR *Str_FmtNbr_Int32U (CPU_INT32U nbr,
- CPU_INT08U nbr_dig,
- CPU_INT08U nbr_base,
- CPU_CHAR lead_char,
- CPU_BOOLEAN lower_case,
- CPU_BOOLEAN nul,
- CPU_CHAR *pstr)
- {
- CPU_CHAR *pstr_fmt;
- pstr_fmt = Str_FmtNbr_Int32(nbr, /* Fmt unsigned int into str. */
- nbr_dig,
- nbr_base,
- DEF_NO,
- lead_char,
- lower_case,
- nul,
- pstr);
- return (pstr_fmt);
- }
- /*
- *********************************************************************************************************
- * Str_FmtNbr_Int32S()
- *
- * Description : Format 32-bit signed integer into a multi-digit character string.
- *
- * Argument(s) : nbr Number to format.
- *
- * nbr_dig Number of digits to format (see Note #1).
- *
- * The following may be used to specify the number of digits to format :
- *
- * DEF_INT_32S_NBR_DIG_MIN + 1 Minimum number of 32-bit signed digits
- * DEF_INT_32S_NBR_DIG_MAX + 1 Maximum number of 32-bit signed digits
- * (plus 1 digit for possible negative sign)
- *
- * nbr_base Base of number to format (see Note #2).
- *
- * The following may be used to specify the number base :
- *
- * DEF_NBR_BASE_BIN Base 2
- * DEF_NBR_BASE_OCT Base 8
- * DEF_NBR_BASE_DEC Base 10
- * DEF_NBR_BASE_HEX Base 16
- *
- * lead_char Prepend leading character (see Note #3) :
- *
- * '\0' Do NOT prepend leading character to string.
- * Printable character Prepend leading character to string.
- * Unprintable character Format invalid string (see Note #6).
- *
- * lower_case Format alphabetic characters (if any) in lower case :
- *
- * DEF_NO Format alphabetic characters in upper case.
- * DEF_YES Format alphabetic characters in lower case.
- *
- * nul Append terminating NULL-character (see Note #4) :
- *
- * DEF_NO Do NOT append terminating NULL-character to string.
- * DEF_YES Append terminating NULL-character to string.
- *
- * pstr Pointer to character array to return formatted number string (see Note #5).
- *
- * Return(s) : Pointer to formatted string, if NO error(s).
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) If the number of digits to format ('nbr_dig') is zero; then NO formatting
- * is performed except possible NULL-termination of the string (see Note #4).
- *
- * Example :
- *
- * nbr = -23456
- * nbr_dig = 0
- * nbr_base = 10
- *
- * pstr = "" See Note #6a
- *
- * (b) If the number of digits to format ('nbr_dig') is less than the number of
- * significant integer digits of the number to format ('nbr'); then an invalid
- * string is formatted instead of truncating any significant integer digits.
- *
- * Example :
- *
- * nbr = 23456
- * nbr_dig = 3
- * nbr_base = 10
- *
- * pstr = "???" See Note #6b
- *
- * (c) If the number to format ('nbr') is negative but the number of digits to format
- * ('nbr_dig') is equal to the number of significant integer digits of the number
- * to format ('nbr'); then an invalid string is formatted instead of truncating
- * the negative sign.
- *
- * Example :
- *
- * nbr = -23456
- * nbr_dig = 5
- * nbr_base = 10
- *
- * pstr = "?????" See Note #6b
- *
- * (2) The number's base MUST be between 2 & 36, inclusive.
- *$PAGE*
- * (3) Leading character option prepends leading characters prior to the first non-zero digit.
- *
- * (a) (1) Leading character MUST be a printable ASCII character.
- *
- * (2) (A) Leading character MUST NOT be a number base digit, ...
- * (B) with the exception of '0'.
- *
- * (b) (1) The number of leading characters is such that the total number of significant
- * integer digits plus the number of leading characters plus possible negative
- * sign character is equal to the requested number of integer digits to format
- * ('nbr_dig').
- *
- * Examples :
- *
- * nbr = 23456
- * nbr_dig = 7
- * nbr_base = 10
- * lead_char = ' '
- *
- * pstr = " 23456"
- *
- *
- * nbr = -23456
- * nbr_dig = 7
- * nbr_base = 10
- * lead_char = ' '
- *
- * pstr = " -23456"
- *
- * (2) (A) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is a '0' digit; then the negative sign character
- * prefixes all leading characters prior to the formatted number.
- *
- * Examples :
- *
- * nbr = -23456
- * nbr_dig = 8
- * nbr_base = 10
- * lead_char = '0'
- *
- * pstr = "-0023456"
- *
- *
- * nbr = -43981
- * nbr_dig = 8
- * nbr_base = 16
- * lead_char = '0'
- * lower_case = DEF_NO
- *
- * pstr = "-000ABCD"
- *
- * (B) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is NOT a '0' digit; then the negative sign character
- * immediately prefixes the most significant digit of the formatted number.
- *
- * Examples :
- *
- * nbr = -23456
- * nbr_dig = 8
- * nbr_base = 10
- * lead_char = '#'
- *
- * pstr = "##-23456"
- *
- *
- * nbr = -43981
- * nbr_dig = 8
- * nbr_base = 16
- * lead_char = '#'
- * lower_case = DEF_YES
- *
- * pstr = "###-abcd"
- *
- * (c) (1) If the value of the number to format is zero ...
- * (2) ... & the number of digits to format is non-zero, ...
- * (3) ... but NO leading character available; ...
- * (4) ... then one digit of '0' value is formatted.
- *
- * This is NOT a leading character; but a single integer digit of '0' value.
- *$PAGE*
- * (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
- * array formatting.
- *
- * (b) WARNING: Unless 'pstr' character array is pre-/post-terminated, NULL-character
- * terminate option DISABLED will cause character string run-on.
- *
- * (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (b) To prevent character buffer overrun :
- *
- * Character array size MUST be >= ('nbr_dig' +
- * 1 negative sign +
- * 1 'NUL' terminator) characters
- *
- * (6) For any unsuccessful string format or error(s), an invalid string of question marks
- * ('?') will be formatted, where the number of question marks is determined by the
- * number of digits to format ('nbr_dig') :
- *
- * Invalid string's { (a) 0 (NULL string) , if 'nbr_dig' = 0
- * number of = {
- * question marks { (b) 'nbr_dig' , if 'nbr_dig' > 0
- *
- *********************************************************************************************************
- */
- CPU_CHAR *Str_FmtNbr_Int32S (CPU_INT32S nbr,
- CPU_INT08U nbr_dig,
- CPU_INT08U nbr_base,
- CPU_CHAR lead_char,
- CPU_BOOLEAN lower_case,
- CPU_BOOLEAN nul,
- CPU_CHAR *pstr)
- {
- CPU_CHAR *pstr_fmt;
- CPU_INT32S nbr_fmt;
- CPU_BOOLEAN nbr_neg;
- if (nbr < 0) { /* If nbr neg, ... */
- nbr_fmt = -nbr; /* ... negate nbr. */
- nbr_neg = DEF_YES;
- } else {
- nbr_fmt = nbr;
- nbr_neg = DEF_NO;
- }
- pstr_fmt = Str_FmtNbr_Int32((CPU_INT32U)nbr_fmt, /* Fmt signed int into str. */
- nbr_dig,
- nbr_base,
- nbr_neg,
- lead_char,
- lower_case,
- nul,
- pstr);
- return (pstr_fmt);
- }
- /*
- *********************************************************************************************************
- * Str_FmtNbr_32()
- *
- * Description : Format number into a multi-digit character string.
- *
- * Argument(s) : nbr Number to format (see Note #1).
- *
- * nbr_dig Number of decimal digits to format (see Note #2).
- *
- * nbr_dp Number of decimal point digits to format.
- *
- * lead_char Prepend leading character (see Note #3) :
- *
- * '\0' Do NOT prepend leading character to string.
- * Printable character Prepend leading character to string.
- * Unprintable character Format invalid string (see Note #6d).
- *
- * nul Append terminating NULL-character (see Note #4) :
- *
- * DEF_NO Do NOT append terminating NULL-character to string.
- * DEF_YES Append terminating NULL-character to string.
- *
- * pstr Pointer to character array to return formatted number string (see Note #5).
- *
- * Return(s) : Pointer to formatted string, if NO error(s) [see Note #6c].
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) (a) The maximum accuracy for 32-bit floating-point numbers :
- *
- *
- * Maximum Accuracy log [Internal-Base ^ (Number-Internal-Base-Digits)]
- * 32-bit Floating-point Number = -----------------------------------------------------
- * log [External-Base]
- *
- * log [2 ^ 24]
- * = --------------
- * log [10]
- *
- * < 7.225 Base-10 Digits
- *
- * where
- * Internal-Base Internal number base of floating-
- * point numbers (i.e. 2)
- * External-Base External number base of floating-
- * point numbers (i.e. 10)
- * Number-Internal-Base-Digits Number of internal number base
- * significant digits (i.e. 24)
- *
- * (b) Some CPUs' &/or compilers' floating-point implementations MAY further reduce the
- * maximum accuracy.
- *$PAGE*
- * (2) (a) If the total number of digits to format ('nbr_dig + nbr_dp') is zero; then NO
- * formatting is performed except possible NULL-termination of the string (see Note #4).
- *
- * Example :
- *
- * nbr = -23456.789
- * nbr_dig = 0
- * nbr_dp = 0
- *
- * pstr = "" See Note #7a
- *
- * (b) (1) If the number of digits to format ('nbr_dig') is less than the number of
- * significant integer digits of the number to format ('nbr'); then an invalid
- * string is formatted instead of truncating any significant integer digits.
- *
- * Example :
- *
- * nbr = 23456.789
- * nbr_dig = 3
- * nbr_dp = 2
- *
- * pstr = "??????" See Note #7d
- *
- * (2) If the number to format ('nbr') is negative but the number of digits to format
- * ('nbr_dig') is equal to the number of significant integer digits of the number
- * to format ('nbr'); then an invalid string is formatted instead of truncating
- * the negative sign.
- *
- * Example :
- *
- * nbr = -23456.789
- * nbr_dig = 5
- * nbr_dp = 2
- *
- * pstr = "????????" See Note #7d
- *
- * (3) If the number to format ('nbr') is negative but the number of significant
- * integer digits is zero, & the number of digits to format ('nbr_dig') is one
- * but the number of decimal point digits to format ('nbr_dp') is zero; then
- * an invalid string is formatted instead of truncating the negative sign.
- *
- * Example :
- *
- * nbr = -0.7895
- * nbr_dig = 1
- * nbr_dp = 0
- *
- * pstr = "?" See Note #7d
- *
- * (4) (A) If the number to format ('nbr') is negative but the number of significant
- * integer digits is zero, & the number of digits to format ('nbr_dig') is
- * zero but the number of decimal point digits to format ('nbr_dp') is non-
- * zero; then the negative sign immediately prefixes the decimal point --
- * with NO decimal digits formatted, NOT even a single decimal digit of '0'.
- *
- * Example :
- *
- * nbr = -0.7895
- * nbr_dig = 0
- * nbr_dp = 2
- *
- * pstr = "-.78"
- *
- * (B) If the number to format ('nbr') is positive but the number of significant
- * integer digits is zero, & the number of digits to format ('nbr_dig') is
- * zero but the number of decimal point digits to format ('nbr_dp') is non-
- * zero; then a single decimal digit of '0' prefixes the decimal point.
- *
- * This '0' digit is used whenever a negative sign is not formatted (see
- * Note #2b4A) so that the formatted string's decimal point is not floating,
- * but fixed in the string as the 2nd character.
- *
- * Example :
- *
- * nbr = 0.7895
- * nbr_dig = 0
- * nbr_dp = 2
- *
- * pstr = "0.78"
- *$PAGE*
- * (c) (1) If the total number of digits to format ('nbr_dig + nbr_dp') is greater than ... :
- *
- * (A) ... the maximum accuracy of the CPU's &/or compiler's 32-bit floating-point
- * numbers, digits following all significantly-accurate digits of the number to
- * format ('nbr') will be inaccurate; ...
- * (B) ... the configured maximum accuracy ('LIB_STR_CFG_FP_MAX_NBR_DIG_SIG'), all
- * digits or decimal places following all significantly-accurate digits of the
- * number to format ('nbr') will be replaced & formatted with zeros ('0').
- *
- * Example :
- *
- * nbr = 123456789.012345
- * nbr_dig = 9
- * nbr_dp = 6
- * LIB_STR_CFG_FP_MAX_NBR_DIG_SIG = 7
- *
- * pstr = "123456700.000000"
- *
- * (2) Therefore, one or more least-significant digit(s) of the number to format ('nbr')
- * MAY be rounded & not necessarily truncated due to the inaccuracy of the CPU's
- * &/or compiler's floating-point implementation.
- *
- * See also Note #1.
- *
- * (3) Leading character option prepends leading characters prior to the first non-zero digit.
- *
- * (a) (1) Leading character MUST be a printable ASCII character.
- *
- * (2) (A) Leading character MUST NOT be a base-10 digit, ...
- * (B) with the exception of '0'.
- *
- * (b) (1) The number of leading characters is such that the total number of significant
- * integer digits plus the number of leading characters plus possible negative
- * sign character is equal to the requested number of integer digits to format
- * ('nbr_dig').
- *
- * Examples :
- *
- * nbr = 23456.789
- * nbr_dig = 7
- * nbr_dp = 2
- * lead_char = ' '
- *
- * pstr = " 23456.78"
- *
- *
- * nbr = -23456.789
- * nbr_dig = 7
- * nbr_dp = 2
- * lead_char = ' '
- *
- * pstr = " -23456.78"
- *
- * (2) (A) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is a '0' digit; then the negative sign character
- * prefixes all leading characters prior to the formatted number.
- *
- * Example :
- *
- * nbr = -23456.789
- * nbr_dig = 8
- * nbr_dp = 2
- * lead_char = '0'
- *
- * pstr = "-0023456.78"
- *
- * (B) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is NOT a '0' digit; then the negative sign character
- * immediately prefixes the most significant digit of the formatted number.
- *
- * Examples :
- *
- * nbr = -23456.789
- * nbr_dig = 8
- * nbr_dp = 2
- * lead_char = '#'
- *
- * pstr = "##-23456.78"
- *
- * (c) (1) If the integer value of the number to format is zero & ...
- * (2) ... the number of digits to format is greater than one ...
- * (3) ... OR the number is NOT negative, ...
- * (4) ... but NO leading character available; ...
- * (5) ... then one digit of '0' value is formatted.
- *
- * This is NOT a leading character; but a single integer digit of '0' value.
- *
- * See also Note #2b4B.
- *$PAGE*
- * (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
- * array formatting.
- *
- * (b) WARNING: Unless 'pstr' character array is pre-/post-terminated, NULL-character
- * terminate option DISABLED will cause character string run-on.
- *
- * (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (b) To prevent character buffer overrun :
- *
- * Character array size MUST be >= ('nbr_dig' +
- * 'nbr_dp' +
- * 1 negative sign +
- * 1 decimal point +
- * 1 'NUL' terminator) characters
- *
- * (6) String format terminates when :
- *
- * (a) Format string pointer is passed a NULL pointer.
- * (1) No string formatted; NULL pointer returned.
- *
- * (b) Total number of digits to format ('nbr_dig + nbr_dp') is zero.
- * (1) NULL string formatted (see Note #7a); NULL pointer returned.
- *
- * (c) Number of digits to format ('nbr_dig') is less than number of significant
- * integer digits of the number to format ('nbr'), including possible
- * negative sign.
- * (1) Invalid string formatted (see Note #7); NULL pointer returned.
- *
- * (d) Lead character is NOT a valid, printable character (see Note #3a).
- * (1) Invalid string formatted (see Note #7); NULL pointer returned.
- *
- * (e) Number successfully formatted into character string array.
- *
- * (7) For any unsuccessful string format or error(s), an invalid string of question marks
- * ('?') will be formatted, where the number of question marks is determined by the
- * number of digits ('nbr_dig') & number of decimal point digits ('nbr_dp') to format :
- *
- * { (a) 0 (NULL string) , if 'nbr_dig' = 0 AND
- * { 'nbr_dp' = 0
- * {
- * { (b) 'nbr_dig' , if 'nbr_dig' > 0 AND
- * { 'nbr_dp' = 0
- * Invalid string's {
- * number of = { (c) ['nbr_dp' + , if 'nbr_dig' = 0 AND
- * question marks { 1 (for decimal point) + 'nbr_dp' > 0
- * { 1 (for negative sign) ]
- * {
- * { (d) ['nbr_dig' + , if 'nbr_dig' > 0 AND
- * { 'nbr_dp' + 'nbr_dp' > 0
- * { 1 (for decimal point) ]
- *
- *********************************************************************************************************
- */
- #if (LIB_STR_CFG_FP_EN == DEF_ENABLED)
- CPU_CHAR *Str_FmtNbr_32 (CPU_FP32 nbr,
- CPU_INT08U nbr_dig,
- CPU_INT08U nbr_dp,
- CPU_CHAR lead_char,
- CPU_BOOLEAN nul,
- CPU_CHAR *pstr)
- {
- CPU_CHAR *pstr_fmt;
- CPU_DATA i;
- CPU_FP32 nbr_fmt;
- CPU_FP32 nbr_log;
- CPU_INT32U nbr_shiftd;
- CPU_INT16U nbr_dig_max;
- CPU_INT16U nbr_dig_sig;
- CPU_INT08U nbr_neg_sign;
- CPU_INT08U dig_val;
- CPU_FP32 dig_exp;
- CPU_FP32 dp_exp;
- CPU_BOOLEAN lead_char_dig;
- CPU_BOOLEAN lead_char_fmtd;
- CPU_BOOLEAN lead_char_0;
- CPU_BOOLEAN fmt_invalid;
- CPU_BOOLEAN print_char;
- CPU_BOOLEAN nbr_neg;
- CPU_BOOLEAN nbr_neg_fmtd;
- /* ---------------- VALIDATE FMT ARGS ----------------- */
- if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if str ptr NULL (see Note #6a). */
- return ((CPU_CHAR *)0);
- }
- dig_exp = 1.0f;
- fmt_invalid = DEF_NO;
- lead_char_0 = (lead_char == '0') ? DEF_YES : DEF_NO; /* Chk if lead char a '0' dig (see Note #3b2). */
- nbr_fmt = 0.0f;
- nbr_neg = DEF_NO;
- if ((nbr_dig < 1) && (nbr_dp < 1)) { /* If nbr digs/dps = 0, ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6b). */
- }
- if (lead_char != (CPU_CHAR)'\0') {
- print_char = ASCII_IsPrint(lead_char);
- if (print_char != DEF_YES) { /* If lead char non-printable (see Note #3a1), ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6d). */
- } else if (lead_char != '0') { /* Chk lead char for non-0 dig. */
- lead_char_dig = ASCII_IsDig(lead_char);
- if (lead_char_dig == DEF_YES) { /* If lead char non-0 dig (see Note #3a2A), ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6d). */
- }
- }
- }
- /* ----------------- PREPARE NBR FMT ------------------ */
- pstr_fmt = pstr;
- if (fmt_invalid == DEF_NO) {
- if (nbr < 0.0f) { /* If nbr neg, ... */
- nbr_fmt = -nbr; /* ... negate nbr. */
- nbr_neg_sign = 1u;
- nbr_neg = DEF_YES;
- } else {
- nbr_fmt = nbr;
- nbr_neg_sign = 0u;
- nbr_neg = DEF_NO;
- }
- nbr_log = nbr_fmt;
- nbr_dig_max = 0u;
- while (nbr_log >= 1.0f) { /* While base-10 digs avail, ... */
- nbr_dig_max++; /* ... calc max nbr digs. */
- nbr_log /= 10.0f;
- }
- if (((nbr_dig >= (nbr_dig_max + nbr_neg_sign)) || /* If req'd nbr digs >= (max nbr digs + neg sign) .. */
- (nbr_dig_max < 1)) && /* .. or NO nbr digs, .. */
- ((nbr_dig > 1) || /* .. but NOT [(req'd nbr dig = 1) AND .. */
- (nbr_dp > 0) || /* .. (req'd nbr dp = 0) AND .. */
- (nbr_neg == DEF_NO))) { /* .. ( nbr neg )] (see Note #2b3). */
- /* .. prepare nbr digs to fmt. */
- for (i = 1u; i < nbr_dig; i++) {
- dig_exp *= 10.0f;
- }
- nbr_neg_fmtd = DEF_NO;
- nbr_dig_sig = 0u;
- lead_char_fmtd = DEF_NO;
- } else { /* Else if nbr trunc'd, ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6c). */
- }
- }
- /* ------------------- FMT NBR STR -------------------- */
- for (i = nbr_dig; i > 0; i--) { /* Fmt str for desired nbr digs : */
- if (fmt_invalid == DEF_NO) {
- if (nbr_dig_sig < LIB_STR_CFG_FP_MAX_NBR_DIG_SIG) { /* If nbr sig digs < max, fmt str digs; ... */
- nbr_shiftd = (CPU_INT32U)(nbr_fmt / dig_exp);
- if ((nbr_shiftd > 0) || /* If shifted nbr > 0 ... */
- (i == 1u)) { /* ... OR on one's dig to fmt (see Note #3c1), ... */
- /* ... calc & fmt dig val; ... */
- if ((nbr_neg == DEF_YES) && /* If nbr neg ... */
- (nbr_neg_fmtd == DEF_NO )) { /* ... but neg sign NOT yet fmt'd; ... */
- if (lead_char_fmtd == DEF_YES) { /* ... & if lead char(s) fmt'd, ... */
- pstr_fmt--; /* ... replace last lead char w/ ... */
- }
- *pstr_fmt++ = '-'; /* ... prepend neg sign (see Notes #2b & #3b). */
- nbr_neg_fmtd = DEF_YES;
- }
- if (nbr_shiftd > 0) { /* If shifted nbr > 0, ... */
- dig_val = (CPU_INT08U)(nbr_shiftd % 10u);
- *pstr_fmt++ = (CPU_CHAR )(dig_val + '0');
- nbr_dig_sig++; /* ... inc nbr sig digs; ... */
- } else if ((nbr_dig > 1) || /* ... else if req'd digs > 1 ... */
- (nbr_neg == DEF_NO)) { /* ... or non-neg nbr, ... */
- *pstr_fmt++ = '0'; /* ... fmt one '0' char (see Note #3c5). */
- }
- } else if ((nbr_neg == DEF_YES) && /* ... else if nbr neg ... */
- (lead_char_0 == DEF_YES) && /* ... & lead char a '0' dig ... */
- (nbr_neg_fmtd == DEF_NO )) { /* ... but neg sign NOT yet fmt'd, ... */
- *pstr_fmt++ = '-'; /* ... prepend neg sign (see Note #3b); ... */
- nbr_neg_fmtd = DEF_YES;
- } else if (lead_char != (CPU_CHAR)'\0') { /* ... else if avail, ... */
- *pstr_fmt++ = lead_char; /* ... fmt lead char. */
- lead_char_fmtd = DEF_YES;
- }
- dig_exp /= 10.0f; /* Shift to next least-sig dig. */
- } else { /* ... else append non-sig 0's (see Note #2c2). */
- *pstr_fmt++ = '0';
- }
- } else { /* Else fmt '?' for invalid str (see Note #7). */
- *pstr_fmt++ = '?';
- }
- }
- if (nbr_dp > 0) { /* Fmt str for desired nbr dp : */
- if (nbr_dig < 1) { /* If NO digs fmt'd; ... */
- if (fmt_invalid == DEF_NO) { /* ... nbr fmt valid, ... */
- if ((nbr_neg == DEF_YES) && /* ... nbr neg ... */
- (nbr_neg_fmtd == DEF_NO )) { /* ... but neg sign NOT yet fmt'd, ... */
- *pstr_fmt++ = '-'; /* ... prepend neg sign (see Notes #2b & #3b); ... */
- } else { /* ... else prepend 1 dig of '0' (see Note #3c5) ... */
- *pstr_fmt++ = '0';
- }
- } else { /* ... else fmt '?' for invalid str (see Note #7). */
- *pstr_fmt++ = '?';
- }
- }
- if (fmt_invalid == DEF_NO) { /* If nbr fmt valid, ... */
- *pstr_fmt++ = '.'; /* ... append dp prior to dp conversion. */
- } else { /* Else fmt '?' for invalid str (see Note #7). */
- *pstr_fmt++ = '?';
- }
- dp_exp = 10.0f;
- for (i = 0u; i < nbr_dp; i++) {
- if (fmt_invalid == DEF_NO) {
- /* If nbr sig digs < max, fmt str dps; ... */
- if (nbr_dig_sig < LIB_STR_CFG_FP_MAX_NBR_DIG_SIG) {
- nbr_shiftd = (CPU_INT32U)(nbr_fmt * dp_exp);
- dig_val = (CPU_INT08U)(nbr_shiftd % 10u);
- *pstr_fmt++ = (CPU_CHAR )(dig_val + '0');
- dp_exp *= 10.0f; /* Shift to next least-sig dp. */
- if ((nbr_shiftd > 0) || /* If shifted nbr > 0 ... */
- (nbr_dig_sig > 0)) { /* ... OR > 0 sig digs already fmt'd, ... */
- nbr_dig_sig++; /* ... inc nbr sig digs. */
- }
- } else { /* ... else append non-sig 0's (see Note #2c2). */
- *pstr_fmt++ = '0';
- }
- } else { /* Else fmt '?' for invalid str (see Note #7). */
- *pstr_fmt++ = '?';
- }
- }
- }
- if (nul != DEF_NO) { /* If NOT DISABLED, append NULL char (see Note #4). */
- *pstr_fmt = (CPU_CHAR)'\0';
- }
- if (fmt_invalid != DEF_NO) { /* Rtn NULL for invalid str fmt (see Notes #6a - #6d). */
- return ((CPU_CHAR *)0);
- }
- return (pstr); /* Rtn ptr to fmt'd str (see Note #6e). */
- }
- #endif
- /*
- *********************************************************************************************************
- * Str_ParseNbr_Int32U()
- *
- * Description : Parse 32-bit unsigned integer from string.
- *
- * Argument(s) : pstr Pointer to string (see Notes #1 & #2a).
- *
- * pstr_next Optional pointer to a variable to ... :
- *
- * (a) Return a pointer to first character following the integer string,
- * if NO error(s) [see Note #2a2B2];
- * (b) Return a pointer to 'pstr',
- * otherwise (see Note #2a2A2).
- *
- * nbr_base Base of number to parse (see Notes #2a1B1 & #2a2B1).
- *
- * Return(s) : Parsed integer, if integer parsed with NO overflow (see Note #2a3A).
- *
- * DEF_INT_32U_MAX_VAL, if integer parsed but overflowed (see Note #2a3A1).
- *
- * 0, otherwise (see Note #2a3B).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : DESCRIPTION' states that "these
- * functions shall convert the initial portion of the string pointed to by 'str' ('pstr')
- * to a type unsigned long ... representation" :
- *
- * (1) "First, they decompose the input string into three parts" :
- *
- * (A) "An initial, possibly empty, sequence of white-space characters [as specified
- * by isspace()]."
- *
- * (1) "The subject sequence is defined as the longest initial subsequence of the
- * input string, starting with the first non-white-space character that is of
- * the expected form. The subject sequence shall contain no characters if the
- * input string is empty or consists entirely of white-space characters."
- *
- * (B) (1) "A subject sequence interpreted as an integer represented in some radix
- * determined by the value of 'base' ('nbr_base')" :
- *
- * (a) "If the value of 'base' ('nbr_base') is 0, the expected form of the
- * subject sequence is that of a decimal constant, octal constant, or
- * hexadecimal constant" :
- *
- * (1) "A decimal constant begins with a non-zero digit, and consists of a
- * sequence of decimal digits."
- *
- * (2) "An octal constant consists of the prefix '0' optionally followed by
- * a sequence of the digits '0' to '7' only."
- *
- * (3) "A hexadecimal constant consists of the prefix '0x' or '0X' followed
- * by a sequence of the decimal digits and letters 'a' (or 'A') to 'f'
- * (or 'F') with values 10 to 15 respectively."
- *
- * (b) "If the value of 'base' ('nbr_base') is between 2 and 36, the expected form
- * of the subject sequence is a sequence of letters and digits representing
- * an integer with the radix specified by 'base' ('nbr_base')" :
- *
- * (1) (A) "The letters from 'a' (or 'A') to 'z' (or 'Z') inclusive are
- * ascribed the values 10 to 35"; ...
- * (B) "only letters whose ascribed values are less than that of base
- * are permitted."
- *
- * (2) (A) "If the value of 'base' ('nbr_base') is 16, the characters '0x' or
- * '0X' may optionally precede the sequence of letters and digits."
- *
- * (B) Although NO specification states that "if the value of 'base'
- * ('nbr_base') is" 8, the '0' character "may optionally precede
- * the sequence of letters and digits"; it seems reasonable to
- * allow the '0' character to be optionally parsed.
- *
- * (2) "A subject sequence .... may be preceded by a '+' or '-' sign."
- *
- * (a) However, it does NOT seem reasonable to parse & convert a negative number
- * integer string into an unsigned integer.
- *
- * (C) (1) (a) "A final string of one or more unrecognized characters," ...
- * (b) "including the terminating null byte of the input string" ...
- * (2) "other than a sign or a permissible letter or digit."
- *$PAGE*
- * (2) Second, "they shall attempt to convert the subject sequence to an unsigned integer" :
- *
- * (A) "If the subject sequence is empty or does not have the expected form" :
- *
- * (1) "no conversion [is] performed"; ...
- * (2) "the value of 'str' ('pstr') [is] stored in the object pointed to by 'endptr'
- * ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null pointer."
- *
- * (B) "If the subject sequence has the expected form" :
- *
- * (1) (a) "and the value of 'base' ('nbr_base') is 0, the sequence of characters
- * starting with the first digit shall be interpreted as an integer constant."
- *
- * (b) "and the value of 'base' ('nbr_base') is between 2 and 36, it shall be
- * used as the base for conversion, ascribing to each letter its value as
- * given above" (see Note #2a1B1b1A).
- *
- * (2) "A pointer to the final string shall be stored in the object pointed to by
- * 'endptr' ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null
- * pointer."
- *
- * (3) Lastly, IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : RETURN VALUE' states that :
- *
- * (A) "Upon successful completion, these functions shall return the converted value."
- * (1) "If the correct value is outside the range of representable values, {ULONG_MAX}
- * ... shall be returned."
- *
- * (B) "If no conversion could be performed, 0 shall be returned."
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * shall fail if" :
- *
- * (A) "[EINVAL] - The value of 'base' ('nbr_base') is not supported."
- *
- * (B) "[ERANGE] - The value to be returned is not representable."
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * may fail if" :
- *
- * (A) "[EINVAL] - No conversion could be performed."
- *
- * (3) Return integer value & next string pointer should be used to diagnose parse success or failure :
- *
- * (a) Valid parse string integer :
- *
- * pstr = " ABCDE xyz"
- * nbr_base = 16
- *
- * nbr = 703710
- * pstr_next = " xyz"
- *
- *
- * (b) Invalid parse string integer :
- *
- * pstr = " ABCDE"
- * nbr_base = 10
- *
- * nbr = 0
- * pstr_next = pstr = " ABCDE"
- *
- *
- * (c) Valid hexadecimal parse string integer :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 16
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (d) Valid decimal parse string integer ('0x' prefix ignored
- * following invalid hexadecimal characters) :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (e) Valid decimal parse string integer ('0' prefix ignored
- * following invalid octal characters) :
- *
- * pstr = " 0GABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "GABCDE"
- *
- *$PAGE*
- * (f) Parse string integer overflow :
- *
- * pstr = " 12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = DEF_INT_32U_MAX_VAL
- * pstr_next = "*123456"
- *
- *
- * (g) Invalid negative unsigned parse string :
- *
- * pstr = " -12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = 0
- * pstr_next = pstr = " -12345678901234567890*123456"
- *
- *********************************************************************************************************
- */
- CPU_INT32U Str_ParseNbr_Int32U (const CPU_CHAR *pstr,
- CPU_CHAR **pstr_next,
- CPU_INT08U nbr_base)
- {
- CPU_INT32U nbr;
- nbr = Str_ParseNbr_Int32( pstr, /* Parse/convert str ... */
- pstr_next,
- nbr_base,
- DEF_NO, /* ... as unsigned int (see Note #2a2). */
- (CPU_BOOLEAN *)0);
- return (nbr);
- }
- /*
- *********************************************************************************************************
- * Str_ParseNbr_Int32S()
- *
- * Description : Parse 32-bit signed integer from string.
- *
- * Argument(s) : pstr Pointer to string (see Notes #1 & #2a).
- *
- * pstr_next Optional pointer to a variable to ... :
- *
- * (a) Return a pointer to first character following the integer string,
- * if NO error(s) [see Note #2a2B2];
- * (b) Return a pointer to 'pstr',
- * otherwise (see Note #2a2A2).
- *
- * nbr_base Base of number to parse (see Notes #2a1B1 & #2a2B1).
- *
- * Return(s) : Parsed integer, if integer parsed with NO over- or underflow (see Note #2a3A).
- *
- * DEF_INT_32S_MIN_VAL, if integer parsed but negatively underflowed (see Note #2a3A1a).
- *
- * DEF_INT_32U_MAX_VAL, if integer parsed but positively overflowed (see Note #2a3A1b).
- *
- * 0, otherwise (see Note #2a3B).
- *
- * Caller(s) : Application.
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strtol() : DESCRIPTION' states that "these
- * functions shall convert the initial portion of the string pointed to by 'str' ('pstr')
- * to a type long ... representation" :
- *
- * (1) "First, they decompose the input string into three parts" :
- *
- * (A) "An initial, possibly empty, sequence of white-space characters [as specified
- * by isspace()]."
- *
- * (1) "The subject sequence is defined as the longest initial subsequence of the
- * input string, starting with the first non-white-space character that is of
- * the expected form. The subject sequence shall contain no characters if the
- * input string is empty or consists entirely of white-space characters."
- *
- * (B) (1) "A subject sequence interpreted as an integer represented in some radix
- * determined by the value of 'base' ('nbr_base')" :
- *
- * (a) "If the value of 'base' ('nbr_base') is 0, the expected form of the
- * subject sequence is that of a decimal constant, octal constant, or
- * hexadecimal constant" :
- *
- * (1) "A decimal constant begins with a non-zero digit, and consists of a
- * sequence of decimal digits."
- *
- * (2) "An octal constant consists of the prefix '0' optionally followed by
- * a sequence of the digits '0' to '7' only."
- *
- * (3) "A hexadecimal constant consists of the prefix '0x' or '0X' followed
- * by a sequence of the decimal digits and letters 'a' (or 'A') to 'f'
- * (or 'F') with values 10 to 15 respectively."
- *
- * (b) "If the value of 'base' ('nbr_base') is between 2 and 36, the expected form
- * of the subject sequence is a sequence of letters and digits representing
- * an integer with the radix specified by 'base' ('nbr_base')" :
- *
- * (1) (A) "The letters from 'a' (or 'A') to 'z' (or 'Z') inclusive are
- * ascribed the values 10 to 35"; ...
- * (B) "only letters whose ascribed values are less than that of base
- * are permitted."
- *
- * (2) (A) "If the value of 'base' ('nbr_base') is 16, the characters '0x' or
- * '0X' may optionally precede the sequence of letters and digits."
- *
- * (B) Although NO specification states that "if the value of 'base'
- * ('nbr_base') is" 8, the '0' character "may optionally precede
- * the sequence of letters and digits"; it seems reasonable to
- * allow the '0' character to be optionally parsed.
- *
- * (2) "A subject sequence .... may be preceded by a '+' or '-' sign."
- *
- * (a) However, it does NOT seem reasonable to parse & convert a negative number
- * integer string into an unsigned integer.
- *
- * (C) (1) (a) "A final string of one or more unrecognized characters," ...
- * (b) "including the terminating null byte of the input string" ...
- * (2) "other than a sign or a permissible letter or digit."
- *$PAGE*
- * (2) Second, "they shall attempt to convert the subject sequence to an integer" :
- *
- * (A) "If the subject sequence is empty or does not have the expected form" :
- *
- * (1) "no conversion is performed"; ...
- * (2) "the value of 'str' ('pstr') is stored in the object pointed to by 'endptr'
- * ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null pointer."
- *
- * (B) "If the subject sequence has the expected form" :
- *
- * (1) (a) "and the value of 'base' ('nbr_base') is 0, the sequence of characters
- * starting with the first digit shall be interpreted as an integer constant."
- *
- * (b) "and the value of 'base' ('nbr_base') is between 2 and 36, it shall be
- * used as the base for conversion, ascribing to each letter its value as
- * given above" (see Note #2a1B1b1A).
- *
- * (2) "A pointer to the final string shall be stored in the object pointed to by
- * 'endptr' ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null
- * pointer."
- *
- * (3) Lastly, IEEE Std 1003.1, 2004 Edition, Section 'strtol() : RETURN VALUE' states that :
- *
- * (A) "Upon successful completion, these functions shall return the converted value."
- *
- * (1) "If the correct value is outside the range of representable values", either
- * of the following "shall be returned" :
- * (a) "{LONG_MIN}" or ...
- * (b) "{LONG_MAX}"
- *
- * (B) "If no conversion could be performed, 0 shall be returned."
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * shall fail if" :
- *
- * (A) "[EINVAL] - The value of 'base' ('nbr_base') is not supported."
- *
- * (B) "[ERANGE] - The value to be returned is not representable."
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * may fail if" :
- *
- * (A) "[EINVAL] - No conversion could be performed."
- *
- * (3) Return integer value & next string pointer should be used to diagnose parse success or failure :
- *
- * (a) Valid parse string integer :
- *
- * pstr = " ABCDE xyz"
- * nbr_base = 16
- *
- * nbr = 703710
- * pstr_next = " xyz"
- *
- *
- * (b) Invalid parse string integer :
- *
- * pstr = " ABCDE"
- * nbr_base = 10
- *
- * nbr = 0
- * pstr_next = pstr = " ABCDE"
- *
- *
- * (c) Valid hexadecimal parse string integer :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 16
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (d) Valid decimal parse string integer ('0x' prefix ignored
- * following invalid hexadecimal characters) :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (e) Valid decimal parse string integer ('0' prefix ignored
- * following invalid octal characters) :
- *
- * pstr = " 0GABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "GABCDE"
- *
- *$PAGE*
- * (f) Parse string integer overflow :
- *
- * pstr = " 12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = DEF_INT_32S_MAX_VAL
- * pstr_next = "*123456"
- *
- *
- * (g) Parse string integer underflow :
- *
- * pstr = " -12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = DEF_INT_32S_MIN_VAL
- * pstr_next = "*123456"
- *
- *********************************************************************************************************
- */
- CPU_INT32S Str_ParseNbr_Int32S (const CPU_CHAR *pstr,
- CPU_CHAR **pstr_next,
- CPU_INT08U nbr_base)
- {
- CPU_INT32S nbr;
- CPU_INT32U nbr_abs;
- CPU_BOOLEAN nbr_neg;
- nbr_abs = Str_ParseNbr_Int32(pstr, /* Parse/convert str ... */
- pstr_next,
- nbr_base,
- DEF_YES, /* ... as signed int (see Note #2a2). */
- &nbr_neg);
- if (nbr_neg == DEF_NO) { /* Chk for neg nbr & ovf/undf (see Note #2a3A1). */
- nbr = (nbr_abs > (CPU_INT32U) DEF_INT_32S_MAX_VAL) ? (CPU_INT32S)DEF_INT_32S_MAX_VAL
- : (CPU_INT32S)nbr_abs;
- } else {
- nbr = (nbr_abs > (CPU_INT32U)-DEF_INT_32S_MIN_VAL_ONES_CPL) ? (CPU_INT32S)DEF_INT_32S_MIN_VAL
- : -(CPU_INT32S)nbr_abs;
- }
- return (nbr);
- }
- /*
- *********************************************************************************************************
- *********************************************************************************************************
- * LOCAL FUNCTIONS
- *********************************************************************************************************
- *********************************************************************************************************
- */
- /*
- *********************************************************************************************************
- * Str_FmtNbr_Int32()
- *
- * Description : Format 32-bit integer into a multi-digit character string.
- *
- * Argument(s) : nbr Number to format.
- *
- * nbr_dig Number of digits to format (see Note #1).
- *
- * nbr_base Base of number to format (see Note #2).
- *
- * nbr_neg Indicates whether number to format is negative :
- * -------
- * DEF_NO Number is non-negative.
- * DEF_YES Number is negative.
- *
- * Argument validated in Str_FmtNbr_Int32U(),
- * Str_FmtNbr_Int32S().
- *
- * lead_char Prepend leading character (see Note #3) :
- *
- * '\0' Do NOT prepend leading character to string.
- * Printable character Prepend leading character to string.
- * Unprintable character Format invalid string (see Note #6e).
- *
- * lower_case Format alphabetic characters (if any) in lower case :
- *
- * DEF_NO Format alphabetic characters in upper case.
- * DEF_YES Format alphabetic characters in lower case.
- *
- * nul Append terminating NULL-character (see Note #4) :
- *
- * DEF_NO Do NOT append terminating NULL-character to string.
- * DEF_YES Append terminating NULL-character to string.
- *
- * pstr Pointer to character array to return formatted number string (see Note #5).
- *
- * Return(s) : Pointer to formatted string, if NO error(s) [see Note #6f].
- *
- * Pointer to NULL, otherwise.
- *
- * Caller(s) : Str_FmtNbr_Int32U(),
- * Str_FmtNbr_Int32S().
- *$PAGE*
- * Note(s) : (1) (a) The maximum number of digits to format for 32-bit integer numbers :
- *
- *
- * Maximum Number of [ log (Number) ]
- * 32-bit Integer Digits = floor [ -------------- + 1 ]
- * to Format [ log (Base) ]
- *
- * where
- * Number Number to format
- * Base Base of number to format
- *
- * (b) (1) If the number of digits to format ('nbr_dig') is zero; then NO formatting
- * is performed except possible NULL-termination of the string (see Note #4).
- *
- * Example :
- *
- * nbr = -23456
- * nbr_dig = 0
- * nbr_base = 10
- *
- * pstr = "" See Note #7a
- *
- * (2) If the number of digits to format ('nbr_dig') is less than the number of
- * significant integer digits of the number to format ('nbr'); then an invalid
- * string is formatted instead of truncating any significant integer digits.
- *
- * Example :
- *
- * nbr = 23456
- * nbr_dig = 3
- * nbr_base = 10
- *
- * pstr = "???" See Note #7b
- *
- * (3) If the number to format ('nbr') is negative but the number of digits to format
- * ('nbr_dig') is equal to the number of significant integer digits of the number
- * to format ('nbr'); then an invalid string is formatted instead of truncating
- * the negative sign.
- *
- * Example :
- *
- * nbr = -23456
- * nbr_dig = 5
- * nbr_base = 10
- *
- * pstr = "?????" See Note #7b
- *
- * (2) The number's base MUST be between 2 & 36, inclusive.
- *$PAGE*
- * (3) Leading character option prepends leading characters prior to the first non-zero digit.
- *
- * (a) (1) Leading character MUST be a printable ASCII character.
- *
- * (2) (A) Leading character MUST NOT be a number base digit, ...
- * (B) with the exception of '0'.
- *
- * (b) (1) The number of leading characters is such that the total number of significant
- * integer digits plus the number of leading characters plus possible negative
- * sign character is equal to the requested number of integer digits to format
- * ('nbr_dig').
- *
- * Examples :
- *
- * nbr = 23456
- * nbr_dig = 7
- * nbr_base = 10
- * lead_char = ' '
- *
- * pstr = " 23456"
- *
- *
- * nbr = -23456
- * nbr_dig = 7
- * nbr_base = 10
- * lead_char = ' '
- *
- * pstr = " -23456"
- *
- * (2) (A) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is a '0' digit; then the negative sign character
- * prefixes all leading characters prior to the formatted number.
- *
- * Examples :
- *
- * nbr = -23456
- * nbr_dig = 8
- * nbr_base = 10
- * lead_char = '0'
- *
- * pstr = "-0023456"
- *
- *
- * nbr = -43981
- * nbr_dig = 8
- * nbr_base = 16
- * lead_char = '0'
- * lower_case = DEF_NO
- *
- * pstr = "-000ABCD"
- *
- * (B) If the number to format ('nbr') is negative AND the leading character
- * ('lead_char') is NOT a '0' digit; then the negative sign character
- * immediately prefixes the most significant digit of the formatted number.
- *
- * Examples :
- *
- * nbr = -23456
- * nbr_dig = 8
- * nbr_base = 10
- * lead_char = '#'
- *
- * pstr = "##-23456"
- *
- *
- * nbr = -43981
- * nbr_dig = 8
- * nbr_base = 16
- * lead_char = '#'
- * lower_case = DEF_YES
- *
- * pstr = "###-abcd"
- *
- * (c) (1) If the value of the number to format is zero ...
- * (2) ... & the number of digits to format is non-zero, ...
- * (3) ... but NO leading character available; ...
- * (4) ... then one digit of '0' value is formatted.
- *
- * This is NOT a leading character; but a single integer digit of '0' value.
- *$PAGE*
- * (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
- * array formatting.
- *
- * (b) WARNING: Unless 'pstr' character array is pre-/post-terminated, NULL-character
- * terminate option DISABLED will cause character string run-on.
- *
- * (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
- *
- * (b) To prevent character buffer overrun :
- *
- * Character array size MUST be >= ('nbr_dig' +
- * 1 negative sign +
- * 1 'NUL' terminator) characters
- *
- * (6) String format terminates when :
- *
- * (a) Format string pointer is passed a NULL pointer.
- * (1) No string formatted; NULL pointer returned.
- *
- * (b) Number of digits to format ('nbr_dig') is zero.
- * (1) NULL string formatted (see Note #7a); NULL pointer returned.
- *
- * (c) Number of digits to format ('nbr_dig') is less than number of significant
- * integer digits of the number to format ('nbr'), including possible
- * negative sign.
- * (1) Invalid string formatted (see Note #7); NULL pointer returned.
- *
- * (d) Base is passed an invalid base (see Note #2).
- * (1) Invalid string format performed; NULL pointer returned.
- *
- * (e) Lead character is NOT a valid, printable character (see Note #3a).
- * (1) Invalid string formatted (see Note #7); NULL pointer returned.
- *
- * (f) Number successfully formatted into character string array.
- *
- * (7) For any unsuccessful string format or error(s), an invalid string of question marks
- * ('?') will be formatted, where the number of question marks is determined by the
- * number of digits to format ('nbr_dig') :
- *
- * Invalid string's { (a) 0 (NULL string) , if 'nbr_dig' = 0
- * number of = {
- * question marks { (b) 'nbr_dig' , if 'nbr_dig' > 0
- *
- *********************************************************************************************************
- */
- static CPU_CHAR *Str_FmtNbr_Int32 (CPU_INT32U nbr,
- CPU_INT08U nbr_dig,
- CPU_INT08U nbr_base,
- CPU_BOOLEAN nbr_neg,
- CPU_CHAR lead_char,
- CPU_BOOLEAN lower_case,
- CPU_BOOLEAN nul,
- CPU_CHAR *pstr)
- {
- CPU_CHAR *pstr_fmt;
- CPU_DATA i;
- CPU_INT32U nbr_fmt;
- CPU_INT32U nbr_log;
- CPU_INT08U nbr_dig_max;
- CPU_INT08U nbr_dig_min;
- CPU_INT08U nbr_dig_fmtd;
- CPU_INT08U nbr_neg_sign;
- CPU_INT08U nbr_lead_char;
- CPU_INT08U dig_val;
- CPU_INT08U lead_char_delta_0;
- CPU_INT08U lead_char_delta_a;
- CPU_BOOLEAN lead_char_dig;
- CPU_BOOLEAN lead_char_0;
- CPU_BOOLEAN fmt_invalid;
- CPU_BOOLEAN print_char;
- CPU_BOOLEAN nbr_neg_fmtd;
- /* ---------------- VALIDATE FMT ARGS ----------------- */
- if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if str ptr NULL (see Note #6a). */
- return ((CPU_CHAR *)0);
- }
- fmt_invalid = DEF_NO;
- lead_char_0 = DEF_NO;
- if (nbr_dig < 1) { /* If nbr digs = 0, ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6b). */
- }
- /* If invalid base, ... */
- if ((nbr_base < 2u) ||
- (nbr_base > 36u)) {
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6d). */
- }
- if (lead_char != (CPU_CHAR)'\0') {
- print_char = ASCII_IsPrint(lead_char);
- if (print_char != DEF_YES) { /* If lead char non-printable (see Note #3a1), ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6e). */
- } else if (lead_char != '0') { /* Chk lead char for non-0 nbr base dig. */
- lead_char_delta_0 = (CPU_INT08U)(lead_char - '0');
- if (lower_case != DEF_YES) {
- lead_char_delta_a = (CPU_INT08U)(lead_char - 'A');
- } else {
- lead_char_delta_a = (CPU_INT08U)(lead_char - 'a');
- }
- lead_char_dig = (((nbr_base <= 10u) && (lead_char_delta_0 < nbr_base)) ||
- ((nbr_base > 10u) && ((lead_char_delta_0 < 10u) ||
- (lead_char_delta_a < (nbr_base - 10u))))) ? DEF_YES : DEF_NO;
- if (lead_char_dig == DEF_YES) { /* If lead char non-0 nbr base dig (see Note #3a2A), ...*/
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6e). */
- }
- }
- }
- /* ----------------- PREPARE NBR FMT ------------------ */
- pstr_fmt = pstr;
- lead_char_0 = DEF_NO;
- if (fmt_invalid == DEF_NO) {
- nbr_fmt = nbr;
- nbr_log = nbr;
- nbr_dig_max = 1u;
- while (nbr_log >= nbr_base) { /* While nbr base digs avail, ... */
- nbr_dig_max++; /* ... calc max nbr digs. */
- nbr_log /= nbr_base;
- }
- nbr_neg_sign = (nbr_neg == DEF_YES) ? 1u : 0u;
- if (nbr_dig >= (nbr_dig_max + nbr_neg_sign)) { /* If req'd nbr digs >= (max nbr digs + neg sign), ... */
- nbr_neg_fmtd = DEF_NO;
- nbr_dig_min = DEF_MIN(nbr_dig_max, nbr_dig);
- /* ... calc nbr digs to fmt & nbr lead chars. */
- if (lead_char != (CPU_CHAR)'\0') {
- nbr_dig_fmtd = nbr_dig;
- nbr_lead_char = nbr_dig -
- nbr_dig_min - nbr_neg_sign;
- } else {
- nbr_dig_fmtd = nbr_dig_min + nbr_neg_sign;
- nbr_lead_char = 0u;
- }
- if (nbr_lead_char > 0) { /* If lead chars to fmt, ... */
- lead_char_0 = (lead_char == '0') /* ... chk if lead char a '0' dig (see Note #3a2B). */
- ? DEF_YES : DEF_NO;
- }
- } else { /* Else if nbr trunc'd, ... */
- fmt_invalid = DEF_YES; /* ... fmt invalid str (see Note #6c). */
- }
- }
- if (fmt_invalid != DEF_NO) {
- nbr_dig_fmtd = nbr_dig;
- }
- /* ------------------- FMT NBR STR -------------------- */
- pstr_fmt += nbr_dig_fmtd; /* Start fmt @ least-sig dig. */
- if (nul != DEF_NO) { /* If NOT DISABLED, append NULL char (see Note #4). */
- *pstr_fmt = (CPU_CHAR)'\0';
- }
- pstr_fmt--;
- for (i = 0u; i < nbr_dig_fmtd; i++) { /* Fmt str for desired nbr digs : */
- if (fmt_invalid == DEF_NO) {
- if ((nbr_fmt > 0) || /* If fmt nbr > 0 ... */
- (i == 0u)) { /* ... OR on one's dig to fmt (see Note #3c1), ... */
- /* ... calc & fmt dig val; ... */
- dig_val = (CPU_INT08U)(nbr_fmt % nbr_base);
- if (dig_val < 10u) {
- *pstr_fmt-- = (CPU_CHAR)(dig_val + '0');
- } else {
- if (lower_case != DEF_YES) {
- *pstr_fmt-- = (CPU_CHAR)((dig_val - 10u) + 'A');
- } else {
- *pstr_fmt-- = (CPU_CHAR)((dig_val - 10u) + 'a');
- }
- }
- nbr_fmt /= nbr_base; /* Shift to next more-sig dig. */
- } else if ((nbr_neg == DEF_YES) && /* ... else if nbr neg AND ... */
- (((lead_char_0 == DEF_NO ) && /* ... lead char NOT a '0' dig ... */
- (nbr_neg_fmtd == DEF_NO )) || /* ... but neg sign NOT yet fmt'd OR ... */
- ((lead_char_0 != DEF_NO ) && /* ... lead char is a '0' dig ... */
- (i == (nbr_dig_fmtd - 1u))))) { /* ... & on most-sig dig to fmt, ... */
- *pstr_fmt-- = '-'; /* ... prepend neg sign (see Note #3b); ... */
- nbr_neg_fmtd = DEF_YES;
- } else if (lead_char != (CPU_CHAR)'\0') { /* ... else if avail, ... */
- *pstr_fmt-- = lead_char; /* ... fmt lead char. */
- }
- } else { /* Else fmt '?' for invalid str (see Note #7). */
- *pstr_fmt-- = '?';
- }
- }
- if (fmt_invalid != DEF_NO) { /* Rtn NULL for invalid str fmt (see Notes #6a - #6e). */
- return ((CPU_CHAR *)0);
- }
- return (pstr); /* Rtn ptr to fmt'd str (see Note #6f). */
- }
- /*
- *********************************************************************************************************
- * Str_ParseNbr_Int32()
- *
- * Description : Parse 32-bit integer from string.
- *
- * Argument(s) : pstr Pointer to string (see Notes #1 & #2a).
- *
- * pstr_next Optional pointer to a variable to ... :
- *
- * (a) Return a pointer to first character following the integer string,
- * if NO error(s) [see Note #2a2B2];
- * (b) Return a pointer to 'pstr',
- * otherwise (see Note #2a2A2).
- *
- * nbr_base Base of number to parse (see Notes #2a1B1 & #2a2B1).
- *
- * nbr_signed Indicates whether number to parse is signed :
- *
- * DEF_NO Number is unsigned.
- * DEF_YES Number is signed.
- *
- * pnbr_neg Pointer to a variable to return if the parsed (signed) number is negative :
- *
- * DEF_NO Number is non-negative.
- * DEF_YES Number is negative.
- *
- * Return(s) : Parsed integer, if integer parsed with NO overflow (see Note #2a3A).
- *
- * DEF_INT_32U_MAX_VAL, if integer parsed but overflowed (see Note #2a3A1).
- *
- * 0, otherwise (see Note #2a3B).
- *
- * Caller(s) : Str_ParseNbr_Int32U(),
- * Str_ParseNbr_Int32S().
- *
- * Note(s) : (1) String buffer NOT modified.
- *
- * (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'strtol() : DESCRIPTION' states that "these
- * functions shall convert the initial portion of the string pointed to by 'str' ('pstr')
- * to a type long ... representation" :
- *
- * (1) "First, they decompose the input string into three parts" :
- *
- * (A) "An initial, possibly empty, sequence of white-space characters [as specified
- * by isspace()]."
- *
- * (1) "The subject sequence is defined as the longest initial subsequence of the
- * input string, starting with the first non-white-space character that is of
- * the expected form. The subject sequence shall contain no characters if the
- * input string is empty or consists entirely of white-space characters."
- *
- * (B) (1) "A subject sequence interpreted as an integer represented in some radix
- * determined by the value of 'base' ('nbr_base')" :
- *
- * (a) "If the value of 'base' ('nbr_base') is 0, the expected form of the
- * subject sequence is that of a decimal constant, octal constant, or
- * hexadecimal constant" :
- *
- * (1) "A decimal constant begins with a non-zero digit, and consists of a
- * sequence of decimal digits."
- *
- * (2) "An octal constant consists of the prefix '0' optionally followed by
- * a sequence of the digits '0' to '7' only."
- *
- * (3) "A hexadecimal constant consists of the prefix '0x' or '0X' followed
- * by a sequence of the decimal digits and letters 'a' (or 'A') to 'f'
- * (or 'F') with values 10 to 15 respectively."
- *
- * (b) "If the value of 'base' ('nbr_base') is between 2 and 36, the expected form
- * of the subject sequence is a sequence of letters and digits representing
- * an integer with the radix specified by 'base' ('nbr_base')" :
- *
- * (1) (A) "The letters from 'a' (or 'A') to 'z' (or 'Z') inclusive are
- * ascribed the values 10 to 35"; ...
- * (B) "only letters whose ascribed values are less than that of base
- * are permitted."
- *
- * (2) (A) "If the value of 'base' ('nbr_base') is 16, the characters '0x' or
- * '0X' may optionally precede the sequence of letters and digits."
- *
- * (B) Although NO specification states that "if the value of 'base'
- * ('nbr_base') is" 8, the '0' character "may optionally precede
- * the sequence of letters and digits"; it seems reasonable to
- * allow the '0' character to be optionally parsed.
- *$PAGE*
- * (2) "A subject sequence .... may be preceded by a '+' or '-' sign."
- *
- * (a) It does NOT seem reasonable to parse & convert a negative number
- * integer string into an unsigned integer. However, a negative sign
- * for an unsigned integer will automatically be parsed as an invalid
- * character (see Note #2aC1).
- *
- * (C) (1) (a) "A final string of one or more unrecognized characters," ...
- * (b) "including the terminating null byte of the input string" ...
- * (2) "other than a sign or a permissible letter or digit."
- *
- * (2) Second, "they shall attempt to convert the subject sequence to an integer" :
- *
- * (A) "If the subject sequence is empty or does not have the expected form" :
- *
- * (1) "no conversion is performed"; ...
- * (2) "the value of 'str' ('pstr') is stored in the object pointed to by 'endptr'
- * ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null pointer."
- *
- * (B) "If the subject sequence has the expected form" :
- *
- * (1) (a) "and the value of 'base' ('nbr_base') is 0, the sequence of characters
- * starting with the first digit shall be interpreted as an integer constant."
- *
- * (b) "and the value of 'base' ('nbr_base') is between 2 and 36, it shall be
- * used as the base for conversion, ascribing to each letter its value as
- * given above" (see Note #2a1B1b1A).
- *
- * (2) "A pointer to the final string shall be stored in the object pointed to by
- * 'endptr' ('pstr_next'), provided that 'endptr' ('pstr_next') is not a null
- * pointer."
- *
- * (3) Lastly, IEEE Std 1003.1, 2004 Edition, Section 'strtol() : RETURN VALUE' states that :
- *
- * (A) "Upon successful completion, these functions shall return the converted value."
- * (1) "If the correct value is outside the range of representable values, {LONG_MIN}
- * [or] {LONG_MAX} ... shall be returned."
- *
- * (B) "If no conversion could be performed, 0 shall be returned."
- *
- * (b) (1) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * shall fail if" :
- *
- * (A) "[EINVAL] - The value of 'base' ('nbr_base') is not supported."
- *
- * (B) "[ERANGE] - The value to be returned is not representable."
- *
- * (2) IEEE Std 1003.1, 2004 Edition, Section 'strtoul() : ERRORS' states that "these functions
- * may fail if" :
- *
- * (A) "[EINVAL] - No conversion could be performed."
- *$PAGE*
- * (3) Return integer value & next string pointer should be used to diagnose parse success or failure :
- *
- * (a) Valid parse string integer :
- *
- * pstr = " ABCDE xyz"
- * nbr_base = 16
- *
- * nbr = 703710
- * pstr_next = " xyz"
- *
- *
- * (b) Invalid parse string integer :
- *
- * pstr = " ABCDE"
- * nbr_base = 10
- *
- * nbr = 0
- * pstr_next = pstr = " ABCDE"
- *
- *
- * (c) Valid hexadecimal parse string integer :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 16
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (d) Valid decimal parse string integer ('0x' prefix ignored
- * following invalid hexadecimal characters) :
- *
- * pstr = " 0xGABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "xGABCDE"
- *
- *
- * (e) Valid decimal parse string integer ('0' prefix ignored
- * following invalid octal characters) :
- *
- * pstr = " 0GABCDE"
- * nbr_base = 0
- *
- * nbr = 0
- * pstr_next = "GABCDE"
- *
- *
- * (f) Parse string integer overflow :
- *
- * pstr = " 12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = DEF_INT_32U_MAX_VAL
- * pstr_next = "*123456"
- *
- *
- * (g) Parse string integer underflow :
- *
- * pstr = " -12345678901234567890*123456"
- * nbr_base = 10
- *
- * nbr = DEF_INT_32S_MIN_VAL
- * pstr_next = "*123456"
- *
- *
- * (4) String parse terminates when :
- *
- * (a) Base passed an invalid base (see Note #2a1B1b).
- * (1) No conversion performed; 0 returned.
- *
- * (b) (1) Parse string passed a NULL pointer OR empty integer sequence (see Note #2a2A).
- * (A) No conversion performed; 0 returned.
- *
- * (2) Invalid parse string character found (see Note #2a1C).
- * (A) Parsed integer returned.
- * (B) 'pstr_next' points to invalid character.
- *
- * (3) Entire parse string converted (see Note #2a2B).
- * (A) Parsed integer returned.
- * (B) 'pstr_next' points to terminating NULL character.
- *
- * (5) Pointers to variables that return values MUST be initialized PRIOR to all other
- * validation or function handling in case of any error(s).
- *********************************************************************************************************
- */
- static CPU_INT32U Str_ParseNbr_Int32 (const CPU_CHAR *pstr,
- CPU_CHAR **pstr_next,
- CPU_INT08U nbr_base,
- CPU_BOOLEAN nbr_signed,
- CPU_BOOLEAN *pnbr_neg)
- {
- const CPU_CHAR *pstr_parse;
- const CPU_CHAR *pstr_parse_nbr;
- CPU_CHAR *pstr_parse_unused;
- CPU_CHAR parse_char;
- CPU_INT08U parse_dig;
- CPU_INT32U nbr;
- CPU_BOOLEAN nbr_neg_unused;
- CPU_BOOLEAN nbr_dig;
- CPU_BOOLEAN nbr_alpha;
- CPU_BOOLEAN nbr_hex;
- CPU_BOOLEAN nbr_hex_lower;
- CPU_BOOLEAN whitespace;
- CPU_BOOLEAN neg;
- CPU_BOOLEAN ovf;
- CPU_BOOLEAN done;
- /* --------------- VALIDATE PARSE ARGS ---------------- */
- if (pstr_next == (CPU_CHAR **) 0) { /* If NOT avail, ... */
- pstr_next = (CPU_CHAR **)&pstr_parse_unused; /* ... re-cfg NULL rtn ptr to unused local var. */
- (void)&pstr_parse_unused; /* Prevent possible 'variable unused' warning. */
- }
- *pstr_next = (CPU_CHAR *)pstr; /* Init rtn str for err (see Note #5). */
- if (pnbr_neg == (CPU_BOOLEAN *) 0) { /* If NOT avail, ... */
- pnbr_neg = (CPU_BOOLEAN *)&nbr_neg_unused; /* ... re-cfg NULL rtn ptr to unused local var. */
- (void)&nbr_neg_unused; /* Prevent possible 'variable unused' warning. */
- }
- *pnbr_neg = DEF_NO; /* Init nbr neg for err (see Note #5). */
- if (pstr == (CPU_CHAR *)0) { /* Rtn zero if str ptr NULL (see Note #4b1). */
- return (0u);
- }
- /* Rtn zero if invalid base (see Note #4a). */
- if ((nbr_base == 1u) ||
- (nbr_base > 36u)) {
- return (0u);
- }
- /* ------------- IGNORE PRECEDING CHAR(S) ------------- */
- pstr_parse = pstr; /* Save ptr to init'l str for err (see Note #2a2A2). */
- whitespace = ASCII_IsSpace(*pstr_parse);
- while (whitespace == DEF_YES) { /* Ignore initial white-space char(s) [see Note #2a1A]. */
- pstr_parse++;
- whitespace = ASCII_IsSpace(*pstr_parse);
- }
- switch (*pstr_parse) {
- case '+': /* Ignore pos sign (see Note #2a1B2). */
- pstr_parse++;
- neg = DEF_NO;
- break;
- case '-': /* Validate neg sign (see Note #2a1B2a). */
- if (nbr_signed == DEF_YES) {
- pstr_parse++;
- }
- neg = DEF_YES;
- break;
- default:
- neg = DEF_NO;
- break;
- }
- /* --------- IGNORE NBR BASE PRECEDING CHAR(S) -------- */
- pstr_parse_nbr = pstr_parse; /* Save ptr to str's nbr (see Note #2a1A1). */
- switch (nbr_base) {
- case 0u: /* Determine unspecified nbr base (see Notes #2a1B1a). */
- if (*pstr_parse == '0') { /* If avail, ... */
- pstr_parse++; /* ... adv past '0' prefix (see Note #2a1B1b2). */
- switch (*pstr_parse) {
- case 'x': /* For '0x' prefix, ... */
- case 'X':
- nbr_base = 16u; /* ... set nbr base = 16 (see Note #2a1B1a3). */
- parse_char = (CPU_CHAR)(*(pstr_parse + 1));
- nbr_hex = ASCII_IsDigHex(parse_char);
- if (nbr_hex == DEF_YES) { /* If next char is valid hex dig, ... */
- pstr_parse++; /* ... adv past '0x' prefix (see Note #2a1B1b2A). */
- }
- break;
- default: /* For '0' prefix, ... */
- nbr_base = 8u; /* ... set nbr base = 8 (see Note #2a1B1a2). */
- break;
- }
- } else { /* For non-'0' prefix, ... */
- nbr_base = 10u; /* ... set nbr base = 10 (see Note #2a1B1a1). */
- }
- break;
- case 8u: /* See Note #2a1B1a2. */
- if (*pstr_parse == '0') { /* If avail, ... */
- pstr_parse++; /* ... adv past '0' prefix (see Note #2a1B1b2B). */
- }
- break;
- case 16u: /* See Note #2a1B1a3. */
- if (*pstr_parse == '0') { /* If avail, ... */
- pstr_parse++; /* ... adv past '0' prefix (see Note #2a1B1b2). */
- switch (*pstr_parse) {
- case 'x':
- case 'X':
- parse_char = (CPU_CHAR)(*(pstr_parse + 1));
- nbr_hex = ASCII_IsDigHex(parse_char);
- if (nbr_hex == DEF_YES) { /* If next char is valid hex dig, ... */
- pstr_parse++; /* ... adv past '0x' prefix (see Note #2a1B1b2A). */
- }
- break;
- default:
- break;
- }
- }
- break;
- default: /* See Note #2a1B1b. */
- break;
- }
- /* ------------------ PARSE INT STR ------------------- */
- nbr = 0u;
- ovf = DEF_NO;
- done = DEF_NO;
- while (done == DEF_NO) { /* Parse str for desired nbr base digs (see Note #2a2). */
- parse_char = (CPU_CHAR)*pstr_parse;
- nbr_alpha = ASCII_IsAlphaNum(parse_char);
- if (nbr_alpha == DEF_YES) { /* If valid alpha num nbr dig avail, ... */
- /* ... convert parse char into nbr dig. */
- nbr_dig = ASCII_IsDig(parse_char);
- if (nbr_dig == DEF_YES) {
- parse_dig = (CPU_INT08U)(parse_char - '0');
- } else {
- nbr_hex_lower = ASCII_IsLower(parse_char);
- if (nbr_hex_lower == DEF_YES) {
- parse_dig = (CPU_INT08U)((parse_char - 'a') + 10u);
- } else {
- parse_dig = (CPU_INT08U)((parse_char - 'A') + 10u);
- }
- }
- if (parse_dig < nbr_base) { /* If parse char valid for nbr base ... */
- if (ovf == DEF_NO) { /* ... & nbr NOT yet ovf'd, ... */
- if (nbr <= Str_MultOvfThTbl_Int32U[nbr_base]) {
- /* ... merge parse char dig into nbr. */
- nbr *= nbr_base;
- nbr += parse_dig;
- if (nbr < parse_dig) {
- ovf = DEF_YES;
- }
- } else {
- ovf = DEF_YES;
- }
- }
- pstr_parse++;
- } else { /* Invalid char parsed (see Note #2a1C1a). */
- done = DEF_YES;
- }
- } else { /* Invalid OR NULL char parsed (see Note #2a1C1). */
- done = DEF_YES;
- }
- }
- if (ovf == DEF_YES) { /* If nbr ovf'd, ... */
- nbr = DEF_INT_32U_MAX_VAL; /* ... rtn max int val (see Note #2a3A1). */
- }
- if (pstr_parse != pstr_parse_nbr) { /* If final parse str != init'l parse nbr str, .. */
- *pstr_next = (CPU_CHAR *)pstr_parse; /* .. rtn parse str's next char (see Note #2a2B2); .. */
- } else {
- *pstr_next = (CPU_CHAR *)pstr; /* .. else rtn initial parse str (see Note #2a2A2). */
- }
- *pnbr_neg = neg; /* Rtn neg nbr status. */
- return (nbr);
- }
|