dclib-basics.h 240 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #ifndef DCLIB_BASICS_H
  34. #define DCLIB_BASICS_H 1
  35. #define _GNU_SOURCE 1
  36. #include <sys/types.h>
  37. #include <arpa/inet.h>
  38. #include <sys/un.h>
  39. #include <limits.h>
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <ctype.h>
  44. #include <math.h>
  45. #ifndef WIN_DCLIB
  46. #include <stdint.h>
  47. #endif
  48. #include "dclib-types.h"
  49. #include "dclib-debug.h"
  50. #include "dclib-color.h"
  51. #include "dclib-numeric.h"
  52. //
  53. ///////////////////////////////////////////////////////////////////////////////
  54. /////////////// conditionals ///////////////
  55. ///////////////////////////////////////////////////////////////////////////////
  56. // support function utimensat()
  57. #undef SUPPORT_UTIMENSAT
  58. #if defined(UTIME_OMIT) && !defined(__APPLE__)
  59. #define SUPPORT_UTIMENSAT 1
  60. #else
  61. #define SUPPORT_UTIMENSAT 0
  62. #endif
  63. //
  64. ///////////////////////////////////////////////////////////////////////////////
  65. /////////////// helpers ///////////////
  66. ///////////////////////////////////////////////////////////////////////////////
  67. #define SIZEOFMEMBER(type,a) sizeof(((type*)0)->a)
  68. #define SIZEOFRANGE(type,a,b) \
  69. ( offsetof(type,b) + sizeof(((type*)0)->b) - offsetof(type,a) )
  70. #define END_OF_VAR(v) ((void*)( (char*)(v) + sizeof(v) ))
  71. #define PTR_DISTANCE(a,b) ( (char*)(a) - (char*)(b) )
  72. #define PTR_DISTANCE_INT(a,b) ( (int)( (char*)(a) - (char*)(b) ))
  73. #define GET_INT_SIGN(type) ({ typeof(type) a=-1; a>0 ? 1 : -1; })
  74. #define GET_INT_TYPE(type) ((int)sizeof(type)*GET_INT_SIGN(type))
  75. // free a string if str is !NULL | !EmptyString | !MinusString | !IsCircBuf()
  76. void FreeString ( ccp str );
  77. //
  78. ///////////////////////////////////////////////////////////////////////////////
  79. /////////////// HAVE_* ///////////////
  80. ///////////////////////////////////////////////////////////////////////////////
  81. #undef HAVE_CLOCK_GETTIME
  82. #if _POSIX_C_SOURCE >= 199309L
  83. #define HAVE_CLOCK_GETTIME 1
  84. #else
  85. #define HAVE_CLOCK_GETTIME 0
  86. #endif
  87. //
  88. ///////////////////////////////////////////////////////////////////////////////
  89. /////////////// external types ///////////////
  90. ///////////////////////////////////////////////////////////////////////////////
  91. typedef struct ColorSet_t ColorSet_t;
  92. typedef struct RestoreState_t RestoreState_t;
  93. typedef struct LogFile_t LogFile_t;
  94. //
  95. ///////////////////////////////////////////////////////////////////////////////
  96. /////////////// bits ///////////////
  97. ///////////////////////////////////////////////////////////////////////////////
  98. extern const uchar TableBitCount[0x100];
  99. extern const char TableLowest0Bit[0x100];
  100. extern const char TableLowest1Bit[0x100];
  101. extern const char TableHighest0Bit[0x100];
  102. extern const char TableHighest1Bit[0x100];
  103. uint Count1Bits ( cvp addr, uint size );
  104. static inline uint Count0Bits ( cvp addr, uint size )
  105. { return CHAR_BIT * size - Count1Bits(addr,size); }
  106. #define Count1BitsObj(obj) Count1Bits(&(obj),sizeof(obj))
  107. #define Count0BitsObj(obj) Count1Bits(&(obj),sizeof(obj))
  108. static inline uint Count1Bits8 ( u8 data )
  109. {
  110. return TableBitCount[data];
  111. }
  112. static inline uint Count1Bits16 ( u16 data )
  113. {
  114. const u8 * d = (u8*)&data;
  115. return TableBitCount[d[0]]
  116. + TableBitCount[d[1]];
  117. }
  118. static inline uint Count1Bits32 ( u32 data )
  119. {
  120. // __builtin_popcount(unsigned int) is slower than table based summary
  121. const u8 * d = (u8*)&data;
  122. return TableBitCount[d[0]]
  123. + TableBitCount[d[1]]
  124. + TableBitCount[d[2]]
  125. + TableBitCount[d[3]];
  126. }
  127. static inline uint Count1Bits64 ( u64 data )
  128. {
  129. #if __GNUC__ > 3
  130. return __builtin_popcountll(data);
  131. #else
  132. const u8 * d = (u8*)&data;
  133. return TableBitCount[d[0]]
  134. + TableBitCount[d[1]]
  135. + TableBitCount[d[2]]
  136. + TableBitCount[d[3]]
  137. + TableBitCount[d[4]]
  138. + TableBitCount[d[5]]
  139. + TableBitCount[d[6]]
  140. + TableBitCount[d[7]];
  141. #endif
  142. }
  143. ///////////////////////////////////////////////////////////////////////////////
  144. // return -1 if bit not found
  145. int FindLowest0BitBE ( cvp addr, uint size );
  146. int FindLowest1BitBE ( cvp addr, uint size );
  147. int FindHighest0BitBE ( cvp addr, uint size );
  148. int FindHighest1BitBE ( cvp addr, uint size );
  149. int FindLowest0BitLE ( cvp addr, uint size );
  150. int FindLowest1BitLE ( cvp addr, uint size );
  151. int FindHighest0BitLE ( cvp addr, uint size );
  152. int FindHighest1BitLE ( cvp addr, uint size );
  153. #if __BYTE_ORDER == 1234
  154. #define FindLowest0Bit FindLowest0BitLE
  155. #define FindLowest1Bit FindLowest1BitLE
  156. #define FindHighest0Bit FindHighest0BitLE
  157. #define FindHighest1Bit FindHighest1BitLE
  158. #else
  159. #define FindLowest0Bit FindLowest0BitBE
  160. #define FindLowest1Bit FindLowest1BitBE
  161. #define FindHighest0Bit FindHighest0BitBE
  162. #define FindHighest1Bit FindHighest1BitBE
  163. #endif
  164. u32 GetAlign32 ( u32 data );
  165. u64 GetAlign64 ( u64 data );
  166. ///////////////////////////////////////////////////////////////////////////////
  167. static inline void SetBit ( void *addr, uint bit_num )
  168. { ((u8*)addr)[ bit_num >> 3 ] |= 1 << ( bit_num & 7 ); }
  169. static inline void ClearBit ( void *addr, uint bit_num )
  170. { ((u8*)addr)[ bit_num >> 3 ] &= ~(1 << ( bit_num & 7 )); }
  171. static inline void InvertBit ( void *addr, uint bit_num )
  172. { ((u8*)addr)[ bit_num >> 3 ] ^= 1 << ( bit_num & 7 ); }
  173. static inline bool TestBit ( const void *addr, uint bit_num )
  174. { return ( ((u8*)addr)[ bit_num >> 3 ] & 1 << ( bit_num & 7 ) ) != 0; }
  175. // change a single bit and return the previous state
  176. bool TestSetBit ( void *addr, uint bit_num );
  177. bool TestClearBit ( void *addr, uint bit_num );
  178. bool TestInvertBit ( void *addr, uint bit_num );
  179. // change bits inclusive 'beg' to exclusive 'end' if beg_bitnum<end_bitnum
  180. void SetBits ( void *addr, uint beg_bitnum, uint end_bitnum );
  181. void ClearBits ( void *addr, uint beg_bitnum, uint end_bitnum );
  182. void InvertBits ( void *addr, uint beg_bitnum, uint end_bitnum );
  183. ///////////////////////////////////////////////////////////////////////////////
  184. ///////////////////////////////////////////////////////////////////////////////
  185. int PrintBitfieldEx
  186. (
  187. // returns the number of printed characters, or -1 if buffer is to small
  188. char *buf, // buffer
  189. uint buf_size, // size of 'buf'
  190. cvp bit_field, // address of bit field
  191. uint min_idx, // minimal index (inclusive) to check
  192. uint max_idx, // maximal index (inclusive) to check
  193. bool use_ranges, // true: create ranges 'a:b'
  194. int mult, // each printed index is first multiplyed by 'mult'
  195. int add // ... and then added to 'add'.
  196. );
  197. static inline int PrintBitfield
  198. (
  199. // returns the number of printed characters, or -1 if buffer is to small
  200. char *buf, // buffer
  201. uint buf_size, // size of 'buf'
  202. cvp bit_field, // address of bit field
  203. uint bit_field_size, // size of 'bit_field' in bytes
  204. bool use_ranges // true: create ranges 'a:b'
  205. )
  206. {
  207. return PrintBitfieldEx ( buf, buf_size, bit_field,
  208. 0, 8*bit_field_size-1, use_ranges, 1, 0 );
  209. }
  210. //
  211. ///////////////////////////////////////////////////////////////////////////////
  212. /////////////// low level endian conversions ///////////////
  213. ///////////////////////////////////////////////////////////////////////////////
  214. //----------------------------------------------------
  215. // swapping bytes = inverse byte order
  216. // void dswap16 ( void * data_ptr );
  217. // void dswap24 ( void * data_ptr );
  218. // void dswap32 ( void * data_ptr );
  219. // void dswap48 ( void * data_ptr );
  220. // void dswap64 ( void * data_ptr );
  221. //----------------------------------------------------
  222. static inline void dswap16 ( void * data_ptr )
  223. {
  224. u8 *d = data_ptr;
  225. u8 temp = d[0];
  226. d[0] = d[1];
  227. d[1] = temp;
  228. }
  229. static inline void dswap24 ( void * data_ptr )
  230. {
  231. u8 *d = data_ptr;
  232. const u8 temp = d[0];
  233. d[0] = d[2];
  234. d[2] = temp;
  235. }
  236. static inline void dswap32 ( void * data_ptr )
  237. {
  238. u8 temp, *d = data_ptr;
  239. temp = d[0]; d[0] = d[3]; d[3] = temp;
  240. temp = d[1]; d[1] = d[2]; d[2] = temp;
  241. }
  242. static inline void dswap48 ( void * data_ptr )
  243. {
  244. u8 temp, *d = data_ptr;
  245. temp = d[0]; d[0] = d[5]; d[5] = temp;
  246. temp = d[1]; d[1] = d[4]; d[4] = temp;
  247. temp = d[2]; d[2] = d[3]; d[3] = temp;
  248. }
  249. static inline void dswap64 ( void * data_ptr )
  250. {
  251. u8 temp, *d = data_ptr;
  252. temp = d[0]; d[0] = d[7]; d[7] = temp;
  253. temp = d[1]; d[1] = d[6]; d[6] = temp;
  254. temp = d[2]; d[2] = d[5]; d[5] = temp;
  255. temp = d[3]; d[3] = d[4]; d[4] = temp;
  256. }
  257. ///////////////////////////////////////////////////////////////////////////////
  258. //----------------------------------------------------
  259. // read data and swap bytes (inverse byte order)
  260. // u16 swap16 ( const void * data_ptr );
  261. // u32 swap24 ( const void * data_ptr );
  262. // u32 swap32 ( const void * data_ptr );
  263. // u64 swap48 ( const void * data_ptr );
  264. // u64 swap64 ( const void * data_ptr );
  265. // float swapf4 ( const void * data_ptr );
  266. // double swapf8 ( const void * data_ptr );
  267. //----------------------------------------------------
  268. static inline u16 swap16 ( const void * data_ptr )
  269. {
  270. u8 r[2];
  271. const u8 *d = data_ptr;
  272. r[1] = *d++;
  273. r[0] = *d;
  274. return *(u16*)r;
  275. }
  276. static inline u32 swap24 ( const void * data_ptr )
  277. {
  278. u8 r[4];
  279. const u8 *d = data_ptr;
  280. r[3] = 0;
  281. r[2] = *d++;
  282. r[1] = *d++;
  283. r[0] = *d;
  284. return *(u32*)r;
  285. }
  286. static inline u32 swap32 ( const void * data_ptr )
  287. {
  288. u8 r[4];
  289. const u8 *d = data_ptr;
  290. r[3] = *d++;
  291. r[2] = *d++;
  292. r[1] = *d++;
  293. r[0] = *d;
  294. return *(u32*)r;
  295. }
  296. static inline u64 swap48 ( const void * data_ptr )
  297. {
  298. u8 r[8];
  299. const u8 *d = data_ptr;
  300. r[7] = 0;
  301. r[6] = 0;
  302. r[5] = *d++;
  303. r[4] = *d++;
  304. r[3] = *d++;
  305. r[2] = *d++;
  306. r[1] = *d++;
  307. r[0] = *d;
  308. return *(u64*)r;
  309. }
  310. static inline u64 swap64 ( const void * data_ptr )
  311. {
  312. u8 r[8];
  313. const u8 *d = data_ptr;
  314. r[7] = *d++;
  315. r[6] = *d++;
  316. r[5] = *d++;
  317. r[4] = *d++;
  318. r[3] = *d++;
  319. r[2] = *d++;
  320. r[1] = *d++;
  321. r[0] = *d;
  322. return *(u64*)r;
  323. }
  324. static inline float swapf4 ( const void * data_ptr )
  325. {
  326. // assume: local system supports IEEE 754
  327. union { float f; u32 i; } u;
  328. u.i = swap32(data_ptr);
  329. return u.f;
  330. }
  331. static inline double swapf8 ( const void * data_ptr )
  332. {
  333. // assume: local system supports IEEE 754
  334. union { double f; u64 i; } u;
  335. u.i = swap64(data_ptr);
  336. return u.f;
  337. }
  338. ///////////////////////////////////////////////////////////////////////////////
  339. //----------------------------------------------------
  340. // convert big endian data to a number in host format
  341. // u16 be16 ( const void * be_data_ptr );
  342. // u32 be24 ( const void * be_data_ptr );
  343. // u32 be32 ( const void * be_data_ptr );
  344. // u64 be40 ( const void * be_data_ptr );
  345. // u64 be48 ( const void * be_data_ptr );
  346. // u64 be56 ( const void * be_data_ptr );
  347. // u64 be64 ( const void * be_data_ptr );
  348. // float bef4 ( const void * be_data_ptr );
  349. // double bef8 ( const void * be_data_ptr );
  350. //----------------------------------------------------
  351. static inline u16 be16 ( const void * be_data_ptr )
  352. {
  353. const u8 * d = be_data_ptr;
  354. return d[0] << 8 | d[1];
  355. }
  356. static inline u32 be24 ( const void * be_data_ptr )
  357. {
  358. const u8 * d = be_data_ptr;
  359. return ( d[0] << 8 | d[1] ) << 8 | d[2];
  360. }
  361. static inline u32 be32 ( const void * be_data_ptr )
  362. {
  363. const u8 * d = be_data_ptr;
  364. return (( d[0] << 8 | d[1] ) << 8 | d[2] ) << 8 | d[3];
  365. }
  366. static inline u64 be40 ( const void * be_data_ptr )
  367. {
  368. const u8 * d = be_data_ptr;
  369. return (u64)be32(d) << 8 | ((u8*)d)[4];
  370. }
  371. static inline u64 be48 ( const void * be_data_ptr )
  372. {
  373. const u8 * d = be_data_ptr;
  374. return (u64)be32(d) << 16 | be16(d+4);
  375. }
  376. static inline u64 be56 ( const void * be_data_ptr )
  377. {
  378. const u8 * d = be_data_ptr;
  379. return (u64)be32(d) << 24 | be24(d+4);
  380. }
  381. static inline u64 be64 ( const void * be_data_ptr )
  382. {
  383. const u8 * d = be_data_ptr;
  384. return (u64)be32(d) << 32 | be32(d+4);
  385. }
  386. static inline float bef4 ( const void * be_data_ptr )
  387. {
  388. // assume: local system supports IEEE 754
  389. union { float f; u32 i; } u;
  390. u.i = be32(be_data_ptr);
  391. return u.f;
  392. }
  393. static inline double bef8 ( const void * be_data_ptr )
  394. {
  395. // assume: local system supports IEEE 754
  396. union { double f; u64 i; } u;
  397. u.i = be64(be_data_ptr);
  398. return u.f;
  399. }
  400. ///////////////////////////////////////////////////////////////////////////////
  401. //-------------------------------------------------------
  402. // convert little endian data to a number in host format
  403. // u16 le16 ( const void * le_data_ptr );
  404. // u32 le24 ( const void * le_data_ptr );
  405. // u32 le32 ( const void * le_data_ptr );
  406. // u64 le40 ( const void * le_data_ptr );
  407. // u64 le48 ( const void * le_data_ptr );
  408. // u64 le56 ( const void * le_data_ptr );
  409. // u64 le64 ( const void * le_data_ptr );
  410. // float lef4 ( const void * le_data_ptr );
  411. // double lef8 ( const void * le_data_ptr );
  412. //-------------------------------------------------------
  413. static inline u16 le16 ( const void * le_data_ptr )
  414. {
  415. const u8 * d = le_data_ptr;
  416. return d[1] << 8 | d[0];
  417. }
  418. static inline u32 le24 ( const void * le_data_ptr )
  419. {
  420. const u8 * d = le_data_ptr;
  421. return ( d[2] << 8 | d[1] ) << 8 | d[0];
  422. }
  423. static inline u32 le32 ( const void * le_data_ptr )
  424. {
  425. const u8 * d = le_data_ptr;
  426. return (( d[3] << 8 | d[2] ) << 8 | d[1] ) << 8 | d[0];
  427. }
  428. static inline u64 le40 ( const void * le_data_ptr )
  429. {
  430. const u8 * d = le_data_ptr;
  431. return (u64)le32(d+1) << 8 | ((u8*)d)[0];
  432. }
  433. static inline u64 le48 ( const void * le_data_ptr )
  434. {
  435. const u8 * d = le_data_ptr;
  436. return (u64)le16(d+4) << 32 | le32(d);
  437. }
  438. static inline u64 le56 ( const void * le_data_ptr )
  439. {
  440. const u8 * d = le_data_ptr;
  441. return (u64)le24(d+4) << 32 | le32(d);
  442. }
  443. static inline u64 le64 ( const void * le_data_ptr )
  444. {
  445. const u8 * d = le_data_ptr;
  446. return (u64)le32(d+4) << 32 | le32(d);
  447. }
  448. static inline float lef4 ( const void * le_data_ptr )
  449. {
  450. // assume: local system supports IEEE 754
  451. union { float f; u32 i; } u;
  452. u.i = le32(le_data_ptr);
  453. return u.f;
  454. }
  455. static inline double lef8 ( const void * le_data_ptr )
  456. {
  457. // assume: local system supports IEEE 754
  458. union { double f; u64 i; } u;
  459. u.i = le64(le_data_ptr);
  460. return u.f;
  461. }
  462. ///////////////////////////////////////////////////////////////////////////////
  463. //-------------------------------------------
  464. // convert u64 from/to network byte order
  465. // be64_t hton64 ( u64 data );
  466. // u64 ntoh64 ( be64_t data );
  467. //-------------------------------------------
  468. static inline be64_t hton64 ( u64 data )
  469. {
  470. be64_t result;
  471. ((u32*)&result)[0] = htonl( (u32)(data >> 32) );
  472. ((u32*)&result)[1] = htonl( (u32)data );
  473. return result;
  474. }
  475. static inline u64 ntoh64 ( be64_t data )
  476. {
  477. return (u64)ntohl(((u32*)&data)[0]) << 32 | ntohl(((u32*)&data)[1]);
  478. }
  479. ///////////////////////////////////////////////////////////////////////////////
  480. // convert a number in host format into big endian data
  481. void write_be16 ( void * be_data_ptr, u16 data );
  482. void write_be24 ( void * be_data_ptr, u32 data );
  483. void write_be32 ( void * be_data_ptr, u32 data );
  484. void write_be40 ( void * be_data_ptr, u64 data );
  485. void write_be48 ( void * be_data_ptr, u64 data );
  486. void write_be56 ( void * be_data_ptr, u64 data );
  487. void write_be64 ( void * be_data_ptr, u64 data );
  488. void write_bef4 ( void * be_data_ptr, float data );
  489. void write_bef8 ( void * be_data_ptr, double data );
  490. // convert a number in host format into little endian data
  491. void write_le16 ( void * le_data_ptr, u16 data );
  492. void write_le24 ( void * le_data_ptr, u32 data );
  493. void write_le32 ( void * le_data_ptr, u32 data );
  494. void write_le40 ( void * le_data_ptr, u64 data );
  495. void write_le48 ( void * le_data_ptr, u64 data );
  496. void write_le56 ( void * le_data_ptr, u64 data );
  497. void write_le64 ( void * le_data_ptr, u64 data );
  498. void write_lef4 ( void * le_data_ptr, float data );
  499. void write_lef8 ( void * le_data_ptr, double data );
  500. // convert lists
  501. void be16n ( u16 * dest, const u16 * src, int n );
  502. void be32n ( u32 * dest, const u32 * src, int n );
  503. void bef4n ( float32 * dest, const float32 * src, int n );
  504. void le16n ( u16 * dest, const u16 * src, int n );
  505. void le32n ( u32 * dest, const u32 * src, int n );
  506. void lef4n ( float32 * dest, const float32 * src, int n );
  507. void write_be16n ( u16 * dest, const u16 * src, int n );
  508. void write_be32n ( u32 * dest, const u32 * src, int n );
  509. void write_bef4n ( float32 * dest, const float32 * src, int n );
  510. void write_le16n ( u16 * dest, const u16 * src, int n );
  511. void write_le32n ( u32 * dest, const u32 * src, int n );
  512. void write_lef4n ( float32 * dest, const float32 * src, int n );
  513. //-----------------------------------------------------------------------------
  514. // [[endian_func_t]]
  515. typedef struct endian_func_t
  516. {
  517. //--- info section
  518. u8 bom[2]; // byte order mark: BE=0xfe,0xff, LE=0xff,0xfe
  519. bool is_be; // true: is big endian
  520. bool is_le; // true: is little endian
  521. dcEndian_t endian; // DC_BIG_ENDIAN or DC_LITTLE_ENDIAN
  522. //--- read functions
  523. u16 (*rd16) ( const void * data_ptr );
  524. u32 (*rd24) ( const void * data_ptr );
  525. u32 (*rd32) ( const void * data_ptr );
  526. u64 (*rd40) ( const void * data_ptr );
  527. u64 (*rd48) ( const void * data_ptr );
  528. u64 (*rd56) ( const void * data_ptr );
  529. u64 (*rd64) ( const void * data_ptr );
  530. float (*rdf4) ( const void * data_ptr );
  531. double (*rdf8) ( const void * data_ptr );
  532. //--- write functions
  533. void (*wr16) ( void * data_ptr, u16 data );
  534. void (*wr24) ( void * data_ptr, u32 data );
  535. void (*wr32) ( void * data_ptr, u32 data );
  536. void (*wr40) ( void * data_ptr, u64 data );
  537. void (*wr48) ( void * data_ptr, u64 data );
  538. void (*wr56) ( void * data_ptr, u64 data );
  539. void (*wr64) ( void * data_ptr, u64 data );
  540. void (*wrf4) ( void * data_ptr, float data );
  541. void (*wrf8) ( void * data_ptr, double data );
  542. //--- convert functions
  543. u16 (*n2hs) ( u16 data );
  544. u32 (*n2hl) ( u32 data );
  545. u64 (*n2h64) ( u64 data );
  546. u16 (*h2ns) ( u16 data );
  547. u32 (*h2nl) ( u32 data );
  548. u64 (*h2n64) ( u64 data );
  549. } endian_func_t;
  550. extern const endian_func_t be_func;
  551. extern const endian_func_t le_func;
  552. const endian_func_t * GetEndianFunc ( const void * byte_order_mark );
  553. uint GetTextBOMLen ( const void * data, uint data_size );
  554. //
  555. ///////////////////////////////////////////////////////////////////////////////
  556. /////////////// CopyMode_t ///////////////
  557. ///////////////////////////////////////////////////////////////////////////////
  558. // [[CopyMode_t]]
  559. typedef enum CopyMode_t
  560. {
  561. CPM_COPY, // make a copy of the data, alloced
  562. CPM_MOVE, // move the alloced data
  563. CPM_LINK, // link the data
  564. } CopyMode_t;
  565. ///////////////////////////////////////////////////////////////////////////////
  566. void * CopyData
  567. (
  568. const void *data, // data to copy/move/link
  569. uint size, // size of 'data'
  570. CopyMode_t mode, // copy mode
  571. bool *res_alloced // not NULL:
  572. // store true, if data must be freed
  573. // otherwise store false
  574. );
  575. ///////////////////////////////////////////////////////////////////////////////
  576. char * CopyString
  577. (
  578. ccp string, // string to copy/move/link
  579. CopyMode_t mode, // copy mode
  580. bool *res_alloced // not NULL:
  581. // store true, if data must be freed
  582. // otherwise store false
  583. );
  584. ///////////////////////////////////////////////////////////////////////////////
  585. static inline void FreeData
  586. (
  587. const void *data, // data to free
  588. CopyMode_t mode // copy mode
  589. )
  590. {
  591. if ( mode != CPM_LINK )
  592. FreeString(data);
  593. }
  594. //
  595. ///////////////////////////////////////////////////////////////////////////////
  596. /////////////// struct mem_t ///////////////
  597. ///////////////////////////////////////////////////////////////////////////////
  598. // [[mem_t]]
  599. typedef struct mem_t
  600. {
  601. ccp ptr; // NULL or a pointer to the data
  602. int len; // length in bytes of the data
  603. }
  604. mem_t;
  605. extern mem_t EmptyMem; // mem_t(EmptyString,0)
  606. extern mem_t NullMem; // mem_t(0,0)
  607. //-----------------------------------------------------------------------------
  608. // [[mem_src_t]]
  609. typedef struct mem_src_t
  610. {
  611. const mem_t *src; // list of sources
  612. int n_src; // number of sources; if <0: first NULL ptr terminates list
  613. bool allow_write; // TRUE: allow to write n_src & src->len if <0
  614. }
  615. mem_src_t;
  616. uint GetMemSrcN ( const mem_src_t *src ); // NULL allowed
  617. uint GetMemSrcLen ( mem_t sep, const mem_src_t *src ); // NULL allowed
  618. //-----------------------------------------------------------------------------
  619. static inline mem_t MemByChar ( char ch )
  620. {
  621. mem_t mem = { &ch, 1 };
  622. return mem;
  623. }
  624. // NULL allowed
  625. static inline mem_t MemByString0 ( ccp str )
  626. {
  627. if (!str)
  628. return NullMem;
  629. mem_t mem = { str, strlen(str) };
  630. return mem;
  631. }
  632. // NULL forbidden
  633. static inline mem_t MemByString ( ccp str )
  634. {
  635. mem_t mem = { str, strlen(str) };
  636. return mem;
  637. }
  638. // NULL forbidden if len<0
  639. static inline mem_t MemByStringS ( ccp str, int len )
  640. {
  641. mem_t mem = { str, len < 0 ? strlen(str) : len };
  642. return mem;
  643. }
  644. // NULL forbidden if end=0
  645. static inline mem_t MemByStringE ( ccp str, ccp end )
  646. {
  647. mem_t mem = { str, end ? end-str : strlen(str) };
  648. return mem;
  649. }
  650. static inline mem_t MemByS ( ccp str, int len )
  651. {
  652. mem_t mem = { str, len };
  653. return mem;
  654. }
  655. static inline mem_t MemByE ( ccp str, ccp end )
  656. {
  657. mem_t mem = { str, end-str };
  658. return mem;
  659. }
  660. //-----------------------------------------------------------------------------
  661. // Index helpers
  662. // For the 'End' variants, index 0 is end_of_source
  663. int CheckIndex1 ( int max, int index );
  664. int CheckIndex1End ( int max, int index );
  665. int CheckIndex2 ( int max, int * p_begin, int * p_end );
  666. int CheckIndex2End ( int max, int * p_begin, int * p_end );
  667. int CheckIndexC ( int max, int * p_begin, int count );
  668. int CheckIndexCEnd ( int max, int * p_begin, int count );
  669. //-----------------------------------------------------------------------------
  670. // All functions are robust.
  671. // A negative index is relative to the end of source.
  672. // For RightMem() and ExtractEndMem(), index 0 means: end of source.
  673. // count<0 means: copy left from 'begin' (only MidMem()) or skip bytes.
  674. mem_t MidMem ( const mem_t src, int begin, int count );
  675. static inline mem_t LeftMem ( const mem_t src, int count )
  676. {
  677. mem_t res;
  678. res.ptr = src.ptr;
  679. res.len = CheckIndex1(src.len,count);
  680. return res;
  681. }
  682. static inline mem_t RightMem ( const mem_t src, int count )
  683. {
  684. mem_t res;
  685. res.len = src.len - CheckIndex1End(src.len,-count);
  686. res.ptr = src.ptr + src.len - res.len;
  687. return res;
  688. }
  689. static inline mem_t ExtractMem ( const mem_t src, int begin, int end )
  690. {
  691. mem_t res;
  692. res.len = CheckIndex2(src.len,&begin,&end);
  693. res.ptr = src.ptr + begin;
  694. return res;
  695. }
  696. static inline mem_t ExtractEndMem ( const mem_t src, int begin, int end )
  697. {
  698. mem_t res;
  699. res.len = CheckIndex2End(src.len,&begin,&end);
  700. res.ptr = src.ptr + begin;
  701. return res;
  702. }
  703. mem_t BeforeMem ( const mem_t src, ccp ref );
  704. mem_t BehindMem ( const mem_t src, ccp ref );
  705. //-----------------------------------------------------------------------------
  706. // UTF8 support
  707. mem_t MidMem8 ( const mem_t src, int begin, int count );
  708. mem_t ExtractMem8 ( const mem_t src, int begin, int end );
  709. mem_t ExtractEndMem8 ( const mem_t src, int begin, int end );
  710. static mem_t LeftMem8 ( const mem_t src, int count )
  711. { return ExtractMem8(src,0,count); }
  712. static mem_t RightMem8 ( const mem_t src, int count )
  713. { return ExtractEndMem8(src,-count,0); }
  714. //-----------------------------------------------------------------------------
  715. // Alloc dest buffer and terminate with 0.
  716. // If m*.len < 0, then use strlen().
  717. mem_t MemCat2A ( const mem_t m1, const mem_t m2 );
  718. mem_t MemCat3A ( const mem_t m1, const mem_t m2, const mem_t m3 );
  719. mem_t MemCatSep2A ( const mem_t sep, const mem_t m1, const mem_t m2 );
  720. mem_t MemCatSep3A ( const mem_t sep, const mem_t m1, const mem_t m2, const mem_t m3 );
  721. //-----------------------------------------------------------------------------
  722. int CmpMem ( const mem_t s1, const mem_t s2 );
  723. int StrCmpMem ( const mem_t mem, ccp str );
  724. bool LeftStrCmpMemEQ ( const mem_t mem, ccp str );
  725. static inline void FreeMem ( mem_t *mem )
  726. {
  727. DASSERT(mem);
  728. FreeString(mem->ptr);
  729. mem->ptr = 0;
  730. mem->len = 0;
  731. }
  732. static inline void AssignDupMem ( mem_t *dest, mem_t src )
  733. {
  734. DASSERT(dest);
  735. FreeString(dest->ptr);
  736. dest->ptr = MEMDUP(src.ptr,src.len);
  737. dest->len = src.len;
  738. }
  739. static inline mem_t DupMem ( const mem_t src )
  740. {
  741. mem_t res = { MEMDUP(src.ptr,src.len), src.len };
  742. return res;
  743. }
  744. static inline char * DupStrMem ( const mem_t src )
  745. {
  746. return MEMDUP(src.ptr,src.len);
  747. }
  748. //
  749. ///////////////////////////////////////////////////////////////////////////////
  750. /////////////// struct exmem_t ///////////////
  751. ///////////////////////////////////////////////////////////////////////////////
  752. // [[exmem_t]]
  753. typedef struct exmem_t
  754. {
  755. mem_t data; // pointer and size of data
  756. u32 attrib; // user defined attribute
  757. bool is_original; // true: 'data' is a copy of source
  758. bool is_circ_buf; // true: 'data' is part of circ-buf
  759. bool is_alloced; // true: 'data' is alloced (not circ-buf)
  760. bool is_key_alloced; // true: external key is alloced
  761. }
  762. exmem_t;
  763. extern exmem_t EmptyExMem; // mem_t(EmptyString,0),false,false
  764. extern exmem_t NullExMem; // mem_t(0,0),false,false
  765. //-----------------------------------------------------------------------------
  766. // [[exmem_dest_t]]
  767. typedef struct exmem_dest_t
  768. {
  769. char *buf; // Dest buffer. If NULL then alloc buffer.
  770. uint buf_size; // Size of 'buf'. If too small then alloc buffer.
  771. bool try_circ; // TRUE: Use circ-buffer, if result is small enough.
  772. }
  773. exmem_dest_t;
  774. // Get a buffer by settings. The returned buffer is always large enough
  775. // to store len+1 bytes. If dest==NULL: Force MALLOC()
  776. exmem_t GetExmemDestBuf ( const exmem_dest_t * dest, uint len );
  777. //-----------------------------------------------------------------------------
  778. // constructors
  779. static inline exmem_t ExMemByChar ( char ch )
  780. {
  781. exmem_t em = { .data={ &ch, 1 }, .is_original=true };
  782. return em;
  783. }
  784. static inline exmem_t ExMemByString0 ( ccp str )
  785. {
  786. if (!str)
  787. return NullExMem;
  788. exmem_t em = { .data={ str, strlen(str) }, .is_original=true };
  789. return em;
  790. }
  791. static inline exmem_t ExMemByString ( ccp str )
  792. {
  793. exmem_t em = { .data={ str, str ? strlen(str) : 0 }, .is_original=true };
  794. return em;
  795. }
  796. static inline exmem_t ExMemByStringS ( ccp str, int len )
  797. {
  798. exmem_t em = { .data={ str, !str ? 0 : len < 0 ? strlen(str) : len }, .is_original=true };
  799. return em;
  800. }
  801. static inline exmem_t ExMemByStringE ( ccp str, ccp end )
  802. {
  803. exmem_t em = { .data={ str, !str ? 0 : end ? end-str : strlen(str) }, .is_original=true };
  804. return em;
  805. }
  806. static inline exmem_t ExMemByS ( cvp str, int len )
  807. {
  808. exmem_t em = { .data={ str, len }, .is_original=true };
  809. return em;
  810. }
  811. static inline exmem_t ExMemByE ( cvp str, cvp end )
  812. {
  813. exmem_t em = { .data={ str, (u8*)end-(u8*)str }, .is_original=true };
  814. return em;
  815. }
  816. static inline exmem_t ExMemCalloc ( int size )
  817. {
  818. char *data = CALLOC(size,1);
  819. exmem_t em = { .data={ data, size }, .is_original=true, .is_alloced=true };
  820. return em;
  821. }
  822. static inline exmem_t ExMemDup ( cvp src, int size )
  823. {
  824. char *data = MEMDUP(src,size);
  825. exmem_t em = { .data={ data, size+1 }, .is_original=true, .is_alloced=true };
  826. return em;
  827. }
  828. //-----------------------------------------------------------------------------
  829. exmem_t ExMemCat
  830. (
  831. exmem_dest_t *dest, // kind of destination, if NULL then MALLOC()
  832. mem_t sep, // insert separators between sources with len>0
  833. const mem_src_t *src // sources. NULL allowed
  834. );
  835. exmem_t ExMemCat2
  836. (
  837. exmem_dest_t *dest, // kind of destination, if NULL then MALLOC()
  838. mem_t sep, // insert separators between sources with len>0
  839. mem_t src1, // first source
  840. mem_t src2 // second source
  841. );
  842. exmem_t ExMemCat3
  843. (
  844. exmem_dest_t *dest, // kind of destination, if NULL then MALLOC()
  845. mem_t sep, // insert separators between sources with len>0
  846. mem_t src1, // first source
  847. mem_t src2, // second source
  848. mem_t src3 // third source
  849. );
  850. //-----------------------------------------------------------------------------
  851. // interface
  852. // 'em' can be modified ignoring 'const'
  853. void ResetExMem ( const exmem_t *em );
  854. void FreeExMem ( const exmem_t *em );
  855. void FreeExMemCM ( const exmem_t *em, CopyMode_t copy_mode ); // free on CPM_MOVE
  856. exmem_t AllocExMemS
  857. (
  858. cvp src, // NULL or source
  859. int src_len, // len of 'src'; if -1: use strlen(source)
  860. bool try_circ, // use circ-buffer, if result is small enough
  861. cvp orig, // NULL or data to compare
  862. int orig_len // len of 'orig'; if -1: use strlen(source)
  863. );
  864. static inline exmem_t AllocExMemM ( mem_t src, bool try_circ, mem_t orig )
  865. { return AllocExMemS(src.ptr,src.len,try_circ,orig.ptr,orig.len); }
  866. void AssignExMem ( exmem_t *dest, const exmem_t *source, CopyMode_t copy_mode );
  867. void AssignExMemS ( exmem_t *dest, cvp source, int slen, CopyMode_t copy_mode );
  868. static inline exmem_t CopyExMem ( const exmem_t *source, CopyMode_t copy_mode )
  869. { exmem_t em = {{0}}; AssignExMem(&em,source,copy_mode); return em; }
  870. static inline exmem_t CopyExMemS ( cvp source, int slen, CopyMode_t copy_mode )
  871. { exmem_t em = {{0}}; AssignExMemS(&em,source,slen,copy_mode); return em; }
  872. static inline exmem_t CopyExMemM ( const mem_t source, CopyMode_t copy_mode )
  873. { exmem_t em = {{0}}; AssignExMemS(&em,source.ptr,source.len,copy_mode); return em; }
  874. ccp PrintExMem ( const exmem_t * em ); // print to circ-buf
  875. //
  876. ///////////////////////////////////////////////////////////////////////////////
  877. /////////////// struct mem_list_t ///////////////
  878. ///////////////////////////////////////////////////////////////////////////////
  879. // [[mem_list_t]]
  880. typedef struct mem_list_t
  881. {
  882. mem_t *list; // List of mem_t objects.
  883. // Elements are always terminated with NULL.
  884. // Content is NULL or EmptyString or stored in 'buf'
  885. uint used; // Number of active 'list' elements
  886. uint size; // Number of alloced 'list' elements
  887. char *buf; // Alloced temp buffer
  888. uint buf_used; // Usage of 'buf'
  889. uint buf_size; // Size of 'buf'
  890. }
  891. mem_list_t;
  892. //-----------------------------------------------------------------------------
  893. // [[mem_list_mode_t]]
  894. typedef enum mem_list_mode_t
  895. {
  896. MEMLM_ALL, // insert all
  897. MEMLM_IGN_NULL, // ignore NULL
  898. MEMLM_IGN_EMPTY, // ignore NULL and empty
  899. MEMLM_REPL_NULL, // replace NULL by EmptyString
  900. }
  901. mem_list_mode_t;
  902. //-----------------------------------------------------------------------------
  903. static inline void InitializeMemList ( mem_list_t *ml )
  904. { DASSERT(ml); memset(ml,0,sizeof(*ml)); }
  905. void ResetMemList ( mem_list_t *ml );
  906. void MoveMemList ( mem_list_t *dest, mem_list_t *src );
  907. void NeedBufMemList ( mem_list_t *ml, uint need_size, uint extra_size );
  908. void NeedElemMemList ( mem_list_t *ml, uint n_elem, uint need_size );
  909. //-----------------------------------------------------------------------------
  910. void InsertMemListN
  911. (
  912. mem_list_t *ml, // valid destination mem_list
  913. int pos, // insert position => CheckIndex1()
  914. const mem_t *src, // source list
  915. uint src_len, // number of elements in source list
  916. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  917. );
  918. //-----------------------------------------------------------------------------
  919. static inline void InsertMemList2
  920. (
  921. mem_list_t *ml, // valid destination mem_list
  922. int pos, // insert position => CheckIndex1()
  923. const mem_list_t *src, // source mem_list
  924. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  925. )
  926. {
  927. DASSERT(src);
  928. InsertMemListN(ml,pos,src->list,src->used,src_ignore);
  929. }
  930. //-----------------------------------------------------------------------------
  931. static inline void AppendMemListN
  932. (
  933. mem_list_t *ml, // valid destination mem_list
  934. const mem_t *src, // source list
  935. uint src_len, // number of elements in source list
  936. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  937. )
  938. {
  939. DASSERT(ml);
  940. InsertMemListN(ml,ml->used,src,src_len,src_ignore);
  941. }
  942. //-----------------------------------------------------------------------------
  943. static inline void AppendMemList2
  944. (
  945. mem_list_t *ml, // valid destination mem_list
  946. const mem_list_t *src, // source mem_list
  947. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  948. )
  949. {
  950. DASSERT(ml);
  951. DASSERT(src);
  952. InsertMemListN(ml,ml->used,src->list,src->used,src_ignore);
  953. }
  954. //-----------------------------------------------------------------------------
  955. static inline void AssignMemListN
  956. (
  957. mem_list_t *ml, // valid destination mem_list
  958. const mem_t *src, // source list
  959. uint src_len, // number of elements in source list
  960. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  961. )
  962. {
  963. DASSERT(ml);
  964. ml->used = 0;
  965. InsertMemListN(ml,0,src,src_len,src_ignore);
  966. }
  967. //-----------------------------------------------------------------------------
  968. static inline void AssignMemList2
  969. (
  970. mem_list_t *ml, // valid destination mem_list
  971. const mem_list_t *src, // source mem_list
  972. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  973. )
  974. {
  975. DASSERT(ml);
  976. DASSERT(src);
  977. ml->used = 0;
  978. InsertMemListN(ml,0,src->list,src->used,src_ignore);
  979. }
  980. ///////////////////////////////////////////////////////////////////////////////
  981. void CatMemListN
  982. (
  983. mem_list_t *dest, // valid destination mem_list
  984. const mem_list_t **src_list, // list with mem lists, element may be NULL
  985. uint n_src_list, // number of elements in 'src'
  986. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  987. );
  988. //-----------------------------------------------------------------------------
  989. static inline void CatMemList2
  990. (
  991. mem_list_t *dest, // valid destination mem_list
  992. const mem_list_t *src1, // source mem_list
  993. const mem_list_t *src2, // source mem_list
  994. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  995. )
  996. {
  997. const mem_list_t *ml[2] = { src1, src2 };
  998. CatMemListN(dest,ml,2,src_ignore);
  999. }
  1000. //-----------------------------------------------------------------------------
  1001. static inline void CatMemList3
  1002. (
  1003. mem_list_t *dest, // valid destination mem_list
  1004. const mem_list_t *src1, // source mem_list
  1005. const mem_list_t *src2, // source mem_list
  1006. const mem_list_t *src3, // source mem_list
  1007. mem_list_mode_t src_ignore // how to manage NULL and empty strings
  1008. )
  1009. {
  1010. const mem_list_t *ml[3] = { src1, src2, src3 };
  1011. CatMemListN(dest,ml,3,src_ignore);
  1012. }
  1013. //-----------------------------------------------------------------------------
  1014. // All functions are robust and modify the current list.
  1015. // A negative index is relative to the end of source.
  1016. // For RightMemList() and *EndMemList(), index 0 means: end of source.
  1017. // count<0 means: copy left from 'begin' (only MidMemList()) or skip bytes.
  1018. // All functions return the number of elements aufer operation.
  1019. uint LeftMemList ( mem_list_t *ml, int count );
  1020. uint RightMemList ( mem_list_t *ml, int count );
  1021. uint MidMemList ( mem_list_t *ml, int begin, int count );
  1022. uint ExtractMemList ( mem_list_t *ml, int begin, int end );
  1023. uint ExtractEndMemList ( mem_list_t *ml, int begin, int end );
  1024. uint RemoveMemList ( mem_list_t *ml, int begin, int end );
  1025. uint RemoveEndMemList ( mem_list_t *ml, int begin, int end );
  1026. //
  1027. ///////////////////////////////////////////////////////////////////////////////
  1028. /////////////// MemPool_t ///////////////
  1029. ///////////////////////////////////////////////////////////////////////////////
  1030. // [[MemPoolChunk_t]]
  1031. typedef struct MemPoolChunk_t
  1032. {
  1033. struct MemPoolChunk_t *next;
  1034. char data[];
  1035. }
  1036. MemPoolChunk_t;
  1037. //-----------------------------------------------------------------------------
  1038. // [[MemPool_t]]
  1039. typedef struct MemPool_t
  1040. {
  1041. MemPoolChunk_t *chunk; // pointer to first (=current) chunk
  1042. uint space; // space left in current chunk
  1043. uint chunk_size; // wanted chunk size
  1044. }
  1045. MemPool_t;
  1046. //-----------------------------------------------------------------------------
  1047. static inline void InitializeMemPool ( MemPool_t *mp, uint chunk_size )
  1048. { DASSERT(mp); memset(mp,0,sizeof(*mp)); mp->chunk_size = chunk_size; }
  1049. void ResetMemPool ( MemPool_t *mp );
  1050. void * MallocMemPool ( MemPool_t *mp, uint size );
  1051. void * CallocMemPool ( MemPool_t *mp, uint size );
  1052. void * MallocMemPoolA ( MemPool_t *mp, uint size, uint align );
  1053. void * CallocMemPoolA ( MemPool_t *mp, uint size, uint align );
  1054. void * MemDupMemPool ( MemPool_t *mp, cvp source, uint size );
  1055. static inline void * StrDupMemPool ( MemPool_t *mp, ccp source )
  1056. { DASSERT(mp); return source ? MemDupMemPool(mp,source,strlen(source)) : 0; }
  1057. //
  1058. ///////////////////////////////////////////////////////////////////////////////
  1059. /////////////// CircBuf_t ///////////////
  1060. ///////////////////////////////////////////////////////////////////////////////
  1061. // [[CircBuf_t]]
  1062. typedef struct CircBuf_t
  1063. {
  1064. char *buf; // NULL or alloced buffer
  1065. uint pos; // position of first valid byte
  1066. uint used; // used bytes in buffer
  1067. uint size; // size of 'buf'
  1068. }
  1069. CircBuf_t;
  1070. ///////////////////////////////////////////////////////////////////////////////
  1071. void InitializeCircBuf ( CircBuf_t *cb, uint size );
  1072. void ResetCircBuf ( CircBuf_t *cb );
  1073. uint WriteCircBuf ( CircBuf_t *cb, cvp data, uint size );
  1074. uint PeakCircBuf ( CircBuf_t *cb, char *buf, uint buf_size );
  1075. uint ReadCircBuf ( CircBuf_t *cb, char *buf, uint buf_size );
  1076. uint DropCircBuf ( CircBuf_t *cb, uint size );
  1077. void ClearCircBuf ( CircBuf_t *cb );
  1078. uint PurgeCircBuf ( CircBuf_t *cb );
  1079. //
  1080. ///////////////////////////////////////////////////////////////////////////////
  1081. /////////////// PrintMode_t ///////////////
  1082. ///////////////////////////////////////////////////////////////////////////////
  1083. // [[PrintMode_t]]
  1084. typedef struct PrintMode_t
  1085. {
  1086. FILE *fout; // NULL (stdout) or output file
  1087. const ColorSet_t
  1088. *cout; // NULL (no colors) or color set for 'fout'
  1089. FILE *ferr; // NULL or error file
  1090. const ColorSet_t
  1091. *cerr; // NULL (no colors) or color set for 'ferr'
  1092. FILE *flog; // if NULL: use 'ferr' or 'fout' as fallback
  1093. const ColorSet_t
  1094. *clog; // NULL (no colors) or color set for 'flog'
  1095. // if 'flog' is copied, use related 'col*'
  1096. ccp prefix; // NULL (no prefix) or line prefix
  1097. ccp eol; // NULL (LF) or end-of-line string
  1098. int indent; // indention after prefix
  1099. int debug; // debug level (ignored if <=0)
  1100. int mode; // user defined print mode
  1101. bool compact; // TRUE: print compact (e.g. no empty lines for readability)
  1102. }
  1103. PrintMode_t;
  1104. void SetupPrintMode ( PrintMode_t * pm );
  1105. //
  1106. ///////////////////////////////////////////////////////////////////////////////
  1107. /////////////// split strings ///////////////
  1108. ///////////////////////////////////////////////////////////////////////////////
  1109. uint SplitByCharMem
  1110. (
  1111. // 'mem_list' will be padded with {EmptyString,0}
  1112. mem_t *mem_list, // array of mem_t
  1113. uint n_mem, // number of elements of 'mem_list'
  1114. mem_t source, // source string
  1115. char sep // separator character
  1116. );
  1117. //-----------------------------------------------------------------------------
  1118. uint SplitByTextMem
  1119. (
  1120. // 'mem_list' will be padded with {EmptyString,0}
  1121. mem_t *mem_list, // array of mem_t
  1122. uint n_mem, // number of elements of 'mem_list'
  1123. mem_t source, // source string
  1124. mem_t sep // separator text
  1125. );
  1126. //-----------------------------------------------------------------------------
  1127. uint SplitByCharMemList
  1128. (
  1129. mem_list_t *ml, // valid destination mem_list
  1130. bool init_ml, // true: initialize 'ml' first
  1131. mem_t source, // source string
  1132. char sep, // separator character
  1133. int max_fields // >0: max number of result fields
  1134. );
  1135. //-----------------------------------------------------------------------------
  1136. uint SplitByTextMemList
  1137. (
  1138. mem_list_t *ml, // valid destination mem_list
  1139. bool init_ml, // true: initialize 'ml' first
  1140. mem_t source, // source string
  1141. mem_t sep, // separator text
  1142. int max_fields // >0: max number of result fields
  1143. );
  1144. //
  1145. ///////////////////////////////////////////////////////////////////////////////
  1146. /////////////// alloc info ///////////////
  1147. ///////////////////////////////////////////////////////////////////////////////
  1148. extern bool alloc_info_calced;
  1149. extern uint alloc_info_overhead;
  1150. extern uint alloc_info_block_size;
  1151. extern uint alloc_info_add1;
  1152. extern uint alloc_info_add2;
  1153. extern uint alloc_info_mask;
  1154. ///////////////////////////////////////////////////////////////////////////////
  1155. uint SetupAllocInfo(void);
  1156. static inline uint GetGoodAllocSize ( uint need )
  1157. {
  1158. return ( need + alloc_info_add1 & alloc_info_mask )
  1159. + alloc_info_add2;
  1160. }
  1161. static inline uint GetGoodAllocSize2 ( uint n_elem, uint itemsize )
  1162. {
  1163. return (( n_elem*itemsize + alloc_info_add1 & alloc_info_mask )
  1164. + alloc_info_add2 ) / itemsize;
  1165. }
  1166. static inline uint GetGoodAllocSizeA ( uint need, uint align )
  1167. {
  1168. need = ( need + align - 1) / align * align;
  1169. return (( need + alloc_info_add1 & alloc_info_mask )
  1170. + alloc_info_add2 ) / align * align;
  1171. }
  1172. //
  1173. ///////////////////////////////////////////////////////////////////////////////
  1174. /////////////// basic string functions ///////////////
  1175. ///////////////////////////////////////////////////////////////////////////////
  1176. extern const char EmptyQuote[]; // »""« Ignored by FreeString()
  1177. extern const char EmptyString[4]; // »« + 4*NULL, Ignored by FreeString()
  1178. extern const char MinusString[4]; // »-« + 3*NULL, Ignored by FreeString()
  1179. extern const char LoDigits[0x41]; // 0-9 a-z A-Z .+ NULL
  1180. extern const char HiDigits[0x41]; // 0-9 A-Z a-z .+ NULL
  1181. extern const char Tabs20[21]; // 20 * TAB + NULL
  1182. extern const char LF20[21]; // 20 * LF + NULL
  1183. extern const char Space200[201]; // 200 * ' ' + NULL
  1184. extern const char Minus300[301]; // 300 * '-' + NULL
  1185. extern const char Underline200[201]; // 200 * '_' + NULL
  1186. extern const char Hash200[201]; // 200 * '#' + NULL
  1187. extern const char Slash200[201]; // 200 * '/' + NULL
  1188. // UTF-8 => 3 bytes per char
  1189. extern const char ThinLine300_3[901]; // 300 * '─' (U+2500) + NULL
  1190. extern const char DoubleLine300_3[901]; // 300 * '═' (U+2550) + NULL
  1191. //-----------------------------------------------------------------------------
  1192. void SetupMultiProcessing(void);
  1193. void PrintSettingsDCLIB ( FILE *f, int indent );
  1194. void SetupProgname ( int argc, char ** argv,
  1195. ccp tool_name, ccp tool_vers, ccp tool_title );
  1196. // return NULL or 'ProgInfo.progpath', calc GetProgramPath() once if needed
  1197. ccp ProgramPath(void);
  1198. // return NULL or 'ProgInfo.progdir', calc ProgramPath() once if needed
  1199. ccp ProgramDirectory(void);
  1200. // path0 can be a directory or a filename (->dir extracted)
  1201. void DefineLogDirectory ( ccp path0, bool force );
  1202. // get 'ProgInfo.logdir' without tailing '/' ("." as fall back)
  1203. ccp GetLogDirectory(void);
  1204. #ifdef __CYGWIN__
  1205. ccp ProgramPathNoExt(void);
  1206. #else
  1207. static inline ccp ProgramPathNoExt(void) { return ProgramPath(); }
  1208. #endif
  1209. int GetProgramPath
  1210. (
  1211. // returns strlen(buf) on success, -1 on failure
  1212. char *buf, // buffer for the result; empty string on failure.
  1213. uint buf_size, // size of buffer
  1214. bool check_proc, // true: read files of /proc/... to find path
  1215. ccp argv0 // not NULL: analyse this argument (argv[0])
  1216. );
  1217. //-----
  1218. // StringCopy*(), StringCat*()
  1219. // RESULT: end of copied string pointing to a NULL character.
  1220. // 'src*' may be a NULL pointer.
  1221. // MAX_COPY define max number of bytes to copy.
  1222. // It's only relevant if src is longer.
  1223. // If MAX_COPY<0: ignore it.
  1224. // SRC_LEN is the length of src (or the number of bytes to copy)
  1225. // If SRC_LEN<0: use strlen(src)
  1226. char * StringCopyS ( char *buf, ssize_t buf_size, ccp src );
  1227. char * StringCopySM ( char *buf, ssize_t buf_size, ccp src, ssize_t max_copy );
  1228. char * StringCopySL ( char *buf, ssize_t buf_size, ccp src, ssize_t src_len );
  1229. static inline char * StringCopyE ( char * buf, ccp buf_end, ccp src )
  1230. { return StringCopyS(buf,buf_end-buf,src); }
  1231. static inline char * StringCopyEM ( char *buf, ccp buf_end, ccp src, ssize_t max_copy )
  1232. { return StringCopySM(buf,buf_end-buf,src,max_copy ); }
  1233. static inline char * StringCopyEL ( char *buf, ccp buf_end, ccp src, ssize_t src_len )
  1234. { return StringCopySL(buf,buf_end-buf,src,src_len ); }
  1235. // concat sources, *A(): use MALLOC()
  1236. char * StringCat2S ( char *buf, ssize_t buf_size, ccp src1, ccp src2 );
  1237. char * StringCat3S ( char *buf, ssize_t buf_size, ccp src1, ccp src2, ccp src3 );
  1238. char * StringCat2E ( char *buf, ccp buf_end, ccp src1, ccp src2 );
  1239. char * StringCat3E ( char *buf, ccp buf_end, ccp src1, ccp src2, ccp src3 );
  1240. char * StringCat2A ( ccp src1, ccp src2 );
  1241. char * StringCat3A ( ccp src1, ccp src2, ccp src3 );
  1242. // like above, but cat with separators
  1243. char * StringCatSep2S ( char *buf, ssize_t bufsize, ccp sep, ccp src1, ccp src2 );
  1244. char * StringCatSep3S ( char *buf, ssize_t bufsize, ccp sep, ccp src1, ccp src2, ccp src3 );
  1245. char * StringCatSep2E ( char *buf, ccp buf_end, ccp sep, ccp src1, ccp src2 );
  1246. char * StringCatSep3E ( char *buf, ccp buf_end, ccp sep, ccp src1, ccp src2, ccp src3 );
  1247. char * StringCatSep2A ( ccp sep, ccp src1, ccp src2 );
  1248. char * StringCatSep3A ( ccp sep, ccp src1, ccp src2, ccp src3 );
  1249. // center string
  1250. ccp StringCenterE ( char * buf, ccp buf_end, ccp src, int width );
  1251. static inline ccp StringCenterS ( char *buf, ssize_t bufsize, ccp src, int width )
  1252. { return StringCenterE(buf,buf+bufsize,src,width); }
  1253. static inline char * StringCopySMem ( char *buf, ssize_t bufsize, mem_t mem )
  1254. { return StringCopySM(buf,bufsize,mem.ptr,mem.len); }
  1255. static inline char * StringCopyEMem ( char *buf, ccp buf_end, mem_t mem )
  1256. { return StringCopyEM(buf,buf_end,mem.ptr,mem.len); }
  1257. char * StringLowerS ( char * buf, ssize_t bufsize, ccp src );
  1258. char * StringLowerE ( char * buf, ccp buf_end, ccp src );
  1259. char * StringUpperS ( char * buf, ssize_t bufsize, ccp src );
  1260. char * StringUpperE ( char * buf, ccp buf_end, ccp src );
  1261. char * MemLowerE ( char * buf, ccp buf_end, mem_t src );
  1262. char * MemLowerS ( char * buf, ssize_t bufsize, mem_t src );
  1263. char * MemUpperE ( char * buf, ccp buf_end, mem_t src );
  1264. char * MemUpperS ( char * buf, ssize_t bufsize, mem_t src );
  1265. // special handling for unsigned decimals
  1266. int StrNumCmp ( ccp a, ccp b );
  1267. // count the number of equal bytes and return a value of 0 to SIZE
  1268. uint CountEqual ( cvp m1, cvp m2, uint size );
  1269. // skip ESC & well known escape sequences (until noc-escape)
  1270. char * SkipEscapes ( ccp str );
  1271. char * SkipEscapesE ( ccp str, ccp end );
  1272. char * SkipEscapesS ( ccp str, int size );
  1273. mem_t SkipEscapesM ( mem_t mem );
  1274. // Concatenate path + path, return pointer to buf
  1275. // Return pointer to buf or path1|path2|buf or alloced string
  1276. char *PathCatBufPP ( char *buf, ssize_t bufsize, ccp path1, ccp path2 );
  1277. char *PathCatBufPPE ( char *buf, ssize_t bufsize, ccp path1, ccp path2, ccp ext );
  1278. ccp PathCatPP ( char *buf, ssize_t bufsize, ccp path1, ccp path2 );
  1279. //ccp PathCatPPE ( char *buf, ssize_t bufsize, ccp path1, ccp path2, ccp ext );
  1280. ccp PathAllocPP ( ccp path1, ccp path2 );
  1281. ccp PathAllocPPE ( ccp path1, ccp path2, ccp ext );
  1282. // inline wrapper
  1283. static inline ccp PathCatPPE ( char *buf, ssize_t bufsize, ccp path1, ccp path2, ccp ext )
  1284. { return PathCatBufPPE(buf,bufsize,path1,path2,ext); }
  1285. // like PathCatPP(), but ignores path2, if path1 is not empty and not a directory
  1286. ccp PathCatDirP ( char * buf, ssize_t bufsize, ccp path1, ccp path2 );
  1287. // Same as PathCatPP*(), but use 'base' as prefix for relative paths.
  1288. // If 'base' is NULL (but not empty), use getcwd() instead.
  1289. // PathCatBufBP() and PathCatBP() are special: path can be part of buf
  1290. char *PathCatBufBP ( char *buf, ssize_t bufsize, ccp base, ccp path );
  1291. char *PathCatBufBPP ( char *buf, ssize_t bufsize, ccp base, ccp path1, ccp path2 );
  1292. char *PathCatBufBPPE ( char *buf, ssize_t bufsize, ccp base, ccp path1, ccp path2, ccp ext );
  1293. ccp PathCatBP ( char *buf, ssize_t bufsize, ccp base, ccp path );
  1294. ccp PathCatBPP ( char *buf, ssize_t bufsize, ccp base, ccp path1, ccp path2 );
  1295. ccp PathCatBPPE ( char *buf, ssize_t bufsize, ccp base, ccp path1, ccp path2, ccp ext );
  1296. ccp PathAllocBP ( ccp base, ccp path );
  1297. ccp PathAllocBPP ( ccp base, ccp path1, ccp path2 );
  1298. ccp PathAllocBPPE ( ccp base, ccp path1, ccp path2, ccp ext );
  1299. char * PathCombine ( char *temp_buf, uint buf_size, ccp path, ccp base_path );
  1300. char * PathCombineFast ( char *dest_buf, uint buf_size, ccp path, ccp base_path );
  1301. // Remove last extension and add a new one.
  1302. // If ext==NULL or emtpy: remove only
  1303. // 'ext' may start with '.'. If not, a additional '.' is included
  1304. // If 'path' is NULL or path==buf: Inplace job using 'buf' as source.
  1305. char * NewFileExtE ( char * buf, ccp buf_end, ccp path, ccp ext );
  1306. char * NewFileExtS ( char * buf, ssize_t bufsize, ccp path, ccp ext );
  1307. // eliminate leading './' before comparing
  1308. int StrPathCmp ( ccp path1, ccp path2 );
  1309. int PathCmp
  1310. (
  1311. ccp path1, // NULL or first path
  1312. ccp path2, // NULL or second path
  1313. uint mode // bit field:
  1314. // 1: skip (multiple) leading './'
  1315. // 2: compare case insensitive
  1316. // 4: sort with respect for unsigned decimal numbers
  1317. );
  1318. int ReplaceToBuf
  1319. (
  1320. // returns -1 on error (buf to small) or the length of the resulting string.
  1321. // In the later case, a 0 byte is appended, but not counting for the length.
  1322. char *buf, // pointer to buf
  1323. uint buf_size, // size of 'buf'
  1324. ccp src1, // NULL or source, maybe part of 'buf'
  1325. int src1_len, // length of 'src1', if -1: determine by strlen()
  1326. int pos, // robust replace position, <0: relative to end
  1327. int rm_len, // robust num of chars to remove, <0: rm before 'pos'
  1328. ccp src2, // NULL or source to insert, must not be part of 'buf'
  1329. int src2_len // lengh of 'src2', if -1: determine by strlen()
  1330. );
  1331. int NormalizeIndent ( int indent );
  1332. //-----------------------------------------------------
  1333. // skips all character 1..SPACE; 'src' can be NULL
  1334. char * SkipControls ( ccp src );
  1335. // skips all character 0..SPACE; if end==NULL: Use SkipControls(); 'src' can be NULL
  1336. char * SkipControlsE ( ccp src, ccp end );
  1337. // same as above, but skip also 'ch1'; 'src' can be NULL
  1338. char * SkipControls1 ( ccp src, char ch1 );
  1339. char * SkipControlsE1 ( ccp src, ccp end, char ch1 );
  1340. // same as above, but skip also 'ch1' and 'ch2'; 'src' can be NULL
  1341. char * SkipControls2 ( ccp src, char ch1, char ch2 );
  1342. char * SkipControlsE2 ( ccp src, ccp end, char ch1, char ch2 );
  1343. //-----------------------------------------------------
  1344. // return the number of chars until first EOL ( \0 | \r | \n );
  1345. // pointer are NULL save
  1346. uint LineLen ( ccp ptr );
  1347. uint LineLenE ( ccp ptr, ccp end );
  1348. //-----------------------------------------------------
  1349. uint TrimBlanks
  1350. (
  1351. char *str, // pointer to string, modified
  1352. ccp end // NULL or end of string
  1353. );
  1354. char * ScanName
  1355. (
  1356. // return a pointer to the first unused character
  1357. char *buf, // destination buffer, terminated with NULL
  1358. uint buf_size, // size of 'buf', must be >0
  1359. ccp str, // source string
  1360. ccp end, // NULL or end of 'str'
  1361. bool allow_signs // true: allow '-' and '+'
  1362. );
  1363. //-----------------------------------------------------
  1364. // Format of version number: AABBCCDD = A.BB | A.BB.CC
  1365. // If D != 0x00 && D != 0xff => append: 'beta' D
  1366. //-----------------------------------------------------
  1367. char * PrintVersion
  1368. (
  1369. char * buf, // result buffer
  1370. // If NULL, a local circulary static buffer is used
  1371. size_t buf_size, // size of 'buf', ignored if buf==NULL
  1372. u32 version // version number to print
  1373. );
  1374. char * PrintID
  1375. (
  1376. const void * id, // ID to convert in printable format
  1377. size_t id_len, // len of 'id'
  1378. void * buf // Pointer to buffer, size >= id_len + 1
  1379. // If NULL, a local circulary static buffer is used
  1380. );
  1381. //
  1382. ///////////////////////////////////////////////////////////////////////////////
  1383. /////////////// circ buf ///////////////
  1384. ///////////////////////////////////////////////////////////////////////////////
  1385. // [[CircBuf]]
  1386. #define CIRC_BUF_MAX_ALLOC 0x0400 // request limit
  1387. #define CIRC_BUF_SIZE 0x4000 // internal buffer size
  1388. // returns true if 'ptr' points into circ buffer => ignored by FreeString()
  1389. bool IsCircBuf ( cvp ptr );
  1390. //-----------------------------------------------------------------------------
  1391. char * GetCircBuf
  1392. (
  1393. // Never returns NULL, but always ALIGN(4)
  1394. u32 buf_size // wanted buffer size, caller must add 1 for NULL-term
  1395. // if buf_size > CIRC_BUF_MAX_ALLOC:
  1396. // ==> ERROR0(ERR_OUT_OF_MEMORY)
  1397. );
  1398. static inline wchar_t * GetCircBufW
  1399. (
  1400. // Never returns NULL, but always ALIGN(4)
  1401. u32 buf_size // wanted buffer size (wchar elements),
  1402. // caller must add 1 for NULL-term
  1403. // if final buf_size > CIRC_BUF_MAX_ALLOC:
  1404. // ==> ERROR0(ERR_OUT_OF_MEMORY)
  1405. )
  1406. {
  1407. return (wchar_t*)GetCircBuf(buf_size*sizeof(wchar_t));
  1408. }
  1409. //-----------------------------------------------------------------------------
  1410. char * CopyCircBuf
  1411. (
  1412. // Never returns NULL, but always ALIGN(4)
  1413. cvp data, // source to copy
  1414. u32 data_size // see GetCircBuf()
  1415. );
  1416. char * CopyCircBuf0
  1417. (
  1418. // Like CopyCircBuf(), but an additional char is alloced and set to NULL
  1419. // Never returns NULL, but always ALIGN(4).
  1420. cvp data, // source to copy
  1421. u32 data_size // see GetCircBuf()
  1422. );
  1423. char * PrintCircBuf
  1424. (
  1425. // returns CopyCircBuf0() or EmptyString.
  1426. ccp format, // format string for vsnprintf()
  1427. ... // arguments for 'format'
  1428. )
  1429. __attribute__ ((__format__(__printf__,1,2)));
  1430. char * AllocCircBuf
  1431. (
  1432. // Never returns NULL. Call FreeString(RESULT) to free possible alloced memory.
  1433. cvp src, // NULL or source
  1434. int src_len, // len of 'src'; if -1: use strlen(source)
  1435. bool try_circ // use circ-buffer, if result is small enough
  1436. );
  1437. char * AllocCircBuf0
  1438. (
  1439. // Never returns NULL. Call FreeString(RESULT) to free possible alloced memory.
  1440. // Like AllocCircBuf(), but an additional char is alloced and set to NULL
  1441. cvp src, // NULL or source
  1442. int src_len, // len of 'src'; if -1: use strlen(source)
  1443. bool try_circ // use circ-buffer, if result is small enough
  1444. );
  1445. void ReleaseCircBuf
  1446. (
  1447. ccp end_buf, // pointer to end of previous alloced buffer
  1448. uint release_size // number of bytes to give back from end
  1449. );
  1450. //
  1451. ///////////////////////////////////////////////////////////////////////////////
  1452. /////////////// get line by list ///////////////
  1453. ///////////////////////////////////////////////////////////////////////////////
  1454. ccp GetLineByListHelper ( const int *list, ccp beg, ccp mid, ccp end, ccp line );
  1455. static inline ccp GetTopLineByList ( const int *list )
  1456. {
  1457. return GetLineByListHelper(list,"┌","┬","┐","─");
  1458. }
  1459. static inline ccp GetMidLineByList ( int *list )
  1460. {
  1461. return GetLineByListHelper(list,"├","┼","┤","─");
  1462. }
  1463. static inline ccp GetBottomLineByList ( int *list )
  1464. {
  1465. return GetLineByListHelper(list,"└","┴","┘","─");
  1466. }
  1467. //
  1468. ///////////////////////////////////////////////////////////////////////////////
  1469. /////////////// struct IntMode_t ///////////////
  1470. ///////////////////////////////////////////////////////////////////////////////
  1471. // [[IntMode_t]]
  1472. typedef enum IntMode_t
  1473. {
  1474. IMD_UNSET = 0, // default, always 0
  1475. //--- big endian modes
  1476. IMD_BE0, // default big endian
  1477. IMD_BE1,
  1478. IMD_BE2,
  1479. IMD_BE3,
  1480. IMD_BE4,
  1481. IMD_BE5,
  1482. IMD_BE6,
  1483. IMD_BE7,
  1484. IMD_BE8,
  1485. //--- little endian modes
  1486. IMD_LE0, // default little endian
  1487. IMD_LE1,
  1488. IMD_LE2,
  1489. IMD_LE3,
  1490. IMD_LE4,
  1491. IMD_LE5,
  1492. IMD_LE6,
  1493. IMD_LE7,
  1494. IMD_LE8,
  1495. //--- local endian modes
  1496. #ifdef LITTLE_ENDIAN
  1497. IMD_0 = IMD_LE0,
  1498. IMD_1 = IMD_LE1,
  1499. IMD_2 = IMD_LE2,
  1500. IMD_3 = IMD_LE3,
  1501. IMD_4 = IMD_LE4,
  1502. IMD_5 = IMD_LE5,
  1503. IMD_6 = IMD_LE6,
  1504. IMD_7 = IMD_LE7,
  1505. IMD_8 = IMD_LE8,
  1506. #else
  1507. IMD_0 = IMD_BE0,
  1508. IMD_1 = IMD_BE1,
  1509. IMD_2 = IMD_BE2,
  1510. IMD_3 = IMD_BE3,
  1511. IMD_4 = IMD_BE4,
  1512. IMD_5 = IMD_BE5,
  1513. IMD_6 = IMD_BE6,
  1514. IMD_7 = IMD_BE7,
  1515. IMD_8 = IMD_BE8,
  1516. #endif
  1517. }
  1518. __attribute__ ((packed)) IntMode_t;
  1519. //-----------------------------------------------------------------------------
  1520. ccp GetIntModeName ( IntMode_t mode );
  1521. //
  1522. ///////////////////////////////////////////////////////////////////////////////
  1523. /////////////// lt/eq/gt ///////////////
  1524. ///////////////////////////////////////////////////////////////////////////////
  1525. // [[compare_operator_t]]
  1526. typedef enum compare_operator_t
  1527. {
  1528. COP_LT = 1,
  1529. COP_EQ = 2,
  1530. COP_GT = 4,
  1531. COP_NE = COP_LT | COP_GT,
  1532. COP_LE = COP_LT | COP_EQ,
  1533. COP_GE = COP_GT | COP_EQ,
  1534. COP_FALSE = 0,
  1535. COP_TRUE = COP_LT | COP_EQ | COP_GT,
  1536. }
  1537. __attribute__ ((packed)) compare_operator_t;
  1538. //-----------------------------------------------------------------------------
  1539. char * ScanCompareOp ( compare_operator_t *dest_op, ccp arg );
  1540. ccp GetCompareOpName ( compare_operator_t op );
  1541. static inline compare_operator_t NegateCompareOp ( compare_operator_t op )
  1542. { return op ^ COP_TRUE; }
  1543. bool CompareByOpStat ( int stat, compare_operator_t op );
  1544. bool CompareByOpINT ( int a, compare_operator_t op, int b );
  1545. bool CompareByOpUINT ( uint a, compare_operator_t op, uint b );
  1546. bool CompareByOpI64 ( s64 a, compare_operator_t op, s64 b );
  1547. bool CompareByOpU64 ( u64 a, compare_operator_t op, u64 b );
  1548. bool CompareByOpFLT ( float a, compare_operator_t op, float b );
  1549. bool CompareByOpDBL ( double a, compare_operator_t op, double b );
  1550. static inline bool CompareByOpS ( ccp a, compare_operator_t op, ccp b )
  1551. { return CompareByOpStat(strcmp(a,b),op); }
  1552. //
  1553. ///////////////////////////////////////////////////////////////////////////////
  1554. /////////////// LOWER/AUTO/UPPER ///////////////
  1555. ///////////////////////////////////////////////////////////////////////////////
  1556. // [[LowerUpper_t]]
  1557. typedef enum LowerUpper_t
  1558. {
  1559. LOUP_ERROR = -99,
  1560. LOUP_LOWER = -1,
  1561. LOUP_AUTO = 0,
  1562. LOUP_UPPER = 1,
  1563. }
  1564. LowerUpper_t;
  1565. extern const KeywordTab_t KeyTab_LOWER_AUTO_UPPER[];
  1566. int ScanKeywordLowerAutoUpper
  1567. (
  1568. // returns one of LOUP_*
  1569. ccp arg, // argument to scan
  1570. int on_empty, // return this value on empty
  1571. uint max_num, // >0: additionally accept+return number <= max_num
  1572. ccp object // NULL (silent) or object for error messages
  1573. );
  1574. ccp GetKeywordLowerAutoUpper ( LowerUpper_t value );
  1575. //
  1576. ///////////////////////////////////////////////////////////////////////////////
  1577. /////////////// struct FastBuf_t ///////////////
  1578. ///////////////////////////////////////////////////////////////////////////////
  1579. // [[FastBuf_t]]
  1580. typedef struct FastBuf_t
  1581. {
  1582. char *buf; // pointer to buffer
  1583. char *ptr; // pointer to first unused char (always space for 0-term)
  1584. char *end; // pointer to end of buffer := buf+size-1
  1585. uint fast_buf_size; // size of 'fast_buf+space'
  1586. char fast_buf[4]; // first use buffer with minimal space
  1587. char space[]; // additional space
  1588. }
  1589. FastBuf_t;
  1590. ///////////////////////////////////////////////////////////////////////////////
  1591. //------------------------------------------------------------------
  1592. //
  1593. // 4 examples for initialization:
  1594. //
  1595. // FastBuf_t fb1;
  1596. // InitializeFastBufAlloc(&fb1,1000);
  1597. // printf("fb1: %s: %s\n", GetFastBufStatus(&fb1), fb1.buf );
  1598. //
  1599. // FastBuf_t fb2;
  1600. // InitializeFastBuf(&fb2,sizeof(fb2));
  1601. // printf("fb2: %s: %s\n", GetFastBufStatus(&fb2), fb2.buf );
  1602. //
  1603. // struct { FastBuf_t b; char space[2000]; } fb3;
  1604. // InitializeFastBuf(&fb3,sizeof(fb3));
  1605. // printf("fb3: %s: %s\n", GetFastBufStatus(&fb.b), fb3.b.buf );
  1606. //
  1607. // char fb4x[2000];
  1608. // FastBuf_t *fb4 = InitializeFastBuf(fb4x,sizeof(fb4x));
  1609. // printf("fb4: %s: %s\n", GetFastBufStatus(fb4), fb4->buf );
  1610. //
  1611. //------------------------------------------------------------------
  1612. FastBuf_t * InitializeFastBuf ( cvp mem, uint size );
  1613. FastBuf_t * InitializeFastBufAlloc ( FastBuf_t *fb, uint size );
  1614. void ResetFastBuf ( FastBuf_t *fb );
  1615. static inline void ClearFastBuf ( FastBuf_t *fb )
  1616. { DASSERT(fb); fb->ptr = fb->buf; }
  1617. ccp GetFastBufStatus ( const FastBuf_t *fb );
  1618. int ReserveSpaceFastBuf ( FastBuf_t *fb, uint size );
  1619. char * GetSpaceFastBuf ( FastBuf_t *fb, uint size );
  1620. // if size<0: use strlen(source) instead
  1621. uint InsertFastBuf ( FastBuf_t *fb, int index, cvp source, int size );
  1622. char * AppendFastBuf ( FastBuf_t *fb, cvp source, int size );
  1623. char * WriteFastBuf ( FastBuf_t *fb, uint offset, cvp source, int size );
  1624. uint AssignFastBuf ( FastBuf_t *fb, cvp source, int size );
  1625. uint AlignFastBuf ( FastBuf_t *fb, uint align, u8 fill );
  1626. uint DropFastBuf ( FastBuf_t *fb, int index, int size );
  1627. void CopyFastBuf ( FastBuf_t *dest, const FastBuf_t *src );
  1628. void MoveFastBuf ( FastBuf_t *dest, FastBuf_t *src );
  1629. static inline void AppendMemFastBuf ( FastBuf_t *fb, const mem_t mem )
  1630. { AppendFastBuf(fb,mem.ptr,mem.len); }
  1631. static inline void AppendCharFastBuf ( FastBuf_t *fb, char ch )
  1632. {
  1633. DASSERT(fb);
  1634. GetSpaceFastBuf(fb,1)[0] = ch;
  1635. }
  1636. void AppendUTF8CharFastBuf ( FastBuf_t *fb, u32 code );
  1637. void AppendBE16FastBuf ( FastBuf_t *fb, u16 num );
  1638. void AppendBE32FastBuf ( FastBuf_t *fb, u32 num );
  1639. void AppendInt64FastBuf ( FastBuf_t *fb, u64 val, IntMode_t mode );
  1640. static inline void AppendU16FastBuf ( FastBuf_t *fb, u16 num )
  1641. { AppendFastBuf(fb,&num,sizeof(num)); }
  1642. static inline void AppendU32FastBuf ( FastBuf_t *fb, u32 num )
  1643. { AppendFastBuf(fb,&num,sizeof(num)); }
  1644. static inline void AppendU64FastBuf ( FastBuf_t *fb, u64 num )
  1645. { AppendFastBuf(fb,&num,sizeof(num)); }
  1646. static inline int GetFastBufLen ( const FastBuf_t *fb )
  1647. { DASSERT(fb); return fb->ptr - fb->buf; }
  1648. //-----------------------------------------------------------------------------
  1649. // The resulting strings of GetFastBufString() and GetFastBufMem0() are always
  1650. // terminated by an additional NULL byte.
  1651. // The resulting strings of GetFastBufMem() is not terminated by a NULL byte.
  1652. //-----------------------------------------------------------------------------
  1653. static inline char * GetFastBufString ( const FastBuf_t *fb )
  1654. {
  1655. DASSERT(fb);
  1656. *fb->ptr = 0;
  1657. return fb->buf;
  1658. }
  1659. static inline mem_t GetFastBufMem0 ( const FastBuf_t *fb )
  1660. {
  1661. DASSERT(fb);
  1662. *fb->ptr = 0;
  1663. mem_t mem = { fb->buf, fb->ptr - fb->buf };
  1664. return mem;
  1665. }
  1666. static inline mem_t GetFastBufMem ( const FastBuf_t *fb )
  1667. {
  1668. DASSERT(fb);
  1669. mem_t mem = { fb->buf, fb->ptr - fb->buf };
  1670. return mem;
  1671. }
  1672. //-----------------------------------------------------------------------------
  1673. // The allocated result is always terminated by an additional NULL byte.
  1674. // FastBuf_t itself is reset, similar to ResetFastBuf()
  1675. char * MoveFromFastBufString ( FastBuf_t *fb );
  1676. mem_t MoveFromFastBufMem ( FastBuf_t *fb );
  1677. //
  1678. ///////////////////////////////////////////////////////////////////////////////
  1679. /////////////// MatchPattern() ///////////////
  1680. ///////////////////////////////////////////////////////////////////////////////
  1681. #define PATTERN_WILDCARDS "*#\t?[{"
  1682. bool HaveWildcards ( mem_t str );
  1683. char * FindFirstWildcard ( mem_t str );
  1684. bool MatchPatternFull
  1685. (
  1686. ccp pattern, // pattern text
  1687. ccp text // raw text
  1688. );
  1689. bool MatchPattern
  1690. (
  1691. ccp pattern, // pattern text
  1692. ccp text, // raw text
  1693. char path_sep // path separator character, standard is '/'
  1694. );
  1695. char * MatchRuleLine
  1696. (
  1697. // returns a pointer to the first non scanned char
  1698. int *status, // not NULL: return match status here
  1699. // -2: no prefix found (no rule found)
  1700. // -1: empty line (no rule found)
  1701. // 0: rule found, but don't match
  1702. // 1: rule found and match
  1703. ccp src, // source line, scanned untilCONTROL
  1704. char rule_prefix, // NULL or a rule-beginning-char'
  1705. ccp path, // path to verify
  1706. char path_sep // path separator character, standard is '/'
  1707. );
  1708. ///////////////////////////////////////////////////////////////////////////////
  1709. static inline int GetHexDigit ( char ch )
  1710. {
  1711. return ch >= '0' && ch <= '9' ? ch-'0'
  1712. : ch >= 'a' && ch <= 'f' ? ch-'a'+10
  1713. : ch >= 'A' && ch <= 'F' ? ch-'A'+10
  1714. : -1;
  1715. }
  1716. //
  1717. ///////////////////////////////////////////////////////////////////////////////
  1718. /////////////// SplitArg_t ///////////////
  1719. ///////////////////////////////////////////////////////////////////////////////
  1720. // [[SplitArg_t]]
  1721. typedef struct SplitArg_t
  1722. {
  1723. uint argc; // number of arguments in 'argv'
  1724. char **argv; // array with 'argc' arguments + a NULL term, alloced
  1725. uint argv_size; // number of alloced pointers for 'argv' without NULL term
  1726. char *temp; // NULL or temporary buffer
  1727. uint temp_size; // size of 'temp'
  1728. }
  1729. SplitArg_t;
  1730. static inline void InitializeSplitArg ( SplitArg_t *sa )
  1731. { DASSERT(sa); memset(sa,0,sizeof(*sa)); }
  1732. void ResetSplitArg ( SplitArg_t *sa );
  1733. int ScanSplitArg
  1734. (
  1735. // returns arg->argc;
  1736. SplitArg_t *arg, // pointer to object
  1737. bool init_arg, // true: call InitializeSplitArg()
  1738. ccp src, // NULL or source string
  1739. ccp src_end, // end of 'src'; if NULL: calculated by strlen(src)
  1740. char *work_buf // pointer to a buffer for strings, may be 'src'
  1741. // size must be: length of 'src' + 1
  1742. // if NULL, a temporary buffer is alloced.
  1743. );
  1744. //
  1745. ///////////////////////////////////////////////////////////////////////////////
  1746. /////////////// PointerList_t ///////////////
  1747. ///////////////////////////////////////////////////////////////////////////////
  1748. // [[PointerList_t]]
  1749. typedef struct PointerList_t
  1750. {
  1751. void **list; // 0 terminated list, 1 longer than size
  1752. uint used; // num of used elements of 'list'
  1753. uint size; // num of alloced elements of 'list'
  1754. int grow; // list grows by 1.5*size + grow (at least by 10)
  1755. }
  1756. PointerList_t;
  1757. //-----------------------------------------------------------------------------
  1758. static inline void InitializePointerMgr ( PointerList_t *pl, int grow )
  1759. { DASSERT(pl); memset(pl,0,sizeof(*pl)); pl->grow = grow; }
  1760. void ResetPointerMgr ( PointerList_t *pl );
  1761. // if n_elem<0: add until NULL pointer
  1762. void AddToPointerMgr ( PointerList_t *pl, const void *info );
  1763. void AddListToPointerMgr ( PointerList_t *pl, const void **list, int n_elem );
  1764. // reset==true: call ResetPointerMgr() after duplicating
  1765. void ** DupPointerMgr ( PointerList_t *pl, bool reset );
  1766. //
  1767. ///////////////////////////////////////////////////////////////////////////////
  1768. /////////////// ArgManager_t ///////////////
  1769. ///////////////////////////////////////////////////////////////////////////////
  1770. // [[ArgManager_t]]
  1771. typedef struct ArgManager_t
  1772. {
  1773. LowerUpper_t force_case; // change case?
  1774. char **argv; // list of strings
  1775. int argc; // number of used elements in 'argv'
  1776. uint size; // >0: 'argv' is alloced to store # elements
  1777. // last NULL element is not counted here
  1778. }
  1779. ArgManager_t;
  1780. //-----------------------------------------------------------------------------
  1781. void ResetArgManager ( ArgManager_t *am );
  1782. void SetupArgManager ( ArgManager_t *am, LowerUpper_t force_case,
  1783. int argc, char ** argv, bool clone );
  1784. void AttachArgManager ( ArgManager_t *am, int argc, char ** argv );
  1785. void CloneArgManager ( ArgManager_t *am, int argc, char ** argv );
  1786. void AddSpaceArgManager ( ArgManager_t *am, int needed_space );
  1787. void CopyArgManager ( ArgManager_t *dest, const ArgManager_t *src );
  1788. void MoveArgManager ( ArgManager_t *dest, ArgManager_t *src );
  1789. void PrepareEditArgManager ( ArgManager_t *am, int needed_space );
  1790. // return the pos behind last insert arguments
  1791. uint AppendArgManager ( ArgManager_t *am, ccp arg1, ccp arg2, bool move_arg );
  1792. uint ReplaceArgManager ( ArgManager_t *am, int pos, ccp arg1, ccp arg2, bool move_arg );
  1793. uint InsertArgManager ( ArgManager_t *am, int pos, ccp arg1, ccp arg2, bool move_arg );
  1794. uint InsertListArgManager( ArgManager_t *am, int pos, int argc, char ** argv, bool move_arg );
  1795. // return the pos at removed argument
  1796. uint RemoveArgManager ( ArgManager_t *am, int pos, int count );
  1797. uint ScanSimpleArgManager ( ArgManager_t *am, ccp src );
  1798. uint ScanQuotedArgManager ( ArgManager_t *am, ccp src, bool is_utf8 );
  1799. // NULL if for both params accepted
  1800. bool CheckFilterArgManager ( const ArgManager_t *filter, ccp name );
  1801. void DumpArgManager ( FILE *f, int indent, const ArgManager_t *am, ccp title );
  1802. enumError ScanFileArgManager
  1803. (
  1804. ArgManager_t *am, // valid arg-manager
  1805. int pos, // insert position, relative to end if <0
  1806. ccp fname, // filename to open
  1807. int silent, // 0: print all error messages
  1808. // 1: suppress file size warning
  1809. // 2: suppress all error messages
  1810. int *n_added
  1811. );
  1812. //-----------------------------------------------------------------------------
  1813. typedef enum arg_expand_mode_t
  1814. {
  1815. // AMXM = ArgManager eXpand Mode
  1816. // P = parameters, S = short options, L = long options
  1817. // 1 = single arg, 2 = double arg
  1818. AMXM_P1 = 0x01, // expand "@file"
  1819. AMXM_P2 = 0x02, // expand "@ file"
  1820. AMXM_S1 = 0x04, // expand "-@file"
  1821. AMXM_S2 = 0x08, // expand "-@ file"
  1822. AMXM_L1 = 0x10, // expand "--@=file" watch out '='
  1823. AMXM_L2 = 0x20, // expand "--@ file"
  1824. AMXM_PARAM = AMXM_P1 | AMXM_P2,
  1825. AMXM_SHORT = AMXM_S1 | AMXM_S2,
  1826. AMXM_LONG = AMXM_L1 | AMXM_L2,
  1827. AMXM_ALL = AMXM_PARAM | AMXM_SHORT | AMXM_LONG,
  1828. }
  1829. arg_expand_mode_t;
  1830. enumError ExpandAtArgManager
  1831. (
  1832. ArgManager_t *am, // valid arg-manager
  1833. arg_expand_mode_t expand_mode, // objects to be replaced
  1834. int recursion, // maximum recursion depth
  1835. int silent // 0: print all error messages
  1836. // 1: suppress file size warning
  1837. // 2: suppress all error messages
  1838. );
  1839. //
  1840. ///////////////////////////////////////////////////////////////////////////////
  1841. /////////////// sizeof_info_t ///////////////
  1842. ///////////////////////////////////////////////////////////////////////////////
  1843. // [[sizeof_info_t]]
  1844. #define SIZEOF_INFO_TITLE(t) { -1, t },
  1845. #define SIZEOF_INFO_ENTRY(e) { sizeof(e), #e },
  1846. #define SIZEOF_INFO_SEP() { -2, 0 },
  1847. #define SIZEOF_INFO_TERM() { -9, 0 },
  1848. typedef struct sizeof_info_t
  1849. {
  1850. int size;
  1851. ccp name;
  1852. }
  1853. __attribute__ ((packed)) sizeof_info_t;
  1854. //-----------------------------------------------------------------------------
  1855. // basic lists
  1856. extern const sizeof_info_t sizeof_info_linux[]; // C and Linux types
  1857. extern const sizeof_info_t sizeof_info_dclib[]; // dcLib types
  1858. // default list of lists for GCMD_Sizeof(), terminated by 0
  1859. extern const sizeof_info_t *sizeof_info_default[];
  1860. extern PointerList_t SizeofInfoMgr;
  1861. static inline void AddDefaultToSizeofInfoMgr(void)
  1862. { AddListToPointerMgr(&SizeofInfoMgr,(cvpp)sizeof_info_default,-1); }
  1863. static inline void AddInfoToSizeofInfoMgr ( const sizeof_info_t *info )
  1864. { AddToPointerMgr(&SizeofInfoMgr,info); }
  1865. static inline void AddListToSizeofInfoMgr ( const sizeof_info_t **list )
  1866. { AddListToPointerMgr(&SizeofInfoMgr,(cvpp)list,-1); }
  1867. static inline const sizeof_info_t ** GetSizeofInfoMgrList(void)
  1868. { return SizeofInfoMgr.used ? (const sizeof_info_t**)SizeofInfoMgr.list : 0; }
  1869. ///////////////////////////////////////////////////////////////////////////////
  1870. // [[sizeof_info_order_t]]
  1871. typedef enum sizeof_info_order_t
  1872. {
  1873. SIZEOF_ORDER_NONE, // don't sort output, but print categories
  1874. SIZEOF_ORDER_NAME, // Sort the output by name (case-insensitive)
  1875. // and suppress output of categories.
  1876. SIZEOF_ORDER_SIZE, // Sort the output by size and suppress output of categories.
  1877. }
  1878. sizeof_info_order_t;
  1879. //-----------------------------------------------------------------------------
  1880. void ListSizeofInfo
  1881. (
  1882. const PrintMode_t *p_pm, // NULL or print mode
  1883. const sizeof_info_t **si_list, // list of list of entries
  1884. ArgManager_t *p_filter, // NULL or filter arguments, LOUP_LOWER recommended
  1885. sizeof_info_order_t order // kind of order
  1886. );
  1887. static inline void ListSizeofInfoMgr
  1888. (
  1889. const PrintMode_t *p_pm, // NULL or print mode
  1890. PointerList_t *mgr, // valid PointerList_t
  1891. ArgManager_t *p_filter, // NULL or filter arguments, LOUP_LOWER recommended
  1892. sizeof_info_order_t order // kind of order
  1893. )
  1894. {
  1895. ListSizeofInfo(p_pm,(const sizeof_info_t**)mgr->list,p_filter,order);
  1896. }
  1897. //
  1898. ///////////////////////////////////////////////////////////////////////////////
  1899. /////////////// ContainerData_t, Container_t ///////////////
  1900. ///////////////////////////////////////////////////////////////////////////////
  1901. //-----------------------------------------------------------------------------
  1902. // OVERVIEW
  1903. //-----------------------------------------------------------------------------
  1904. // Container_t * CreateContainer ( Container_t, protect, data,size, CopyMode_t )
  1905. // Container_t * InheritContainer ( Container_t cur, protect, Container_t parent, data,size )
  1906. // bool AssignContainer ( Container_t, protect, data,size, CopyMode_t )
  1907. // void ResetContainer ( Container_t )
  1908. // void DeleteContainer ( Container_t )
  1909. // void UnlinkContainerData ( Container_t )
  1910. // ContainerData_t * LinkContainerData ( Container_t )
  1911. // ContainerData_t * MoveContainerData ( Container_t )
  1912. // Container_t * CatchContainerData ( Container_t, int protect, ContainerData_t )
  1913. // Container_t * UseContainerData ( Container_t, int protect, Container_t )
  1914. //------------
  1915. // ContainerData_t DisjoinContainerData ( Container_t )
  1916. // void JoinContainerData ( Container_t, ContainerData_t )
  1917. // void FreeContainerData ( ContainerData_t )
  1918. //------------
  1919. // static inline bool ModificationAllowed ( const Container_t )
  1920. // void ModifyAllContainer ( Container_t )
  1921. // void ModifyContainer ( Container_t, data, size, CopyMode_t )
  1922. // int SetProtectContainer ( Container_t, int new_protect )
  1923. // static inline int AddProtectContainer ( Container_t, int add_protect )
  1924. // static inline bool IsValidContainer ( const Container_t * c )
  1925. // static inline bool InContainerP ( const Container_t, cvp ptr )
  1926. // static inline bool InContainerS ( const Container_t, cvp ptr, uint size )
  1927. // static inline bool InContainerE ( const Container_t, cvp ptr, cvp end )
  1928. // uint DumpInfoContainer ( f,colset,indent,prefix, Container_t, hexdump_len )
  1929. // uint DumpInfoContainerData ( f,col,indent,prefix, CData_t, hex_len, hex_indent )
  1930. //-----------------------------------------------------------------------------
  1931. ///////////////////////////////////////////////////////////////////////////////
  1932. // [[ContainerData_t]]
  1933. typedef struct ContainerData_t
  1934. {
  1935. u8 *data; // data
  1936. uint size; // size of 'data'
  1937. int ref_count; // reference counter
  1938. int protect_count; // >0: don't modify data
  1939. bool data_alloced; // true: free data
  1940. } ContainerData_t;
  1941. //-----------------------------------------------------------------------------
  1942. // [[Container_t]]
  1943. typedef struct Container_t
  1944. {
  1945. ContainerData_t *cdata; // NULL or pointer to ContainerData
  1946. int protect_level; // >0: don't modify data
  1947. } Container_t;
  1948. ///////////////////////////////////////////////////////////////////////////////
  1949. Container_t * CreateContainer
  1950. (
  1951. // returns 'c' or the alloced container
  1952. // 'c' is always initialized
  1953. Container_t *c, // valid container, alloc one if NULL
  1954. int protect, // initial value for protection
  1955. const void *data, // data to copy/move/link
  1956. uint size, // size of 'data'
  1957. CopyMode_t mode // copy mode on creation
  1958. );
  1959. //-----------------------------------------------------------------------------
  1960. Container_t * InheritContainer
  1961. (
  1962. // returns 'c' or the alloced container
  1963. Container_t *c, // valid container, alloc one if NULL
  1964. int protect, // initial value for protection
  1965. const Container_t *parent, // NULL or valid parent container
  1966. const void *data, // data to copy/move/link
  1967. uint size // size of 'data'
  1968. );
  1969. //-----------------------------------------------------------------------------
  1970. bool AssignContainer
  1971. (
  1972. // return TRUE on new ContainerData_t
  1973. Container_t *c, // valid container; if NULL: only FREE(data)
  1974. int protect, // new protection level
  1975. const void *data, // data to copy/move/link
  1976. uint size, // size of 'data'
  1977. CopyMode_t mode // copy mode on creation
  1978. );
  1979. //-----------------------------------------------------------------------------
  1980. void ResetContainer
  1981. (
  1982. Container_t *c // container to reset => no data
  1983. );
  1984. //-----------------------------------------------------------------------------
  1985. void DeleteContainer
  1986. (
  1987. Container_t *c // container to reset and to free => no data
  1988. );
  1989. //-----------------------------------------------------------------------------
  1990. void UnlinkContainerData
  1991. (
  1992. Container_t *c // container to reset => no data
  1993. );
  1994. ///////////////////////////////////////////////////////////////////////////////
  1995. ContainerData_t * LinkContainerData
  1996. (
  1997. // increment 'ref_count' and return NULL or current ContainerData
  1998. // => use CatchContainerData() to complete operation
  1999. const Container_t *c // NULL or valid container
  2000. );
  2001. //-----------------------------------------------------------------------------
  2002. ContainerData_t * MoveContainerData
  2003. (
  2004. // return NULL or unlinked current ContainerData
  2005. // => use CatchContainerData() to complete operation
  2006. Container_t *c // NULL or valid container
  2007. );
  2008. //-----------------------------------------------------------------------------
  2009. Container_t * CatchContainerData
  2010. (
  2011. // returns 'c' or the alloced container
  2012. // 'c' is always initialized
  2013. Container_t *c, // valid container, alloc one if NULL
  2014. int protect, // initial value for protection
  2015. ContainerData_t *cdata // if not NULL: catch this
  2016. );
  2017. //-----------------------------------------------------------------------------
  2018. static inline Container_t * UseContainerData
  2019. (
  2020. // returns 'c' or the alloced container
  2021. Container_t *c, // valid container, alloc one if NULL
  2022. int protect, // initial value for protection
  2023. const Container_t *src // if not NULL: catch this
  2024. )
  2025. {
  2026. return CatchContainerData(c,protect,LinkContainerData(src));
  2027. }
  2028. ///////////////////////////////////////////////////////////////////////////////
  2029. ContainerData_t * DisjoinContainerData
  2030. (
  2031. // Disjoin data container date without freeing it. Call either
  2032. // JoinContainerData() or FreeContainerData() to finish operation.
  2033. // Reference counters are not modified.
  2034. // Return the data container or NULL
  2035. Container_t *c // NULL or valid container
  2036. );
  2037. //-----------------------------------------------------------------------------
  2038. void JoinContainerData
  2039. (
  2040. // Join a data container, that was diojoined by DisjoinContainerData()
  2041. // Reference counters are not modified.
  2042. Container_t *c, // if NULL: FreeContainerData()
  2043. ContainerData_t *cdata // NULL or container-data to join
  2044. );
  2045. //-----------------------------------------------------------------------------
  2046. void FreeContainerData
  2047. (
  2048. // Decrement the reference counter of an already disjoined data container
  2049. // and free it if unused.
  2050. ContainerData_t *cdata // NULL or container-data to free
  2051. );
  2052. ///////////////////////////////////////////////////////////////////////////////
  2053. static inline bool ModificationAllowed ( const Container_t *c )
  2054. { return c && c->cdata
  2055. && ( c->cdata->ref_count <= 1
  2056. || c->cdata->protect_count <= ( c->protect_level > 0 ) );
  2057. }
  2058. //-----------------------------------------------------------------------------
  2059. bool ModifyAllContainer
  2060. (
  2061. // prepare modification of container-data, create a copy if necessary
  2062. // return true, if a new container-data is used
  2063. Container_t *c // NULL or valid container
  2064. );
  2065. //-----------------------------------------------------------------------------
  2066. bool ModifyContainer
  2067. (
  2068. // prepare modification of container-data, create an extract if necessary
  2069. // return true, if a new container-data is used
  2070. Container_t *c, // NULL or valid container
  2071. const void *data, // data to copy/move/link
  2072. uint size, // size of 'data'
  2073. CopyMode_t mode // copy mode on creation
  2074. );
  2075. //-----------------------------------------------------------------------------
  2076. int SetProtectContainer
  2077. (
  2078. // returns 'c' new protection level
  2079. Container_t *c, // valid container, alloc one if NULL
  2080. int new_protect // new protection value
  2081. );
  2082. //-----------------------------------------------------------------------------
  2083. static inline int AddProtectContainer
  2084. (
  2085. // returns 'c' new protection level
  2086. Container_t *c, // valid container, alloc one if NULL
  2087. int add_protect // new protection value
  2088. )
  2089. {
  2090. DASSERT(c);
  2091. return SetProtectContainer(c,c->protect_level+add_protect);
  2092. }
  2093. ///////////////////////////////////////////////////////////////////////////////
  2094. static inline bool IsValidContainer ( const Container_t * c )
  2095. { return c && c->cdata && c->cdata->data; }
  2096. //-----------------------------------------------------------------------------
  2097. static inline bool InContainerP ( const Container_t * c, cvp ptr )
  2098. { return c && c->cdata && ptr
  2099. && (u8*)ptr >= c->cdata->data
  2100. && (u8*)ptr <= c->cdata->data + c->cdata->size; }
  2101. //-----------------------------------------------------------------------------
  2102. static inline bool InContainerS ( const Container_t * c, cvp ptr, uint size )
  2103. { return c && c->cdata && ptr
  2104. && (u8*)ptr >= c->cdata->data
  2105. && (u8*)ptr + size <= c->cdata->data + c->cdata->size; }
  2106. //-----------------------------------------------------------------------------
  2107. static inline bool InContainerE ( const Container_t * c, cvp ptr, cvp end )
  2108. { return c && c->cdata
  2109. && ptr && (u8*)ptr >= c->cdata->data
  2110. && end && (u8*)end <= c->cdata->data + c->cdata->size; }
  2111. ///////////////////////////////////////////////////////////////////////////////
  2112. struct ColorSet_t;
  2113. uint DumpInfoContainer
  2114. (
  2115. // return the number of printed lines
  2116. FILE *f, // valid output file
  2117. const ColorSet_t *colset, // NULL or color set
  2118. int indent, // indent the output
  2119. ccp prefix, // not NULL: use it as prefix behind indention
  2120. const Container_t *c, // dump infos for this container, NULL allowed
  2121. uint hexdump_len // max number of bytes used for a hexdump
  2122. );
  2123. //-----------------------------------------------------------------------------
  2124. uint DumpInfoContainerData
  2125. (
  2126. // return the number of printed lines
  2127. FILE *f, // valid output file
  2128. const ColorSet_t *colset, // NULL or color set
  2129. int indent, // indent of output
  2130. ccp prefix, // not NULL: use it as prefix behind indention
  2131. const
  2132. ContainerData_t *cdata, // dump infos for this container-data, NULL allowed
  2133. uint hexdump_len, // max number of bytes used for a hexdump
  2134. int hexdump_indent // indent of hexdump
  2135. );
  2136. //
  2137. ///////////////////////////////////////////////////////////////////////////////
  2138. /////////////// print lines with autobreak ///////////////
  2139. ///////////////////////////////////////////////////////////////////////////////
  2140. void PutLines
  2141. (
  2142. FILE * f, // valid output stream
  2143. int indent, // indent of output
  2144. int fw, // field width of output
  2145. int first_line, // length without prefix of already printed first line
  2146. ccp prefix, // NULL or prefix for each line
  2147. ccp text, // text to print
  2148. ccp eol // End-Of-Line text. If NULL -> LF
  2149. );
  2150. void PrintArgLines
  2151. (
  2152. FILE * f, // valid output stream
  2153. int indent, // indent of output
  2154. int fw, // field width of output
  2155. int first_line, // length without prefix of already printed first line
  2156. ccp prefix, // NULL or prefix for each line
  2157. ccp format, // format string for vsnprintf()
  2158. va_list arg // parameters for 'format'
  2159. );
  2160. void PrintLines
  2161. (
  2162. FILE * f, // valid output stream
  2163. int indent, // indent of output
  2164. int fw, // field width of output
  2165. int first_line, // length without prefix of already printed first line
  2166. ccp prefix, // NULL or prefix for each line
  2167. ccp format, // format string for vsnprintf()
  2168. ... // arguments for 'vsnprintf(format,...)'
  2169. )
  2170. __attribute__ ((__format__(__printf__,6,7)));
  2171. ///////////////////////////////////////////////////////////////////////////////
  2172. ///////////////////////////////////////////////////////////////////////////////
  2173. //
  2174. // Rules for P*ColoredLines():
  2175. //
  2176. // |+ : Define a TAB pos (not is defined at start)
  2177. // |- : Remove a TAB pos
  2178. // |[pos,...] : Comma separated list: Clear all tabs and define new TABs
  2179. // POS : Define TAB add POS
  2180. // POS*DELTA : Define TAB add POS and then at every DELTA
  2181. // \t : Jump to TAB stop
  2182. //
  2183. // | or |> : Define an indention for continuation lines.
  2184. // Use the single char only, if a letter, digit, underline, SPACE,
  2185. // CTRL or '{' follows. All ather chars are reserved for extensions.
  2186. // \r : Force a new continuation line.
  2187. // \n : Terminate current line.
  2188. // \r\n : Same as '\n'.
  2189. //
  2190. // {name} : Change active color to NAME
  2191. // {name|text} : Use color NAME only for TEXT, then restore active color.
  2192. // {} : Reset and deactivate all colors.
  2193. //
  2194. // || : Print Single '|'
  2195. // {{ : Print Single '{'
  2196. //
  2197. ///////////////////////////////////////////////////////////////////////////////
  2198. uint PutColoredLines
  2199. (
  2200. // returns the number of written lines
  2201. FILE * f, // valid output stream
  2202. const ColorSet_t *colset, // NULL or color set
  2203. int indent, // indent of output
  2204. int fw, // field width; indent+prefix+eol don't count
  2205. ccp prefix, // NULL or prefix for each line
  2206. ccp eol, // End-Of-Line text. If NULL -> LF
  2207. ccp text // text to print
  2208. );
  2209. uint PrintArgColoredLines
  2210. (
  2211. // returns the number of written lines
  2212. FILE * f, // valid output stream
  2213. const ColorSet_t *colset, // NULL or color set
  2214. int indent, // indent of output
  2215. int fw, // field width; indent+prefix+eol don't count
  2216. ccp prefix, // NULL or prefix for each line
  2217. ccp eol, // End-Of-Line text. If NULL -> LF
  2218. ccp format, // format string for vsnprintf()
  2219. va_list arg // parameters for 'format'
  2220. );
  2221. uint PrintColoredLines
  2222. (
  2223. // returns the number of written lines
  2224. FILE * f, // valid output stream
  2225. const ColorSet_t *colset, // NULL or color set
  2226. int indent, // indent of output
  2227. int fw, // field width; indent+prefix+eol don't count
  2228. ccp prefix, // NULL or prefix for each line
  2229. ccp eol, // End-Of-Line text. If NULL -> LF
  2230. ccp format, // format string for vsnprintf()
  2231. ... // arguments for 'vsnprintf(format,...)'
  2232. )
  2233. __attribute__ ((__format__(__printf__,7,8)));
  2234. //
  2235. ///////////////////////////////////////////////////////////////////////////////
  2236. /////////////// encoding/decoding ///////////////
  2237. ///////////////////////////////////////////////////////////////////////////////
  2238. extern const u32 TableCRC32[0x100];
  2239. u32 CalcCRC32 ( u32 crc, cvp buf, uint size );
  2240. ///////////////////////////////////////////////////////////////////////////////
  2241. extern const u16 TableCP1252_80[0x20];
  2242. ///////////////////////////////////////////////////////////////////////////////
  2243. // [[CharMode_t]]
  2244. typedef enum CharMode_t // select encodig/decoding method
  2245. {
  2246. CHMD_UTF8 = 0x01, // UTF8 support enabled (compatible with legacy bool)
  2247. CHMD_ESC = 0x02, // escape ESC by \e
  2248. CHMD_PIPE = 0x04, // escape pipes '|' to '\!'
  2249. CHMD_IF_REQUIRED = 0x08, // check for special chars and encode only if required
  2250. CHMD__ALL = 0x0f,
  2251. CHMD__MODERN = CHMD_UTF8 | CHMD_ESC,
  2252. CHMD__PIPE8 = CHMD__MODERN | CHMD_PIPE | CHMD_IF_REQUIRED,
  2253. }
  2254. __attribute__ ((packed)) CharMode_t;
  2255. ///////////////////////////////////////////////////////////////////////////////
  2256. // [[EncodeMode_t]]
  2257. typedef enum EncodeMode_t // select encodig/decoding method
  2258. {
  2259. ENCODE_OFF, // no encoding (always 0)
  2260. ENCODE_STRING, // ScanEscapedString(ANSI), byte mode
  2261. ENCODE_UTF8, // ScanEscapedString(UTF8), force UTF8 on decoding
  2262. ENCODE_PIPE, // analyse and use ENCODE_OFF|ENCODE_STRING, escape '|' too
  2263. ENCODE_PIPE8, // analyse and use ENCODE_OFF|ENCODE_UTF8, escape '|' too
  2264. ENCODE_BASE64, // Base64
  2265. ENCODE_BASE64URL, // Base64.URL (=) / decoder detects Standard + URL + STAR
  2266. ENCODE_BASE64STAR, // Base64.URL (*) / decoder detects Standard + URL + STAR
  2267. ENCODE_BASE64XML, // Base64 with XML name tokens / decoder detects Standard + XML (name+id)
  2268. ENCODE_JSON, // JSON string encoding
  2269. ENCODE_HEX, // Use hex-string without quotes
  2270. ENCODE__N // number of encoding modes
  2271. }
  2272. EncodeMode_t;
  2273. // [[doxygen]]
  2274. static inline bool NeedsQuotesByEncoding ( EncodeMode_t em )
  2275. { return em > ENCODE_OFF && em < ENCODE_BASE64 || em > ENCODE_BASE64XML; }
  2276. ccp GetEncodingName ( EncodeMode_t em );
  2277. ///////////////////////////////////////////////////////////////////////////////
  2278. // [[DecodeType_t]]
  2279. enum DecodeType_t // for decoding tables
  2280. {
  2281. DECODE_NULL = -1,
  2282. DECODE_CONTROL = -2,
  2283. DECODE_LINE = -3,
  2284. DECODE_SPACE = -4,
  2285. DECODE_SEPARATE = -5,
  2286. DECODE_FILLER = -6,
  2287. DECODE_OTHER = -7
  2288. };
  2289. extern const char TableNumbers[256];
  2290. extern char TableDecode64[256]; // Standard coding
  2291. extern char TableDecode64url[256]; // Standard + URL + STAR coding
  2292. extern char TableDecode64xml[256]; // Standard + XML (name tokens + identifiers)
  2293. extern const char TableEncode64[64+1]; // last char is filler
  2294. extern const char TableEncode64url[64+1]; // URL coding, used by Nintendo
  2295. extern const char TableEncode64star[64+1]; // Like URL, with '*' instead of '=' as filler
  2296. extern const char TableEncode64xml[64+1]; // XML name tokens
  2297. // for tests: encode the 48 bytes to get the full BASE64 alphabet
  2298. extern const u8 TableAlphabet64[48];
  2299. // Default tables for DecodeBase64() and EncodeBase64(), if no table is defined.
  2300. // They are initialized with TableDecode64[] and TableEncode64[].
  2301. extern ccp TableDecode64default, TableEncode64default;
  2302. ///////////////////////////////////////////////////////////////////////////////
  2303. uint GetEscapeLen
  2304. (
  2305. // returns the extra size needed for escapes.
  2306. // Add 'src_len' to get the escaped string size.
  2307. // Add 'additionally 4 to get a good buffer size.
  2308. ccp source, // NULL or string to print
  2309. int src_len, // length of string. if -1, str is null terminated
  2310. CharMode_t char_mode, // modes, bit field (CHMD_*)
  2311. char quote // NULL or quotation char, that must be quoted
  2312. );
  2313. //-----------------------------------------------------------------------------
  2314. char * PrintEscapedString
  2315. (
  2316. // returns 'buf'
  2317. char *buf, // valid destination buffer
  2318. uint buf_size, // size of 'buf', >= 10
  2319. ccp source, // NULL or string to print
  2320. int len, // length of string. if -1, str is null terminated
  2321. CharMode_t char_mode, // modes, bit field (CHMD_*)
  2322. char quote, // NULL or quotation char, that must be quoted
  2323. uint *dest_len // not NULL: Store length of result here
  2324. );
  2325. ///////////////////////////////////////////////////////////////////////////////
  2326. uint ScanEscapedString
  2327. (
  2328. // returns the number of valid bytes in 'buf' (NULL term added but not counted)
  2329. char *buf, // valid destination buffer, maybe source
  2330. uint buf_size, // size of 'buf'
  2331. ccp source, // string to scan
  2332. int len, // length of string. if -1, str is null terminated
  2333. bool utf8, // true: source and output is UTF-8
  2334. int quote, // -1:auto, 0:none, >0: quotation char
  2335. uint *scanned_len // not NULL: Store number of scanned 'source' bytes here
  2336. );
  2337. //-----------------------------------------------------------------------------
  2338. // escan string from tabels with pipe separator (UTF8 only)
  2339. static inline uint ScanEscapedStringPipe
  2340. (
  2341. // returns the number of valid bytes in 'buf' (NULL term added but not counted)
  2342. char *buf, // valid destination buffer, maybe source
  2343. uint buf_size, // size of 'buf'
  2344. ccp source, // string to scan
  2345. uint *scanned_len // not NULL: Store number of scanned 'source' bytes here
  2346. )
  2347. {
  2348. return ScanEscapedString(buf,buf_size,source,-1,true,
  2349. source && *source == '"' ? '"' : '|', scanned_len );
  2350. }
  2351. ///////////////////////////////////////////////////////////////////////////////
  2352. ///////////////////////////////////////////////////////////////////////////////
  2353. u64 DecodeU64
  2354. (
  2355. ccp source, // string to decode
  2356. int len, // length of string. if -1, str is null terminated
  2357. uint base, // number of possible digits (2..36):
  2358. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2359. );
  2360. ///////////////////////////////////////////////////////////////////////////////
  2361. ccp EncodeU64
  2362. (
  2363. char * buf, // result buffer (size depends on base)
  2364. // If NULL, a local circulary static buffer is used
  2365. size_t buf_size, // size of 'buf', ignored if buf==NULL
  2366. u64 num, // number to encode
  2367. uint base // number of possible digits (2..64):
  2368. );
  2369. ///////////////////////////////////////////////////////////////////////////////
  2370. ///////////////////////////////////////////////////////////////////////////////
  2371. uint DecodeBase64
  2372. (
  2373. // returns the number of valid bytes in 'buf'
  2374. char *buf, // valid destination buffer
  2375. uint buf_size, // size of 'buf', >= 3
  2376. ccp source, // NULL or string to decode
  2377. int len, // length of string. if -1, str is null terminated
  2378. const char decode64[256], // decoding table; if NULL: use TableDecode64default
  2379. bool allow_white_spaces, // true: skip white spaces
  2380. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2381. );
  2382. //-----------------------------------------------------------------------------
  2383. mem_t DecodeBase64Circ
  2384. (
  2385. // Returns a buffer alloced by GetCircBuf()
  2386. // with valid pointer and null terminated.
  2387. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2388. ccp source, // NULL or string to decode
  2389. int len, // length of string. if -1, str is null terminated
  2390. const char decode64[256] // decoding table; if NULL: use TableDecode64default
  2391. );
  2392. ///////////////////////////////////////////////////////////////////////////////
  2393. uint EncodeBase64
  2394. (
  2395. // returns the number of scanned bytes of 'source'
  2396. char *buf, // valid destination buffer
  2397. uint buf_size, // size of 'buf' >= 4
  2398. const void *source, // NULL or data to encode
  2399. int source_len, // length of 'source'; if <0: use strlen(source)
  2400. const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
  2401. bool use_filler, // use filler for aligned output
  2402. ccp next_line, // not NULL: use this string as new line sep
  2403. uint bytes_per_line // >0: use 'next_line' every # input bytes
  2404. // will be rounded down to multiple of 3
  2405. );
  2406. //-----------------------------------------------------------------------------
  2407. mem_t EncodeBase64Circ
  2408. (
  2409. // Returns a buffer alloced by GetCircBuf()
  2410. // with valid pointer and null terminated.
  2411. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2412. const void *source, // NULL or data to encode
  2413. int source_len, // length of 'source'; if <0: use strlen(source)
  2414. const char encode64[64+1] // encoding table; if NULL: use TableEncode64default
  2415. );
  2416. //-----------------------------------------------------------------------------
  2417. uint EncodeBase64ml // ml: multi line
  2418. (
  2419. // returns the number of scanned bytes of 'source'
  2420. char *buf, // valid destination buffer
  2421. uint buf_size, // size of 'buf' >= 4
  2422. const void *source, // NULL or data to encode
  2423. int source_len, // length of 'source'; if <0: use strlen(source)
  2424. const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
  2425. bool use_filler, // use filler for aligned output
  2426. int indent, // indention of output
  2427. ccp prefix, // NULL or prefix before encoded data
  2428. ccp eol, // line terminator, if NULL then use NL
  2429. int bytes_per_line // create a new line every # input bytes
  2430. // will be rounded down to multiple of 3
  2431. );
  2432. ///////////////////////////////////////////////////////////////////////////////
  2433. static inline uint GetEncodeBase64Len ( uint src_len )
  2434. { return 4 * (src_len+2) / 3; }
  2435. static inline uint GetEncodeBase64FillLen ( uint src_len )
  2436. { return (src_len+2) / 3 * 4; }
  2437. static inline uint GetDecodeBase64Len ( uint src_len )
  2438. { return 3 * src_len / 4; }
  2439. ///////////////////////////////////////////////////////////////////////////////
  2440. ///////////////////////////////////////////////////////////////////////////////
  2441. static inline uint DecodeJSON
  2442. (
  2443. // returns the number of valid bytes in 'buf'
  2444. char *buf, // valid destination buffer
  2445. uint buf_size, // size of 'buf', >= 3
  2446. ccp source, // NULL or string to decode
  2447. int source_len, // length of 'source'. If -1, str is NULL terminated
  2448. int quote, // -1:auto, 0:none, >0: quotation char
  2449. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2450. )
  2451. {
  2452. return ScanEscapedString(buf,buf_size,source,source_len,true,quote,scanned_len);
  2453. }
  2454. //-----------------------------------------------------------------------------
  2455. mem_t DecodeJSONCirc
  2456. (
  2457. // Returns a buffer alloced by GetCircBuf()
  2458. // with valid pointer and null terminated.
  2459. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2460. ccp source, // NULL or string to decode
  2461. int source_len, // length of 'source'. If -1, str is NULL terminated
  2462. int quote // -1:auto, 0:none, >0: quotation char
  2463. );
  2464. ///////////////////////////////////////////////////////////////////////////////
  2465. uint EncodeJSON
  2466. (
  2467. // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
  2468. char *buf, // valid destination buffer
  2469. uint buf_size, // size of 'buf', >2 and 2 bytes longer than needed
  2470. const void *source, // NULL or data to encode
  2471. int source_len // length of 'source'; if <0: use strlen(source)
  2472. );
  2473. //-----------------------------------------------------------------------------
  2474. mem_t EncodeJSONCirc
  2475. (
  2476. // Returns a buffer alloced by GetCircBuf()
  2477. // with valid pointer and null terminated.
  2478. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2479. const void *source, // NULL or data to encode
  2480. int source_len // length of 'source'; if <0: use strlen(source)
  2481. );
  2482. //-----------------------------------------------------------------------------
  2483. mem_t QuoteJSONCirc
  2484. (
  2485. // Returns a buffer alloced by GetCircBuf()
  2486. // with valid pointer and null terminated.
  2487. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2488. const void *source, // NULL or data to encode
  2489. int source_len, // length of 'source'; if <0: use strlen(source)
  2490. int null_if // return 'null' without quotes ...
  2491. // <=0: never
  2492. // >=1: if source == NULL
  2493. // >=2: if source_len == 0
  2494. );
  2495. ///////////////////////////////////////////////////////////////////////////////
  2496. ///////////////////////////////////////////////////////////////////////////////
  2497. uint DecodeHex
  2498. (
  2499. // returns the number of valid bytes in 'buf'
  2500. char *buf, // valid destination buffer
  2501. uint buf_size, // size of 'buf', >= 3
  2502. ccp source, // NULL or string to decode
  2503. int source_len, // length of 'source'. If -1, str is NULL terminated
  2504. int quote, // -1:auto, 0:none, >0: quotation char
  2505. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2506. );
  2507. //-----------------------------------------------------------------------------
  2508. mem_t DecodeHexCirc
  2509. (
  2510. // Returns a buffer alloced by GetCircBuf()
  2511. // with valid pointer and null terminated.
  2512. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2513. ccp source, // NULL or string to decode
  2514. int source_len, // length of 'source'. If -1, str is NULL terminated
  2515. int quote // -1:auto, 0:none, >0: quotation char
  2516. );
  2517. ///////////////////////////////////////////////////////////////////////////////
  2518. uint EncodeHex
  2519. (
  2520. // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
  2521. char *buf, // valid destination buffer
  2522. uint buf_size, // size of 'buf', >2 and 2 bytes longer than needed
  2523. const void *source, // NULL or data to encode
  2524. int source_len, // length of 'source'; if <0: use strlen(source)
  2525. ccp digits // digits to use, eg. LoDigits[] (=fallback) or HiDigits[]
  2526. );
  2527. //-----------------------------------------------------------------------------
  2528. mem_t EncodeHexCirc
  2529. (
  2530. // Returns a buffer alloced by GetCircBuf()
  2531. // with valid pointer and null terminated.
  2532. // If result is too large (>CIRC_BUF_MAX_ALLOC) then (0,0) is returned.
  2533. const void *source, // NULL or data to encode
  2534. int source_len, // length of 'source'; if <0: use strlen(source)
  2535. ccp digits // digits to use, eg. LoDigits[] (=fallback) or HiDigits[]
  2536. );
  2537. ///////////////////////////////////////////////////////////////////////////////
  2538. ///////////////////////////////////////////////////////////////////////////////
  2539. uint DecodeByMode
  2540. (
  2541. // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
  2542. char *buf, // valid destination buffer
  2543. uint buf_size, // size of 'buf', >= 3
  2544. ccp source, // string to decode
  2545. int slen, // length of string. if -1, str is null terminated
  2546. EncodeMode_t emode, // encoding mode
  2547. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2548. );
  2549. ///////////////////////////////////////////////////////////////////////////////
  2550. mem_t DecodeByModeMem
  2551. (
  2552. // Returns the decoded 'source'. Result is NULL-terminated.
  2553. // It points either to 'buf' or is alloced (on buf==NULL or too less space)
  2554. // If alloced (mem.ptr!=buf) => call FreeMem(&mem)
  2555. char *buf, // NULL or destination buffer
  2556. uint buf_size, // size of 'buf'
  2557. ccp source, // string to decode
  2558. int slen, // length of string. if -1, str is null terminated
  2559. EncodeMode_t emode, // encoding mode
  2560. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2561. );
  2562. ///////////////////////////////////////////////////////////////////////////////
  2563. uint DecodeByModeMemList
  2564. (
  2565. // returns the number of scanned strings
  2566. mem_list_t *res, // result
  2567. uint res_mode, // 0:append, 1:clear, 2:init
  2568. ccp source, // string to decode
  2569. int slen, // length of string. if -1, str is null terminated
  2570. EncodeMode_t emode, // encoding mode
  2571. uint *scanned_len // not NULL: Store number of scanned 'str' bytes here
  2572. );
  2573. ///////////////////////////////////////////////////////////////////////////////
  2574. ///////////////////////////////////////////////////////////////////////////////
  2575. uint EncodeByMode
  2576. (
  2577. // returns the number of valid bytes in 'buf'. Result is NULL-terminated.
  2578. char *buf, // valid destination buffer
  2579. uint buf_size, // size of 'buf' >= 4
  2580. ccp source, // string to encode
  2581. int slen, // length of string. if -1, str is null terminated
  2582. EncodeMode_t emode // encoding mode
  2583. );
  2584. ///////////////////////////////////////////////////////////////////////////////
  2585. mem_t EncodeByModeMem
  2586. (
  2587. // Returns the encoded 'source'. Result is NULL-terminated.
  2588. // It points either to 'buf' or is alloced (on buf==NULL or too less space)
  2589. // If alloced (mem.ptr!=buf) => call FreeMem(&mem)
  2590. char *buf, // NULL or destination buffer
  2591. uint buf_size, // size of 'buf'
  2592. ccp source, // string to encode
  2593. int slen, // length of string. if -1, str is null terminated
  2594. EncodeMode_t emode // encoding mode
  2595. );
  2596. ///////////////////////////////////////////////////////////////////////////////
  2597. #define SJIS_TAB_MAPPING_BEG 0xeea0 // first code used for table mapping
  2598. #define SJIS_TAB_MAPPING_END 0xeecf // last code used for table mapping
  2599. #define SJIS_INVALID_CODE 0xffff // invalid code
  2600. #define SJIS_CACHE_SIZE 0xffff // number of elements in cache
  2601. static inline bool IsValidShiftJIS ( uint code )
  2602. { return code < SJIS_TAB_MAPPING_BEG
  2603. || code > SJIS_TAB_MAPPING_END && code < SJIS_INVALID_CODE; }
  2604. int ScanShiftJISChar ( cucp * str );
  2605. int ScanShiftJISCharE ( cucp * str, cvp end );
  2606. void SetupGetShiftJISCache(void);
  2607. int GetShiftJISChar ( u32 code );
  2608. ccp GetShiftJISStatistics(void);
  2609. //
  2610. ///////////////////////////////////////////////////////////////////////////////
  2611. /////////////// escape/quote strings, alloc space ///////////////
  2612. ///////////////////////////////////////////////////////////////////////////////
  2613. exmem_t EscapeStringEx
  2614. (
  2615. // Returns an exmem_t struct. If not quoted (CHMD_IF_REQUIRED) it returns 'src'
  2616. // Use FreeExMem(&result) to free possible alloced result.
  2617. cvp src, // NULL or source
  2618. int src_len, // size of 'src'. If -1: Use strlen(src)
  2619. cvp return_if_null, // return this, if 'src==NULL'
  2620. cvp return_if_empty, // return this, if src is empty (have no chars)
  2621. CharMode_t char_mode, // how to escape (CHMD_*)
  2622. char quote, // quoting character: " or ' or $ (for $'...')
  2623. bool try_circ // use circ-buffer, if result is small enough
  2624. );
  2625. //-----------------------------------------------------------------------------
  2626. char * EscapeString
  2627. (
  2628. // Returns a pointer.
  2629. // Use FreeString(result) to free possible alloced result.
  2630. // circ-buffer is ignored by FreeString().
  2631. cvp src, // NULL or source
  2632. int src_len, // size of 'src'. If -1: Use strlen(src)
  2633. cvp return_if_null, // return this, if 'src==NULL'
  2634. cvp return_if_empty, // return this, if src is empty (have no chars)
  2635. CharMode_t char_mode, // how to escape
  2636. char quote, // quoting character: " or ' or $ (for $'...')
  2637. bool try_circ, // use circ-buffer, if result is small enough
  2638. uint *dest_len // not NULL: Store length of result here
  2639. );
  2640. //-----------------------------------------------------------------------------
  2641. static inline char * EscapeStringM ( mem_t src, cvp if_null, CharMode_t cm )
  2642. { return EscapeString(src.ptr,src.len,if_null,EmptyString,cm,0,false,0); }
  2643. static char * EscapeStringS ( ccp src, cvp if_null, CharMode_t cm )
  2644. { return EscapeString(src,-1,if_null,EmptyString,cm,0,false,0); }
  2645. //-----------------------------------------------------------------------------
  2646. static inline char * EscapeStringCircM ( mem_t src, cvp if_null, CharMode_t cm )
  2647. { return EscapeString(src.ptr,src.len,if_null,EmptyString,cm,0,true,0); }
  2648. static char * EscapeStringCircS ( ccp src, cvp if_null, CharMode_t cm )
  2649. { return EscapeString(src,-1,if_null,EmptyString,cm,0,true,0); }
  2650. //-----------------------------------------------------------------------------
  2651. static inline char * QuoteStringM ( mem_t src, cvp if_null, CharMode_t cm )
  2652. { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,true,false,0); }
  2653. static char * QuoteStringS ( ccp src, cvp if_null, CharMode_t cm )
  2654. { return EscapeString(src,-1,if_null,EmptyQuote,cm,'"',false,0); }
  2655. static inline char * QuoteBashM ( mem_t src, cvp if_null, CharMode_t cm )
  2656. { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'$',false,0); }
  2657. static char * QuoteBashS ( ccp src, cvp if_null, CharMode_t cm )
  2658. { return EscapeString(src,-1,if_null,EmptyQuote,cm,'$',false,0); }
  2659. //-----------------------------------------------------------------------------
  2660. static inline char * QuoteStringCircM ( mem_t src, cvp if_null, CharMode_t cm )
  2661. { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'"',true,0); }
  2662. static char * QuoteStringCircS ( ccp src, cvp if_null, CharMode_t cm )
  2663. { return EscapeString(src,-1,if_null,EmptyQuote,cm,'"',true,0); }
  2664. static inline char * QuoteBashCircM ( mem_t src, cvp if_null, CharMode_t cm )
  2665. { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'$',true,0); }
  2666. static char * QuoteBashCircS ( ccp src, cvp if_null, CharMode_t cm )
  2667. { return EscapeString(src,-1,if_null,EmptyQuote,cm,'$',true,0); }
  2668. //-----------------------------------------------------------------------------
  2669. // Escape strings for tables with pipe separator (UTF8 only).
  2670. // Use FreeExMem(result) to free possible alloced result.
  2671. static inline exmem_t EscapeStringPipeM ( mem_t src )
  2672. { return EscapeStringEx(src.ptr,src.len,EmptyString,EmptyString,CHMD__PIPE8,'"',false); }
  2673. static exmem_t EscapeStringPipeS ( ccp src )
  2674. { return EscapeStringEx(src,-1,EmptyString,EmptyString,CHMD__PIPE8,'"',false); }
  2675. static inline exmem_t EscapeStringPipeCircM ( mem_t src )
  2676. { return EscapeStringEx(src.ptr,src.len,EmptyString,EmptyString,CHMD__PIPE8,'"',true); }
  2677. static exmem_t EscapeStringPipeCircS ( ccp src )
  2678. { return EscapeStringEx(src,-1,EmptyString,EmptyString,CHMD__PIPE8,'"',false); }
  2679. //
  2680. ///////////////////////////////////////////////////////////////////////////////
  2681. /////////////// struct Escape_t ///////////////
  2682. ///////////////////////////////////////////////////////////////////////////////
  2683. // [[EscapeStat_t]]
  2684. typedef enum EscapeStat_t
  2685. {
  2686. ESCST_NONE, // nothing scanned (data incomplete)
  2687. ESCST_CHAR, // single char scanned (char behind '\e')
  2688. ESCST_FE, // FE scanned (single byte)
  2689. ESCST_SS2, // SS2 scanned ('N' + single byte), code := second char
  2690. ESCST_SS3, // SS3 scanned ('O' + single byte) , code := second char
  2691. ESCST_CSI, // 'Control Sequence Introduce' based string scanned, code := final char
  2692. ESCST_OSC, // 'Operating System Command' based string scanned
  2693. ESCST__N
  2694. }
  2695. EscapeStat_t;
  2696. extern const char ecape_stat_name[ESCST__N+1][5];
  2697. ///////////////////////////////////////////////////////////////////////////////
  2698. // [[Escape_t]]
  2699. typedef struct Escape_t
  2700. {
  2701. EscapeStat_t status; // one of EscapeStat_t
  2702. int scanned_len; // number of scanned chars
  2703. u32 code; // depends on 'status', see enum EscapeStat_t
  2704. mem_t esc; // if status==2: pointer+len to escape string; else (0,0)
  2705. }
  2706. Escape_t;
  2707. //-----------------------------------------------------------------------------
  2708. // returns esc->status
  2709. EscapeStat_t CheckEscape ( Escape_t *esc, cvp source, cvp end, bool check_esc );
  2710. //
  2711. ///////////////////////////////////////////////////////////////////////////////
  2712. /////////////// scan keywords ///////////////
  2713. ///////////////////////////////////////////////////////////////////////////////
  2714. #define KEYWORD_NAME_MAX 100
  2715. typedef s64 (*KeywordCallbackFunc)
  2716. (
  2717. void *param, // NULL or user defined parameter
  2718. ccp name, // normalized name of option
  2719. const KeywordTab_t *key_tab, // valid pointer to command table
  2720. const KeywordTab_t *key, // valid pointer to found command
  2721. char prefix, // 0 | '-' | '+' | '='
  2722. s64 result // current value of result
  2723. );
  2724. ///////////////////////////////////////////////////////////////////////////////
  2725. const KeywordTab_t *GetKewordById
  2726. (
  2727. const KeywordTab_t *key_tab, // NULL or pointer to command table
  2728. s64 id // id to search
  2729. );
  2730. //-----------------------------------------------------------------------------
  2731. const KeywordTab_t *GetKewordByIdAndOpt
  2732. (
  2733. const KeywordTab_t *key_tab, // NULL or pointer to command table
  2734. s64 id, // id to search
  2735. s64 opt // opt to search
  2736. );
  2737. //-----------------------------------------------------------------------------
  2738. static inline ccp GetKewordNameById
  2739. (
  2740. const KeywordTab_t *key_tab, // NULL or pointer to command table
  2741. s64 id, // id to search
  2742. ccp res_not_found // return this if not found
  2743. )
  2744. {
  2745. const KeywordTab_t *key = GetKewordById(key_tab,id);
  2746. return key ? key->name1 : res_not_found;
  2747. }
  2748. //-----------------------------------------------------------------------------
  2749. static inline ccp GetKewordNameByIdAndOpt
  2750. (
  2751. const KeywordTab_t *key_tab, // NULL or pointer to command table
  2752. s64 id, // id to search
  2753. s64 opt, // opt to search
  2754. ccp res_not_found // return this if not found
  2755. )
  2756. {
  2757. const KeywordTab_t *key = GetKewordByIdAndOpt(key_tab,id,opt);
  2758. return key ? key->name1 : res_not_found;
  2759. }
  2760. ///////////////////////////////////////////////////////////////////////////////
  2761. const KeywordTab_t * ScanKeyword
  2762. (
  2763. int *res_abbrev, // NULL or pointer to result 'abbrev_count'
  2764. ccp arg, // argument to scan
  2765. const KeywordTab_t *key_tab // valid pointer to command table
  2766. );
  2767. //-----------------------------------------------------------------------------
  2768. s64 ScanKeywordListEx
  2769. (
  2770. ccp arg, // argument to scan
  2771. const KeywordTab_t * key_tab, // valid pointer to command table
  2772. KeywordCallbackFunc func, // NULL or calculation function
  2773. bool allow_prefix, // allow '-' | '+' | '=' as prefix
  2774. u32 max_number, // allow numbers < 'max_number' (0=disabled)
  2775. s64 result, // start value for result
  2776. uint err_mode, // bit field:
  2777. // 1: continue on error
  2778. ccp err_msg, // not NULL: print a warning message:
  2779. // "<ERR_MSG>: Unknown keyword: <KEY>"
  2780. enumError err_code, // use 'err_code' for the 'err_msg'
  2781. uint *err_count // not NULL: store errors here
  2782. );
  2783. static inline s64 ScanKeywordList
  2784. (
  2785. ccp arg, // argument to scan
  2786. const KeywordTab_t * key_tab, // valid pointer to command table
  2787. KeywordCallbackFunc func, // NULL or calculation function
  2788. bool allow_prefix, // allow '-' | '+' | '=' as prefix
  2789. u32 max_number, // allow numbers < 'max_number' (0=disabled)
  2790. s64 result, // start value for result
  2791. ccp err_msg, // not NULL: print a warning message:
  2792. // "<ERR_MSG>: Unknown keyword: <KEY>"
  2793. enumError err_code // use 'err_code' for the 'err_msg'
  2794. )
  2795. {
  2796. return ScanKeywordListEx( arg, key_tab, func, allow_prefix,
  2797. max_number, result, 0, err_msg, err_code, 0 );
  2798. }
  2799. //-----------------------------------------------------------------------------
  2800. enumError ScanKeywordListFunc
  2801. (
  2802. ccp arg, // argument to scan
  2803. const KeywordTab_t *key_tab, // valid pointer to command table
  2804. KeywordCallbackFunc func, // calculation function
  2805. void *param, // used define parameter for 'func'
  2806. bool allow_prefix // allow '-' | '+' | '=' as prefix
  2807. );
  2808. //-----------------------------------------------------------------------------
  2809. s64 ScanKeywordListMask
  2810. (
  2811. ccp arg, // argument to scan
  2812. const KeywordTab_t * key_tab // valid pointer to command table
  2813. );
  2814. //-----------------------------------------------------------------------------
  2815. ccp GetKeywordError
  2816. (
  2817. // return circ-buf
  2818. const KeywordTab_t * key_tab, // NULL or pointer to command table
  2819. ccp key_arg, // analyzed command
  2820. int key_stat, // status of ScanKeyword()
  2821. ccp object // NULL or object for error messages
  2822. // default= 'command'
  2823. );
  2824. enumError PrintKeywordError
  2825. (
  2826. const KeywordTab_t * key_tab, // NULL or pointer to command table
  2827. ccp key_arg, // analyzed command
  2828. int key_stat, // status of ScanKeyword()
  2829. ccp prefix, // NULL or prefix for messages
  2830. ccp object // NULL or object for error messages
  2831. // default= 'command'
  2832. );
  2833. uint CollectAmbiguousKeywords
  2834. (
  2835. char *buf, // destination buffer, 200 bytes are good
  2836. uint buf_size, // size of buffer
  2837. const KeywordTab_t * key_tab, // NULL or pointer to command table
  2838. ccp key_arg // analyzed command
  2839. );
  2840. //-----------------------------------------------------------------------------
  2841. char * PrintKeywordList
  2842. (
  2843. // returns a pointer to the result buffer
  2844. char *buf, // result buffer
  2845. // If NULL, a local circulary static buffer
  2846. // with max CIRC_BUF_MAX_ALLOC bytes is used
  2847. uint buf_size, // size of 'buf', at least 10 bytes if buf is set
  2848. uint *ret_length, // not NULL: store result length here
  2849. const KeywordTab_t *tab, // related keyword table
  2850. u64 mode, // mode to print
  2851. u64 default_mode, // NULL or default mode
  2852. u64 hide_mode // bit field to hide parameters
  2853. );
  2854. //-----------------------------------------------------------------------------
  2855. int ScanKeywordOffOn
  2856. (
  2857. // returns 0 for '0|OFF'; 1 for '1|ON; -1 for empty; -2 on error
  2858. ccp arg, // argument to scan
  2859. uint max_num, // >0: additionally accept+return number <= max_num
  2860. ccp object // NULL (silent) or object for error messages
  2861. );
  2862. //-----------------------------------------------------------------------------
  2863. enumError Command_ARGTEST ( int argc, char ** argv );
  2864. enumError Command_TESTCOLORS ( int argc, char ** argv );
  2865. enumError Command_COLORS
  2866. (
  2867. int level, // only used, if mode==NULL
  2868. // < 0: status message (ignore mode)
  2869. // >= 1: include names
  2870. // >= 2: include alt names
  2871. // >= 3: include color names incl bold
  2872. // >= 4: include background color names
  2873. ColorSelect_t select, // select color groups; if 0: use level
  2874. uint format // output format => see PrintColorSet()
  2875. );
  2876. //
  2877. ///////////////////////////////////////////////////////////////////////////////
  2878. /////////////// OFF/AUTO/ON/FORCE ///////////////
  2879. ///////////////////////////////////////////////////////////////////////////////
  2880. // [[OffOn_t]]
  2881. typedef enum OffOn_t
  2882. {
  2883. OFFON_ERROR = -99,
  2884. OFFON_OFF = -1,
  2885. OFFON_AUTO = 0,
  2886. OFFON_ON = 1,
  2887. OFFON_FORCE = 2,
  2888. }
  2889. OffOn_t;
  2890. extern const KeywordTab_t KeyTab_OFF_AUTO_ON[];
  2891. int ScanKeywordOffAutoOnEx
  2892. (
  2893. // returns one of OFFON_*
  2894. const KeywordTab_t *keytab, // Keyword table. If NULL, then use KeyTab_OFF_AUTO_ON[]
  2895. ccp arg, // argument to scan
  2896. int on_empty, // return this value on empty
  2897. uint max_num, // >0: additionally accept+return number <= max_num
  2898. ccp object // NULL (silent) or object for error messages
  2899. );
  2900. static inline int ScanKeywordOffAutoOn( ccp arg, int on_empty, uint max_num, ccp object )
  2901. { return ScanKeywordOffAutoOnEx(0,arg,on_empty,max_num,object); }
  2902. ccp GetKeywordOffAutoOn ( OffOn_t value );
  2903. //
  2904. ///////////////////////////////////////////////////////////////////////////////
  2905. /////////////// scan command lists ///////////////
  2906. ///////////////////////////////////////////////////////////////////////////////
  2907. //
  2908. // Scan a semicolon separated command list with binary support of format:
  2909. // COMMAND := NAME [BINLIST] CONTROL* ['='] CONTROL* [PARAM] CONTROL* ';'
  2910. // BLANK := TAB(9) or SPACE(32)
  2911. // CONTROL := NUL..SPACE (0..32)
  2912. // NAME := 1..99 alphanumeric chars incl. minus and underline
  2913. // BINLIST := BINARY [BINLIST]
  2914. // BINARY := BLANK* '\1' be16:SIZE DATA
  2915. // PARAM := all except ';'
  2916. //
  2917. // CONTROLS are possible before and behind the '=' and at the end of param.
  2918. // Only BLANK* are allowed between command NAME and BINARY block.
  2919. // BINARY data starts with \1 and is stored as '->bin' and '->bin_len' and
  2920. // inludes SIZE and DATA. The BINARY.SIZE includes itself and is a 16-bit
  2921. // big-endian number. In '->bin[]', member 'be16:SIZE' is excluded,
  2922. // but '->bin[].ptr - 2' points to be16:SIZE.
  2923. //
  2924. ///////////////////////////////////////////////////////////////////////////////
  2925. ///////////////////////////////////////////////////////////////////////////////
  2926. // [[CommandList_t]] docu -> see above
  2927. struct TCPStream_t;
  2928. #define COMMAND_LIST_N_BIN 5
  2929. typedef struct CommandList_t
  2930. {
  2931. //--- input params
  2932. ccp command; // command text
  2933. uint command_len; // total length of 'command'
  2934. char command_sep; // not NULL: alternative command separator
  2935. u8 change_case; // >0: convert command to lower(1) or upper(2) case
  2936. bool term_param; // 1: write a NULL at end-of-param => modify 'command'
  2937. // 2: write a ';' at end-of-param => modify 'command'
  2938. // in this case, ';' is counted to 'record_len'
  2939. bool is_terminated; // true: last command is terminated
  2940. // even without ';'
  2941. //--- user parameters, pass-through
  2942. struct TCPStream_t
  2943. *user_ts; // NULL or a stream for replies
  2944. void *user_ptr; // any pointer
  2945. int user_int; // any number or id
  2946. ccp log_fname; // not NULL: open log file
  2947. uint log_level; // 0:off, 1:stat+err, 2:+cmd, 3:+bin+param, 4:+func
  2948. //--- analysed data, only valid at callback
  2949. char cmd[100]; // scanned command name
  2950. uint cmd_len; // length of scanned command name
  2951. uint n_bin; // number of binary blocks
  2952. mem_t bin[COMMAND_LIST_N_BIN];
  2953. // binary data detected, if bin[].ptr not null
  2954. ccp param; // pointer to text parameter, not NULL terminated
  2955. uint param_len; // length of text parameter
  2956. const u8 *record; // complete record from NAME to END_RECORD_CHAR
  2957. uint record_len; // length of trimmed record
  2958. uint input_len; // length of complete record at input time
  2959. //--- statistics
  2960. uint read_cmd_len; // number of used bytes of 'command'
  2961. uint fail_count; // number of failed commands
  2962. uint cmd_count; // number of commands
  2963. }
  2964. CommandList_t;
  2965. // return -1 to abort scanning
  2966. typedef int (*CommandListFunc) ( CommandList_t *cli );
  2967. //-----------------------------------------------------------------------------
  2968. static inline void InitializeCommandList ( CommandList_t *cli )
  2969. { DASSERT(cli); memset(cli,0,sizeof(*cli)); }
  2970. static inline void ClearCommandList ( CommandList_t *cli )
  2971. { DASSERT(cli); }
  2972. static inline void ResetCommandList ( CommandList_t *cli )
  2973. { DASSERT(cli); memset(cli,0,sizeof(*cli)); }
  2974. // a test function for ScanCommandList()
  2975. int ExecCommandOfList ( CommandList_t *cli );
  2976. int ScanCommandList
  2977. (
  2978. // scan a semicolon separated command list. See above for format
  2979. // returns -1 on 'cli->fail_count'; otherwise 'cli->cmd_count'
  2980. CommandList_t *cli, // valid command list
  2981. CommandListFunc func // NULL or function for each command
  2982. );
  2983. //
  2984. ///////////////////////////////////////////////////////////////////////////////
  2985. /////////////// numeric functions ///////////////
  2986. ///////////////////////////////////////////////////////////////////////////////
  2987. extern int urandom_available; // <0:not, =0:not tested, >0:ok
  2988. extern bool use_urandom_for_myrandom;
  2989. uint ReadFromUrandom ( void *dest, uint size );
  2990. ///////////////////////////////////////////////////////////////////////////////
  2991. u32 MyRandom ( u32 max );
  2992. u64 MySeed ( u64 base );
  2993. u64 MySeedByTime(void);
  2994. void MyRandomFill ( void * buf, size_t size );
  2995. ///////////////////////////////////////////////////////////////////////////////
  2996. void CreateUUID ( uuid_buf_t dest );
  2997. uint CreateTextUUID ( char *buf, uint bufsize );
  2998. uint PrintUUID ( char *buf, uint bufsize, uuid_buf_t uuid );
  2999. char * ScanUUID ( uuid_buf_t uuid, ccp source );
  3000. ///////////////////////////////////////////////////////////////////////////////
  3001. uint gcd ( uint n1, uint n2 ); // greatest common divisor, german: ggt
  3002. u32 gcd32 ( u32 n1, u32 n2 );
  3003. u64 gcd64 ( u64 n1, u64 n2 );
  3004. uint lcm ( uint n1, uint n2 ); // lowest common multiple, german: kgv
  3005. u32 lcm32 ( u32 n1, u32 n2 );
  3006. u64 lcm64 ( u64 n1, u64 n2 );
  3007. //
  3008. ///////////////////////////////////////////////////////////////////////////////
  3009. /////////////// scan number ///////////////
  3010. ///////////////////////////////////////////////////////////////////////////////
  3011. enum DigitTable_t
  3012. {
  3013. NUMBER_NULL = -1, // NULL
  3014. NUMBER_CONTROL = -2, // < 0x20, but not SPACE or LINE
  3015. NUMBER_LINE = -3, // LF, CR
  3016. NUMBER_SPACE = -4, // SPACE, TAB, VT
  3017. NUMBER_TIE = -5, // ':' '-' '.'
  3018. NUMBER_SEPARATE = -6, // ',' ';'
  3019. NUMBER_OTHER = -7 // all other
  3020. };
  3021. extern const char DigitTable[256];
  3022. //-----------------------------------------------------------------------------
  3023. u64 ScanDigits
  3024. (
  3025. // same as ScanNumber(), but other interface
  3026. // returns the scanned number
  3027. ccp *source, // pointer to source string, modified
  3028. ccp end_source, // NULL or end of 'source'
  3029. uint intbase, // integer base, 2..36
  3030. int maxchar, // max number of digits to read
  3031. uint *count // not NULL: store number of scanned digits here
  3032. );
  3033. //-----------------------------------------------------------------------------
  3034. char * ScanNumber
  3035. (
  3036. // same as ScanDigits(), but other interface
  3037. // returns a pointer to the first not used character
  3038. uint *dest_num, // store result here, never NULL
  3039. ccp src, // pointer to source string, modified
  3040. ccp src_end, // NULL or end of 'src'
  3041. uint intbase, // integer base, 2..36
  3042. int maxchar // max number of digits to read
  3043. );
  3044. //-----------------------------------------------------------------------------
  3045. char * ScanEscape
  3046. (
  3047. // returns a pointer to the first not used character
  3048. uint *dest_code, // store result here, never NULL
  3049. ccp src, // pointer to source string (behind escape char)
  3050. ccp src_end // NULL or end of 'src'
  3051. );
  3052. //-----------------------------------------------------------------------------
  3053. uint ScanHexString
  3054. (
  3055. // return the number of written bytes
  3056. void *buf, // write scanned data here
  3057. uint buf_size, // size of buf
  3058. ccp *source, // pointer to source string, modified
  3059. ccp end_source, // NULL or end of 'source'
  3060. bool allow_tie // allow chars ' .:-' and TAB,VT as byte separator
  3061. );
  3062. ///////////////////////////////////////////////////////////////////////////////
  3063. ///////////////////////////////////////////////////////////////////////////////
  3064. char * ScanS32
  3065. (
  3066. // return 'source' on error
  3067. s32 *res_num, // not NULL: store result (only on success)
  3068. ccp source, // NULL or source text
  3069. uint default_base // base for numbers without '0x' prefix
  3070. // 0: C like with octal support
  3071. // 10: standard value for decimal numbers
  3072. // 16: standard value for hex numbers
  3073. );
  3074. static inline char * ScanU32 ( u32 *res_num, ccp source, uint default_base )
  3075. { return ScanS32((s32*)res_num,source,default_base); }
  3076. //-----------------------------------------------------------------------------
  3077. char * ScanS64
  3078. (
  3079. // return 'source' on error
  3080. s64 *res_num, // not NULL: store result (only on success)
  3081. ccp source, // NULL or source text
  3082. uint default_base // base for numbers without '0x' prefix
  3083. // 0: C like with octal support
  3084. // 10: standard value for decimal numbers
  3085. // 16: standard value for hex numbers
  3086. );
  3087. static inline char * ScanU64 ( u64 *res_num, ccp source, uint default_base )
  3088. { return ScanS64((s64*)res_num,source,default_base); }
  3089. //-----------------------------------------------------------------------------
  3090. #if __WORDSIZE >= 64
  3091. static inline char * ScanINT ( int *res_num, ccp source, uint default_base )
  3092. { return ScanS32((s32*)res_num,source,default_base); }
  3093. static inline char * ScanUINT ( uint *res_num, ccp source, uint default_base )
  3094. { return ScanS32((s32*)res_num,source,default_base); }
  3095. #else
  3096. static inline char * ScanINT ( int *res_num, ccp source, uint default_base )
  3097. { return ScanS64((s64*)res_num,source,default_base); }
  3098. static inline char * ScanUINT ( uint *res_num, ccp source, uint default_base )
  3099. { return ScanS64((s64*)res_num,source,default_base); }
  3100. #endif
  3101. //-----------------------------------------------------------------------------
  3102. // strto*() replacements: Use Scan*() with better base support, NULL allowed as source
  3103. long int str2l ( const char *nptr, char **endptr, int base );
  3104. long long int str2ll ( const char *nptr, char **endptr, int base );
  3105. unsigned long int str2ul ( const char *nptr, char **endptr, int base );
  3106. unsigned long long int str2ull ( const char *nptr, char **endptr, int base );
  3107. //
  3108. ///////////////////////////////////////////////////////////////////////////////
  3109. /////////////// print numbers and size ///////////////
  3110. ///////////////////////////////////////////////////////////////////////////////
  3111. // [[sizeform_mode_t]]
  3112. typedef enum sizeform_mode_t
  3113. {
  3114. DC_SFORM_ALIGN = 0x01, // aligned output
  3115. DC_SFORM_CENTER = 0x02, // aligned and centered output
  3116. DC_SFORM_NARROW = 0x04, // suppress space between number and unit
  3117. DC_SFORM_UNIT1 = 0x08, // limit unit to 1 character (space for bytes)
  3118. DC_SFORM_INC = 0x10, // increment to next factor if no fraction is lost
  3119. DC_SFORM_PLUS = 0x20, // on signed output: print PLUS sign for values >0
  3120. DC_SFORM_DASH = 0x40, // on NULL: print only a dash (minus sign)
  3121. DC_SFORM__MASK = 0x7f, // mask of above
  3122. DC_SFORM__AUTO = 0x80, // hint for some functions to decide by themself
  3123. DC_SFORM_TINY = DC_SFORM_NARROW | DC_SFORM_UNIT1,
  3124. }
  3125. sizeform_mode_t;
  3126. ///////////////////////////////////////////////////////////////////////////////
  3127. float RoundF2bytes ( float f );
  3128. float RoundF3bytes ( float f );
  3129. double RoundD6bytes ( double d );
  3130. double RoundD7bytes ( double d );
  3131. ///////////////////////////////////////////////////////////////////////////////
  3132. // Parameters:
  3133. // char *buf, // result buffer
  3134. // // NULL: use a local circulary static buffer
  3135. // size_t buf_size, // size of 'buf', ignored if buf==NULL
  3136. // * num, // number to print
  3137. // sizeform_mode_t mode // any of DC_SFORM_ALIGN, DC_SFORM_DASH[not *D*()]
  3138. char * PrintNumberU4 ( char *buf, size_t buf_size, u64 num, sizeform_mode_t mode );
  3139. char * PrintNumberU5 ( char *buf, size_t buf_size, u64 num, sizeform_mode_t mode );
  3140. char * PrintNumberU6 ( char *buf, size_t buf_size, u64 num, sizeform_mode_t mode );
  3141. char * PrintNumberU7 ( char *buf, size_t buf_size, u64 num, sizeform_mode_t mode );
  3142. char * PrintNumberS5 ( char *buf, size_t buf_size, s64 num, sizeform_mode_t mode );
  3143. char * PrintNumberS6 ( char *buf, size_t buf_size, s64 num, sizeform_mode_t mode );
  3144. char * PrintNumberS7 ( char *buf, size_t buf_size, s64 num, sizeform_mode_t mode );
  3145. char * PrintNumberD5 ( char *buf, size_t buf_size, double num, sizeform_mode_t mode );
  3146. char * PrintNumberD6 ( char *buf, size_t buf_size, double num, sizeform_mode_t mode );
  3147. char * PrintNumberD7 ( char *buf, size_t buf_size, double num, sizeform_mode_t mode );
  3148. ///////////////////////////////////////////////////////////////////////////////
  3149. ///////////////////////////////////////////////////////////////////////////////
  3150. // [[size_mode_t]]
  3151. typedef enum size_mode_t
  3152. {
  3153. //----- modes => used as index for dc_size_tab_1000[] & dc_size_tab_1024[]
  3154. DC_SIZE_DEFAULT = 0, // special default value, fall back to AUTO
  3155. DC_SIZE_AUTO, // select unit automatically
  3156. DC_SIZE_BYTES, // force output in bytes
  3157. DC_SIZE_K, // force output in KB or KiB (kilo,kibi)
  3158. DC_SIZE_M, // force output in MB or MiB (mega,mebi)
  3159. DC_SIZE_G, // force output in GB or GiB (giga,gibi)
  3160. DC_SIZE_T, // force output in TB or TiB (tera,tebi)
  3161. DC_SIZE_P, // force output in PB or PiB (peta,pebi)
  3162. DC_SIZE_E, // force output in EB or EiB (exa, exbi)
  3163. // zetta/zebi & yotta/yobi not supported because >2^64
  3164. DC_SIZE_N_MODES, // number of modes
  3165. //----- flags
  3166. DC_SIZE_F_1000 = 0x010, // force output in SI units (kB=1000, MB=1000000,...)
  3167. DC_SIZE_F_1024 = 0x020, // force output in IEC units (KiB=1024, MiB=1024*1024,...)
  3168. DC_SIZE_F_AUTO_UNIT = 0x040, // suppress output of unit for non AUTO mode
  3169. DC_SIZE_F_NO_UNIT = 0x080, // suppress allways output of unit
  3170. //----- masks
  3171. DC_SIZE_M_MODE = 0x00f, // mask for modes
  3172. DC_SIZE_M_BASE = 0x030, // mask for base
  3173. DC_SIZE_M_ALL = 0x0ff, // all relevant bits
  3174. }
  3175. size_mode_t;
  3176. //-----------------------------------------------------------------------------
  3177. extern ccp dc_size_tab_1000[DC_SIZE_N_MODES+1];
  3178. extern ccp dc_size_tab_1024[DC_SIZE_N_MODES+1];
  3179. //-----------------------------------------------------------------------------
  3180. ccp GetSizeUnit // get a unit for column headers
  3181. (
  3182. size_mode_t mode, // print mode
  3183. ccp if_invalid // output for invalid modes
  3184. );
  3185. //-----------------------------------------------------------------------------
  3186. int GetSizeFW // get a good value field width
  3187. (
  3188. size_mode_t mode, // print mode
  3189. int min_fw // minimum fw => return max(calc_fw,min_fw);
  3190. // this value is also returned for invalid modes
  3191. );
  3192. //-----------------------------------------------------------------------------
  3193. char * PrintSize
  3194. (
  3195. char *buf, // result buffer
  3196. // NULL: use a local circulary static buffer
  3197. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3198. u64 size, // size to print
  3199. sizeform_mode_t sform_mode, // output format, bit field
  3200. size_mode_t mode // print mode
  3201. );
  3202. //-----------------------------------------------------------------------------
  3203. char * PrintSize1000
  3204. (
  3205. char *buf, // result buffer
  3206. // NULL: use a local circulary static buffer
  3207. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3208. u64 size, // size to print
  3209. sizeform_mode_t sform_mode // output format, bit field
  3210. );
  3211. //-----------------------------------------------------------------------------
  3212. char * PrintSize1024
  3213. (
  3214. char *buf, // result buffer
  3215. // NULL: use a local circulary static buffer
  3216. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3217. u64 size, // size to print
  3218. sizeform_mode_t sform_mode // output format, bit field
  3219. );
  3220. //
  3221. ///////////////////////////////////////////////////////////////////////////////
  3222. /////////////// scan size ///////////////
  3223. ///////////////////////////////////////////////////////////////////////////////
  3224. extern u64 (*ScanSizeFactorHook)
  3225. (
  3226. char ch_factor, // char to analyze
  3227. int force_base // if 1000|1024: force multiple of this
  3228. );
  3229. u64 ScanSizeFactor
  3230. (
  3231. char ch_factor, // char to analyze
  3232. int force_base // if 1000|1024: force multiple of this
  3233. );
  3234. char * ScanSizeTerm
  3235. (
  3236. double *num, // not NULL: store result
  3237. ccp source, // source text
  3238. u64 default_factor, // use this factor if number hasn't one
  3239. int force_base // if 1000|1024: force multiple of this
  3240. );
  3241. char * ScanSize
  3242. (
  3243. double *num, // not NULL: store result
  3244. ccp source, // source text
  3245. u64 default_factor, // use this factor if number hasn't one
  3246. u64 default_factor_add, // use this factor for summands
  3247. int force_base // if 1000|1024: force multiple of this
  3248. );
  3249. char * ScanSizeU32
  3250. (
  3251. u32 *num, // not NULL: store result
  3252. ccp source, // source text
  3253. u64 default_factor, // use this factor if number hasn't one
  3254. u64 default_factor_add, // use this factor for summands
  3255. int force_base // if 1000|1024: force multiple of this
  3256. );
  3257. char * ScanSizeU64
  3258. (
  3259. u64 *num, // not NULL: store result
  3260. ccp source, // source text
  3261. u64 default_factor, // use this factor if number hasn't one
  3262. u64 default_factor_add, // use this factor for summands
  3263. int force_base // if 1000|1024: force multiple of this
  3264. );
  3265. //-----------------------------------------------------------------------------
  3266. // strto*() like wrappers
  3267. u32 GetSizeU32 ( ccp src, char **end, int force_base );
  3268. u64 GetSizeU64 ( ccp src, char **end, int force_base );
  3269. double GetSizeD ( ccp src, char **end, int force_base );
  3270. //-----------------------------------------------------------------------------
  3271. // [[range_opt_t]]
  3272. typedef enum range_opt_t
  3273. {
  3274. RAOPT_COLON = 0x01, // allow ':' as from/to separator
  3275. RAOPT_MINUS = 0x02, // allow '-' as from/to separator
  3276. RAOPT_HASH = 0x04, // allow '#' as from/size separator
  3277. RAOPT_COMMA = 0x08, // allow ',' as from/size separator
  3278. RAOPT_NEG = 0x10, // accept negative numbers as index relative to max_value
  3279. RAOPT_ASSUME_0 = 0x20, // allow ':-#,' as first char and assume 0 as first value
  3280. RAOPT_F_FORCE = 0x40, // flag to avoid value 0 as default alias
  3281. RAOPT__ALL = 0x7f, // all possible bits
  3282. RAOPT__DEFAULT = RAOPT_COLON | RAOPT_HASH,
  3283. }
  3284. range_opt_t;
  3285. //-----------------------------------------------------------------------------
  3286. char * ScanSizeRange
  3287. (
  3288. int *stat, // if not NULL: store result
  3289. // 0:none, 1:single, 2:range
  3290. double *num1, // not NULL: store 'from' result
  3291. double *num2, // not NULL: store 'to' result
  3292. ccp source, // source text
  3293. u64 default_factor, // use this factor if number hasn't one
  3294. u64 default_factor_add, // use this factor for summands
  3295. int force_base, // if 1000|1024: force multiple of this
  3296. double max_value, // >0: max value for open ranges
  3297. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3298. );
  3299. char * ScanSizeRangeU32
  3300. (
  3301. int *stat, // if not NULL: store result
  3302. // 0:none, 1:single, 2:range
  3303. u32 *num1, // not NULL: store 'from' result
  3304. u32 *num2, // not NULL: store 'to' result
  3305. ccp source, // source text
  3306. u64 default_factor, // use this factor if number hasn't one
  3307. u64 default_factor_add, // use this factor for summands
  3308. int force_base, // if 1000|1024: force multiple of this
  3309. u32 max_value, // >0: max value for open ranges
  3310. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3311. );
  3312. char * ScanSizeRangeS32
  3313. (
  3314. int *stat, // if not NULL: store result
  3315. // 0:none, 1:single, 2:range
  3316. s32 *num1, // not NULL: store 'from' result
  3317. s32 *num2, // not NULL: store 'to' result
  3318. ccp source, // source text
  3319. u64 default_factor, // use this factor if number hasn't one
  3320. u64 default_factor_add, // use this factor for summands
  3321. int force_base, // if 1000|1024: force multiple of this
  3322. s32 max_value, // >0: max value for open ranges
  3323. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3324. );
  3325. char * ScanSizeRangeU64
  3326. (
  3327. int *stat, // if not NULL: store result
  3328. // 0:none, 1:single, 2:range
  3329. u64 *num1, // not NULL: store 'from' result
  3330. u64 *num2, // not NULL: store 'to' result
  3331. ccp source, // source text
  3332. u64 default_factor, // use this factor if number hasn't one
  3333. u64 default_factor_add, // use this factor for summands
  3334. int force_base, // if 1000|1024: force multiple of this
  3335. u64 max_value, // >0: max value for open ranges
  3336. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3337. );
  3338. char * ScanSizeRangeS64
  3339. (
  3340. int *stat, // if not NULL: store result
  3341. // 0:none, 1:single, 2:range
  3342. s64 *num1, // not NULL: store 'from' result
  3343. s64 *num2, // not NULL: store 'to' result
  3344. ccp source, // source text
  3345. u64 default_factor, // use this factor if number hasn't one
  3346. u64 default_factor_add, // use this factor for summands
  3347. int force_base, // if 1000|1024: force multiple of this
  3348. s64 max_value, // >0: max value for open ranges
  3349. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3350. );
  3351. //-----------------------------------------------------------------------------
  3352. char * ScanSizeRangeList
  3353. (
  3354. uint *n_range, // not NULL: store number of scanned ranges
  3355. double *num, // array with '2*max_range' elements
  3356. // unused elements are filled with 0.0
  3357. uint max_range, // max number of allowed ranges
  3358. ccp source, // source text
  3359. u64 default_factor, // use this factor if number hasn't one
  3360. u64 default_factor_add, // use this factor for summands
  3361. int force_base, // if 1000|1024: force multiple of this
  3362. double max_value, // >0: max value for open ranges
  3363. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3364. );
  3365. char * ScanSizeRangeListU32
  3366. (
  3367. uint *n_range, // not NULL: store number of scanned ranges
  3368. u32 *num, // array with '2*max_range' elements
  3369. // unused elements are filled with 0
  3370. uint max_range, // max number of allowed ranges
  3371. ccp source, // source text
  3372. u32 default_factor, // use this factor if number hasn't one
  3373. u32 default_factor_add, // use this factor for summands
  3374. int force_base, // if 1000|1024: force multiple of this
  3375. u32 max_value, // >0: max value for open ranges
  3376. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3377. );
  3378. char * ScanSizeRangeListU64
  3379. (
  3380. uint *n_range, // not NULL: store number of scanned ranges
  3381. u64 *num, // array with '2*max_range' elements
  3382. // unused elements are filled with 0
  3383. uint max_range, // max number of allowed ranges
  3384. ccp source, // source text
  3385. u64 default_factor, // use this factor if number hasn't one
  3386. u64 default_factor_add, // use this factor for summands
  3387. int force_base, // if 1000|1024: force multiple of this
  3388. u64 max_value, // >0: max value for open ranges
  3389. range_opt_t opt // options, if 0 then use RAOPT__DEFAULT
  3390. );
  3391. //-----------------------------------------------------------------------------
  3392. enumError ScanSizeOpt
  3393. (
  3394. double *num, // not NULL: store result
  3395. ccp source, // source text
  3396. u64 default_factor, // use this factor if number hasn't one
  3397. u64 default_factor_add, // use this factor for summands
  3398. int force_base, // if 1000|1024: force multiple of this
  3399. ccp opt_name, // NULL or name of option for error messages
  3400. u64 min, // >0: minimum allowed value
  3401. u64 max, // >0: maximum allowed value
  3402. bool print_err // true: print error messages
  3403. );
  3404. enumError ScanSizeOptU64
  3405. (
  3406. u64 *num, // not NULL: store result
  3407. ccp source, // source text
  3408. u64 default_factor, // use this factor if number hasn't one
  3409. int force_base, // if 1000|1024: force multiple of this
  3410. ccp opt_name, // NULL or name of option for error messages
  3411. u64 min, // >0: minimum allowed value
  3412. u64 max, // >0: maximum allowed value
  3413. u32 multiple, // >0: result must be multiple
  3414. u32 pow2, // >0: result must power of '1<<pow2'
  3415. bool print_err // true: print error messages
  3416. );
  3417. enumError ScanSizeOptU32
  3418. (
  3419. u32 *num, // not NULL: store result
  3420. ccp source, // source text
  3421. u64 default_factor, // use this factor if number hasn't one
  3422. int force_base, // if 1000|1024: force multiple of this
  3423. ccp opt_name, // NULL or name of option for error messages
  3424. u64 min, // >0: minimum allowed value
  3425. u64 max, // >0: maximum allowed value
  3426. u32 multiple, // >0: result must be multiple
  3427. u32 pow2, // >0: result must power of '1<<pow2'
  3428. bool print_err // true: print error messages
  3429. );
  3430. //
  3431. ///////////////////////////////////////////////////////////////////////////////
  3432. /////////////// time & timer ///////////////
  3433. ///////////////////////////////////////////////////////////////////////////////
  3434. //--- conversion factors
  3435. #define SEC_PER_MIN 60
  3436. #define SEC_PER_HOUR 3600
  3437. #define SEC_PER_DAY 86400
  3438. #define SEC_PER_WEEK 604800
  3439. #define SEC_PER_MONTH 2629746 // 365.2425 * SEC_PER_DAY / 12
  3440. #define SEC_PER_QUARTER 7889238 // 365.2425 * SEC_PER_DAY / 4
  3441. #define SEC_PER_YEAR 31556952 // 365.2425 * SEC_PER_DAY
  3442. #define MSEC_PER_SEC 1000ll
  3443. #define MSEC_PER_MIN (MSEC_PER_SEC*SEC_PER_MIN)
  3444. #define MSEC_PER_HOUR (MSEC_PER_SEC*SEC_PER_HOUR)
  3445. #define MSEC_PER_DAY (MSEC_PER_SEC*SEC_PER_DAY)
  3446. #define MSEC_PER_WEEK (MSEC_PER_SEC*SEC_PER_WEEK)
  3447. #define MSEC_PER_MONTH (MSEC_PER_SEC*SEC_PER_MONTH)
  3448. #define MSEC_PER_QUARTER (MSEC_PER_SEC*SEC_PER_QUARTER)
  3449. #define MSEC_PER_YEAR (MSEC_PER_SEC*SEC_PER_YEAR)
  3450. #define USEC_PER_MSEC 1000ll
  3451. #define USEC_PER_SEC 1000000ll
  3452. #define USEC_PER_MIN (USEC_PER_SEC*SEC_PER_MIN)
  3453. #define USEC_PER_HOUR (USEC_PER_SEC*SEC_PER_HOUR)
  3454. #define USEC_PER_DAY (USEC_PER_SEC*SEC_PER_DAY)
  3455. #define USEC_PER_WEEK (USEC_PER_SEC*SEC_PER_WEEK)
  3456. #define USEC_PER_MONTH (USEC_PER_SEC*SEC_PER_MONTH)
  3457. #define USEC_PER_QUARTER (USEC_PER_SEC*SEC_PER_QUARTER)
  3458. #define USEC_PER_YEAR (USEC_PER_SEC*SEC_PER_YEAR)
  3459. #define NSEC_PER_USEC 1000ll
  3460. #define NSEC_PER_MSEC 1000000ll
  3461. #define NSEC_PER_SEC 1000000000ll
  3462. #define NSEC_PER_MIN (NSEC_PER_SEC*SEC_PER_MIN)
  3463. #define NSEC_PER_HOUR (NSEC_PER_SEC*SEC_PER_HOUR)
  3464. #define NSEC_PER_DAY (NSEC_PER_SEC*SEC_PER_DAY)
  3465. #define NSEC_PER_WEEK (NSEC_PER_SEC*SEC_PER_WEEK)
  3466. #define NSEC_PER_MONTH (NSEC_PER_SEC*SEC_PER_MONTH)
  3467. #define NSEC_PER_QUARTER (NSEC_PER_SEC*SEC_PER_QUARTER)
  3468. #define NSEC_PER_YEAR (NSEC_PER_SEC*SEC_PER_YEAR)
  3469. //--- time types
  3470. typedef uint u_sec_t; // unsigned type to store time as seconds
  3471. typedef int s_sec_t; // signed type to store time as seconds
  3472. typedef u64 u_msec_t; // unsigned type to store time as milliseconds
  3473. typedef s64 s_msec_t; // signed type to store time as milliseconds
  3474. typedef u64 u_usec_t; // unsigned type to store time as microseconds
  3475. typedef s64 s_usec_t; // signed type to store time as microseconds
  3476. typedef u64 u_nsec_t; // unsigned type to store time as nanoseconds
  3477. typedef s64 s_nsec_t; // signed type to store time as nanoseconds
  3478. //--- max values time types
  3479. #define S_SEC_MAX S32_MAX
  3480. #define U_SEC_MAX U32_MAX
  3481. #define S_MSEC_MAX S64_MAX
  3482. #define U_MSEC_MAX U64_MAX
  3483. #define S_USEC_MAX S64_MAX
  3484. #define U_USEC_MAX U64_MAX
  3485. #define S_NSEC_MAX S64_MAX
  3486. #define U_NSEC_MAX U64_MAX
  3487. //-----------------------------------------------------------------------------
  3488. // [[DayTime_t]]
  3489. typedef struct DayTime_t
  3490. {
  3491. time_t time; // seconds since epoch, like time()
  3492. int day; // days since epoch
  3493. int hour; // hour of day
  3494. int min; // minute of hour
  3495. int sec; // second of minute
  3496. int usec; // microsecond of second
  3497. int nsec; // nanosecond of second
  3498. }
  3499. DayTime_t;
  3500. //--- only valid after call to SetupTimezone()
  3501. extern s64 timezone_adjust_sec;
  3502. extern s64 timezone_adjust_usec;
  3503. extern s64 timezone_adjust_nsec;
  3504. extern int timezone_adjust_isdst;
  3505. ///////////////////////////////////////////////////////////////////////////////
  3506. extern ccp micro_second_char; // default = "u"
  3507. static inline void SetMicroSecondChar ( bool use_micro )
  3508. { micro_second_char = use_micro ? "µ" : "u"; }
  3509. ///////////////////////////////////////////////////////////////////////////////
  3510. void SetupTimezone ( bool force );
  3511. int GetTimezoneAdjust ( time_t tim );
  3512. struct timeval GetTimeOfDay ( bool localtime );
  3513. struct timespec GetClockTime ( bool localtime );
  3514. DayTime_t GetDayTime ( bool localtime );
  3515. u_sec_t GetTimeSec ( bool localtime );
  3516. u_msec_t GetTimeMSec ( bool localtime );
  3517. u_usec_t GetTimeUSec ( bool localtime );
  3518. u_nsec_t GetTimeNSec ( bool localtime );
  3519. struct timespec GetClockTimer(void);
  3520. u_sec_t GetTimerSec(void);
  3521. u_msec_t GetTimerMSec(void);
  3522. u_usec_t GetTimerUSec(void);
  3523. u_nsec_t GetTimerNSec(void);
  3524. //-----------------------------------------------------------------------------
  3525. static inline u_sec_t Time2TimerSec ( u_sec_t tim, bool localtime )
  3526. { return tim - GetTimeSec(localtime) + GetTimerSec(); }
  3527. static inline u_msec_t Time2TimerMSec ( u_msec_t tim, bool localtime )
  3528. { return tim - GetTimeMSec(localtime) + GetTimerMSec(); }
  3529. static inline u_usec_t Time2TimerUSec ( u_usec_t tim, bool localtime )
  3530. { return tim - GetTimeUSec(localtime) + GetTimerUSec(); }
  3531. static inline u_nsec_t Time2TimerNSec ( u_nsec_t tim, bool localtime )
  3532. { return tim - GetTimeNSec(localtime) + GetTimerNSec(); }
  3533. static inline u_sec_t Timer2TimeSec ( u_sec_t tim, bool localtime )
  3534. { return tim - GetTimerSec() + GetTimeSec(localtime); }
  3535. static inline u_msec_t Timer2TimeMSec ( u_msec_t tim, bool localtime )
  3536. { return tim - GetTimerMSec() + GetTimeMSec(localtime); }
  3537. static inline u_usec_t Timer2TimeUSec ( u_usec_t tim, bool localtime )
  3538. { return tim - GetTimerUSec() + GetTimeUSec(localtime); }
  3539. static inline u_nsec_t Timer2TimeNSec ( u_nsec_t tim, bool localtime )
  3540. { return tim - GetTimerNSec() + GetTimeNSec(localtime); }
  3541. //-----------------------------------------------------------------------------
  3542. static inline u_sec_t double2sec ( double d ) { return d>0.0 ? (u_msec_t)trunc( d+0.5 ) : 0; }
  3543. static inline u_msec_t double2msec ( double d ) { return d>0.0 ? (u_msec_t)trunc( 1e3*d+0.5 ) : 0; }
  3544. static inline u_usec_t double2usec ( double d ) { return d>0.0 ? (u_usec_t)trunc( 1e6*d+0.5 ) : 0; }
  3545. static inline u_nsec_t double2nsec ( double d ) { return d>0.0 ? (u_nsec_t)trunc( 1e9*d+0.5 ) : 0; }
  3546. static inline s_sec_t double2ssec ( double d ) { return (s_sec_t) floor( d+0.5 ); }
  3547. static inline s_msec_t double2smsec ( double d ) { return (s_msec_t) floor( 1e3*d+0.5 ); }
  3548. static inline s_usec_t double2susec ( double d ) { return (s_usec_t) floor( 1e6*d+0.5 ); }
  3549. static inline s_nsec_t double2snsec ( double d ) { return (s_nsec_t) floor( 1e9*d+0.5 ); }
  3550. static inline double sec2double ( s_sec_t num ) { return num; }
  3551. static inline double msec2double ( s_msec_t num ) { return num * 1e-3; }
  3552. static inline double usec2double ( s_usec_t num ) { return num * 1e-6; }
  3553. static inline double nsec2double ( s_nsec_t num ) { return num * 1e-9; }
  3554. //--- another epoch: Monday, 2001-01-01
  3555. #define EPOCH_2001_SEC 0x3a4fc880
  3556. #define EPOCH_2001_MSEC (EPOCH_2001_SEC*MSEC_PER_SEC)
  3557. #define EPOCH_2001_USEC (EPOCH_2001_SEC*USEC_PER_SEC)
  3558. #define EPOCH_2001_NSEC (EPOCH_2001_SEC*NSEC_PER_SEC)
  3559. ///////////////////////////////////////////////////////////////////////////////
  3560. // [[CurrentTime_t]]
  3561. typedef struct CurrentTime_t
  3562. {
  3563. u_sec_t sec;
  3564. u_msec_t msec;
  3565. u_usec_t usec;
  3566. }
  3567. CurrentTime_t;
  3568. //-----------------------------------------------------------------------------
  3569. CurrentTime_t GetCurrentTime ( bool localtime );
  3570. extern CurrentTime_t current_time;
  3571. static inline void UpdateCurrentTime(void)
  3572. { current_time = GetCurrentTime(false); }
  3573. ///////////////////////////////////////////////////////////////////////////////
  3574. ///////////////////////////////////////////////////////////////////////////////
  3575. // PrintRefTime*() return temporary buffer by GetCircBuf(), field width 10
  3576. // Formats:
  3577. // ±10h: " %k:%M:%S"
  3578. // ±12d: " %e. %k:%M"
  3579. // *: "%F"
  3580. ccp PrintRefTime
  3581. (
  3582. u_sec_t tim, // seconds since epoch; 0 is replaced by time()
  3583. u_sec_t *ref_tim // NULL or ref_tim; if *ref_tim==0: write current time
  3584. // it is used to select format
  3585. );
  3586. ccp PrintRefTimeUTC
  3587. (
  3588. u_sec_t tim, // seconds since epoch; 0 is replaced by time()
  3589. u_sec_t *ref_tim // NULL or ref_tim; if *ref_tim==0: write current time
  3590. // it is used to select format
  3591. );
  3592. //-----------------------------------------------------------------------------
  3593. ccp PrintTimeByFormat
  3594. (
  3595. // returns temporary buffer by GetCircBuf();
  3596. ccp format, // format string for strftime()
  3597. u_sec_t tim // seconds since epoch; 0 is replaced by time()
  3598. );
  3599. ccp PrintTimeByFormatUTC
  3600. (
  3601. // returns temporary buffer by GetCircBuf();
  3602. ccp format, // format string for strftime()
  3603. u_sec_t tim // seconds since epoch; 0 is replaced by time()
  3604. );
  3605. //-----------------------------------------------------------------------------
  3606. ccp PrintNSecByFormat
  3607. (
  3608. // returns temporary buffer by GetCircBuf();
  3609. ccp format, // format string for strftime()
  3610. // 1-9 '@' in row replaced by digits of 'nsec'
  3611. time_t tim, // seconds since epoch
  3612. uint nsec // nanosecond of second
  3613. );
  3614. ccp PrintNSecByFormatUTC
  3615. (
  3616. // returns temporary buffer by GetCircBuf();
  3617. ccp format, // format string for strftime()
  3618. // 1-9 '@' in row replaced by digits of 'nsec'
  3619. time_t tim, // seconds since epoch
  3620. uint nsec // nanosecond of second
  3621. );
  3622. ccp PrintNTimeByFormat
  3623. (
  3624. // returns temporary buffer by GetCircBuf();
  3625. ccp format, // format string for strftime()
  3626. // 1-9 '@' in row replaced by digits of 'usec'
  3627. u_nsec_t ntime
  3628. );
  3629. ccp PrintNTimeByFormatUTC
  3630. (
  3631. // returns temporary buffer by GetCircBuf();
  3632. ccp format, // format string for strftime()
  3633. // 1-9 '@' in row replaced by digits of 'usec'
  3634. u_nsec_t ntime
  3635. );
  3636. //-----------------------------------------------------------------------------
  3637. static inline ccp PrintUSecByFormat
  3638. (
  3639. // returns temporary buffer by GetCircBuf();
  3640. ccp format, // format string for strftime()
  3641. // 1-9 '@' in row replaced by digits of 'usec'
  3642. time_t tim, // seconds since epoch
  3643. uint usec // microsecond of second
  3644. )
  3645. {
  3646. return PrintNSecByFormat(format,tim,usec*NSEC_PER_USEC);
  3647. }
  3648. static inline ccp PrintUSecByFormatUTC
  3649. (
  3650. // returns temporary buffer by GetCircBuf();
  3651. ccp format, // format string for strftime()
  3652. // 1-9 '@' in row replaced by digits of 'usec'
  3653. time_t tim, // seconds since epoch
  3654. uint usec // microsecond of second
  3655. )
  3656. {
  3657. return PrintNSecByFormatUTC(format,tim,usec*NSEC_PER_USEC);
  3658. }
  3659. ccp PrintUTimeByFormat
  3660. (
  3661. // returns temporary buffer by GetCircBuf();
  3662. ccp format, // format string for strftime()
  3663. // 1-9 '@' in row replaced by digits of 'usec'
  3664. u_usec_t utime
  3665. );
  3666. ccp PrintUTimeByFormatUTC
  3667. (
  3668. // returns temporary buffer by GetCircBuf();
  3669. ccp format, // format string for strftime()
  3670. // 1-9 '@' in row replaced by digits of 'usec'
  3671. u_usec_t utime
  3672. );
  3673. //-----------------------------------------------------------------------------
  3674. static inline ccp PrintMSecByFormat
  3675. (
  3676. // returns temporary buffer by GetCircBuf();
  3677. ccp format, // format string for strftime()
  3678. // 1-9 '@' in row replaced by digits of 'usec'
  3679. time_t tim, // seconds since epoch
  3680. uint msec // millisecond of second
  3681. )
  3682. {
  3683. return PrintNSecByFormat(format,tim,msec*NSEC_PER_MSEC);
  3684. }
  3685. static inline ccp PrintMSecByFormatUTC
  3686. (
  3687. // returns temporary buffer by GetCircBuf();
  3688. ccp format, // format string for strftime()
  3689. // 1-9 '@' in row replaced by digits of 'usec'
  3690. time_t tim, // seconds since epoch
  3691. uint msec // millisecond of second
  3692. )
  3693. {
  3694. return PrintNSecByFormatUTC(format,tim,msec*NSEC_PER_MSEC);
  3695. }
  3696. ccp PrintMTimeByFormat
  3697. (
  3698. // returns temporary buffer by GetCircBuf();
  3699. ccp format, // format string for strftime()
  3700. // 1-9 '@' in row replaced by digits of 'usec'
  3701. u_msec_t mtime
  3702. );
  3703. ccp PrintMTimeByFormatUTC
  3704. (
  3705. // returns temporary buffer by GetCircBuf();
  3706. ccp format, // format string for strftime()
  3707. // 1-9 '@' in row replaced by digits of 'usec'
  3708. u_msec_t mtime
  3709. );
  3710. //-----------------------------------------------------------------------------
  3711. ccp PrintTimevalByFormat
  3712. (
  3713. // returns temporary buffer by GetCircBuf();
  3714. ccp format, // format string for strftime()
  3715. const struct timeval *tv // time to print, if NULL use gettimeofday()
  3716. );
  3717. ccp PrintTimevalByFormatUTC
  3718. (
  3719. // returns temporary buffer by GetCircBuf();
  3720. ccp format, // format string for strftime()
  3721. const struct timeval *tv // time to print, if NULL use gettimeofday()
  3722. );
  3723. //-----------------------------------------------------------------------------
  3724. ccp PrintTimespecByFormat
  3725. (
  3726. // returns temporary buffer by GetCircBuf();
  3727. ccp format, // format string for strftime()
  3728. const struct timespec *ts // time to print, if NULL use GetClockTime(false)
  3729. );
  3730. ccp PrintTimespecByFormatUTC
  3731. (
  3732. // returns temporary buffer by GetCircBuf();
  3733. ccp format, // format string for strftime()
  3734. const struct timespec *ts // time to print, if NULL use GetClockTime(false)
  3735. );
  3736. ///////////////////////////////////////////////////////////////////////////////
  3737. ccp PrintTimeSec
  3738. (
  3739. char * buf, // result buffer (>19 bytes are good)
  3740. // If NULL, a local circulary static buffer is used
  3741. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3742. u_sec_t sec // seconds (=time) to print
  3743. );
  3744. ccp PrintTimeMSec
  3745. (
  3746. char * buf, // result buffer (>23 bytes are good)
  3747. // If NULL, a local circulary static buffer is used
  3748. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3749. u_msec_t msec, // milliseconds to print
  3750. uint fraction // number of digits (0-3) to print as fraction
  3751. );
  3752. ccp PrintTimeUSec
  3753. (
  3754. char * buf, // result buffer (>26 bytes are good)
  3755. // If NULL, a local circulary static buffer is used
  3756. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3757. u_usec_t usec, // microseconds to print
  3758. uint fraction // number of digits (0-6) to print as fraction
  3759. );
  3760. ccp PrintTimeNSec
  3761. (
  3762. char * buf, // result buffer (>26 bytes are good)
  3763. // If NULL, a local circulary static buffer is used
  3764. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3765. u_nsec_t nsec, // nanoseconds to print
  3766. uint fraction // number of digits (0-9) to print as fraction
  3767. );
  3768. //-----------------------------------------------------------------------------
  3769. ccp PrintTimerMSec
  3770. (
  3771. char * buf, // result buffer (>12 bytes are good)
  3772. // If NULL, a local circulary static buffer is used
  3773. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3774. u32 msec, // milliseconds to print
  3775. uint fraction // number of digits (0-3) to print as fraction
  3776. );
  3777. ccp PrintTimerUSec
  3778. (
  3779. char * buf, // result buffer (>16 bytes are good)
  3780. // If NULL, a local circulary static buffer is used
  3781. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3782. s_usec_t usec, // microseconds to print
  3783. uint fraction // number of digits (0-6) to print as fraction
  3784. );
  3785. ccp PrintTimerNSec
  3786. (
  3787. char * buf, // result buffer (>16 bytes are good)
  3788. // If NULL, a local circulary static buffer is used
  3789. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3790. s_nsec_t nsec, // nanoseconds to print
  3791. uint fraction // number of digits (0-9) to print as fraction
  3792. );
  3793. //-----------------------------------------------------------------------------
  3794. ccp PrintTimer3 // helper function
  3795. (
  3796. char * buf, // result buffer (>3 bytes)
  3797. // If NULL, a local circulary static buffer is used
  3798. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3799. u64 sec, // seconds to print
  3800. int usec, // 0...999999: usec fraction,
  3801. // otherwise suppress ms/us output
  3802. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3803. );
  3804. static inline ccp PrintTimerSec3
  3805. (
  3806. char * buf, // result buffer (>3 bytes)
  3807. // If NULL, a local circulary static buffer is used
  3808. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3809. u_sec_t sec, // seconds to print
  3810. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3811. )
  3812. {
  3813. return PrintTimer3(buf,buf_size,sec,-1,mode);
  3814. }
  3815. static inline ccp PrintTimerMSec3
  3816. (
  3817. char * buf, // result buffer (>3 bytes)
  3818. // If NULL, a local circulary static buffer is used
  3819. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3820. u_msec_t msec, // microseconds to print
  3821. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3822. )
  3823. {
  3824. return PrintTimer3(buf,buf_size,msec/1000,msec%1000*1000,mode);
  3825. }
  3826. static inline ccp PrintTimerUSec3
  3827. (
  3828. char * buf, // result buffer (>3 bytes)
  3829. // If NULL, a local circulary static buffer is used
  3830. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3831. u_usec_t usec, // microseconds to print
  3832. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3833. )
  3834. {
  3835. return PrintTimer3(buf,buf_size,usec/1000000,usec%1000000,mode);
  3836. }
  3837. //-----------------------------------------------------------------------------
  3838. ccp PrintTimer4 // helper function
  3839. (
  3840. char * buf, // result buffer (>4 bytes)
  3841. // If NULL, a local circulary static buffer is used
  3842. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3843. u64 sec, // seconds to print
  3844. int usec, // 0...999999: usec fraction,
  3845. // otherwise suppress ms/us output
  3846. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3847. );
  3848. static inline ccp PrintTimerSec4
  3849. (
  3850. char * buf, // result buffer (>4 bytes)
  3851. // If NULL, a local circulary static buffer is used
  3852. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3853. u_sec_t sec, // seconds to print
  3854. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3855. )
  3856. {
  3857. return PrintTimer4(buf,buf_size,sec,-1,mode);
  3858. }
  3859. static inline ccp PrintTimerMSec4
  3860. (
  3861. char * buf, // result buffer (>4 bytes)
  3862. // If NULL, a local circulary static buffer is used
  3863. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3864. u_msec_t msec, // microseconds to print
  3865. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3866. )
  3867. {
  3868. return PrintTimer4(buf,buf_size,msec/MSEC_PER_SEC,msec%MSEC_PER_SEC*USEC_PER_SEC,mode);
  3869. }
  3870. static inline ccp PrintTimerUSec4
  3871. (
  3872. char * buf, // result buffer (>4 bytes)
  3873. // If NULL, a local circulary static buffer is used
  3874. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3875. u_usec_t usec, // microseconds to print
  3876. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3877. )
  3878. {
  3879. return PrintTimer4(buf,buf_size,usec/USEC_PER_SEC,usec%USEC_PER_SEC,mode);
  3880. }
  3881. static inline ccp PrintTimerNSec4
  3882. (
  3883. char * buf, // result buffer (>4 bytes)
  3884. // If NULL, a local circulary static buffer is used
  3885. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3886. u_nsec_t nsec, // nanoseconds to print
  3887. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_DASH
  3888. )
  3889. {
  3890. const u_usec_t usec = nsec / NSEC_PER_USEC;
  3891. return PrintTimer4(buf,buf_size,usec/USEC_PER_SEC,usec%USEC_PER_SEC,mode);
  3892. }
  3893. //-----------------------------------------------------------------------------
  3894. ccp PrintTimer6N // helper function
  3895. (
  3896. char * buf, // result buffer (>6 bytes)
  3897. // If NULL, a local circulary static buffer is used
  3898. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3899. u64 sec, // seconds to print
  3900. int nsec, // 0...999999999: nsec fraction,
  3901. // otherwise suppress ms/us/ns output
  3902. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_CENTER | DC_SFORM_DASH
  3903. );
  3904. static inline ccp PrintTimerSec6
  3905. (
  3906. char * buf, // result buffer (>6 bytes)
  3907. // If NULL, a local circulary static buffer is used
  3908. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3909. u_sec_t sec, // seconds to print
  3910. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_CENTER | DC_SFORM_DASH
  3911. )
  3912. {
  3913. return PrintTimer6N(buf,buf_size,sec,-1,mode);
  3914. }
  3915. static inline ccp PrintTimerMSec6
  3916. (
  3917. char * buf, // result buffer (>6 bytes)
  3918. // If NULL, a local circulary static buffer is used
  3919. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3920. u_msec_t msec, // microseconds to print
  3921. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_CENTER | DC_SFORM_DASH
  3922. )
  3923. {
  3924. return PrintTimer6N( buf, buf_size,
  3925. msec/MSEC_PER_SEC, msec%MSEC_PER_SEC*NSEC_PER_MSEC, mode );
  3926. }
  3927. static inline ccp PrintTimerUSec6
  3928. (
  3929. char * buf, // result buffer (>6 bytes)
  3930. // If NULL, a local circulary static buffer is used
  3931. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3932. u_usec_t usec, // microseconds to print
  3933. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_CENTER | DC_SFORM_DASH
  3934. )
  3935. {
  3936. return PrintTimer6N( buf, buf_size,
  3937. usec/USEC_PER_SEC, usec%USEC_PER_SEC*NSEC_PER_USEC, mode );
  3938. }
  3939. static inline ccp PrintTimerNSec6
  3940. (
  3941. char * buf, // result buffer (>6 bytes)
  3942. // If NULL, a local circulary static buffer is used
  3943. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3944. u_nsec_t nsec, // nanoseconds to print
  3945. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_CENTER | DC_SFORM_DASH
  3946. )
  3947. {
  3948. return PrintTimer6N( buf, buf_size,
  3949. nsec/NSEC_PER_SEC, nsec%NSEC_PER_SEC, mode );
  3950. }
  3951. //-----------------------------------------------------------------------------
  3952. ccp PrintTimerUSec4s
  3953. (
  3954. char * buf, // result buffer (>4 bytes)
  3955. // If NULL, a local circulary static buffer is used
  3956. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3957. s_usec_t usec, // microseconds to print
  3958. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  3959. );
  3960. static inline ccp PrintTimerNSec4s
  3961. (
  3962. char * buf, // result buffer (>4 bytes)
  3963. // If NULL, a local circulary static buffer is used
  3964. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3965. s_nsec_t nsec, // nanoseconds to print
  3966. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  3967. )
  3968. {
  3969. return PrintTimerUSec4s(buf,buf_size,nsec/NSEC_PER_USEC,mode);
  3970. }
  3971. static inline ccp PrintTimerMSec4s
  3972. (
  3973. char * buf, // result buffer (>4 bytes)
  3974. // If NULL, a local circulary static buffer is used
  3975. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3976. s_msec_t msec, // milliseconds to print
  3977. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  3978. )
  3979. {
  3980. return PrintTimerUSec4s(buf,buf_size,msec*USEC_PER_MSEC,mode);
  3981. }
  3982. static inline ccp PrintTimerSec4s
  3983. (
  3984. char * buf, // result buffer (>4 bytes)
  3985. // If NULL, a local circulary static buffer is used
  3986. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3987. int sec, // seconds to print
  3988. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  3989. )
  3990. {
  3991. return PrintTimerUSec4s(buf,buf_size,1000000ll*sec,mode);
  3992. }
  3993. //-----------------------------------------------------------------------------
  3994. ccp PrintTimerNSec7s
  3995. (
  3996. char * buf, // result buffer (>7 bytes)
  3997. // If NULL, a local circulary static buffer is used
  3998. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3999. s_nsec_t nsec, // nanoseconds to print
  4000. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  4001. );
  4002. ccp PrintTimerUSec7s
  4003. (
  4004. char * buf, // result buffer (>7 bytes)
  4005. // If NULL, a local circulary static buffer is used
  4006. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4007. s_usec_t usec, // microseconds to print
  4008. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  4009. );
  4010. static inline ccp PrintTimerMSec7s
  4011. (
  4012. char * buf, // result buffer (>7 bytes)
  4013. // If NULL, a local circulary static buffer is used
  4014. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4015. s_msec_t msec, // milliseconds to print
  4016. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  4017. )
  4018. {
  4019. return PrintTimerUSec7s(buf,buf_size,1000*msec,mode);
  4020. }
  4021. static inline ccp PrintTimerSec7s
  4022. (
  4023. char * buf, // result buffer (>7 bytes)
  4024. // If NULL, a local circulary static buffer is used
  4025. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4026. int sec, // seconds to print
  4027. sizeform_mode_t mode // DC_SFORM_ALIGN | DC_SFORM_PLUS | DC_SFORM_DASH
  4028. )
  4029. {
  4030. return PrintTimerUSec7s(buf,buf_size,1000000ll*sec,mode);
  4031. }
  4032. //-----------------------------------------------------------------------------
  4033. ccp PrintAge3Sec
  4034. (
  4035. u_sec_t now, // NULL or current time by GetTimeSec(false)
  4036. u_sec_t time // time to print
  4037. );
  4038. ccp PrintAge4Sec
  4039. (
  4040. u_sec_t now, // NULL or current time by GetTimeSec(false)
  4041. u_sec_t time // time to print
  4042. );
  4043. ccp PrintAge6Sec
  4044. (
  4045. u_sec_t now, // NULL or current time by GetTimeSec(false)
  4046. u_sec_t time // time to print
  4047. );
  4048. ccp PrintAge7Sec
  4049. (
  4050. u_sec_t now, // NULL or current time by GetTimeSec(false)
  4051. u_sec_t time // time to print
  4052. );
  4053. //
  4054. ///////////////////////////////////////////////////////////////////////////////
  4055. /////////////// Scan Duration ///////////////
  4056. ///////////////////////////////////////////////////////////////////////////////
  4057. // [[ScanDuration_t]]
  4058. typedef enum ScanDuration_t
  4059. {
  4060. SDUMD_SKIP_BLANKS = 0x01, // skip leading blanks
  4061. SDUMD_ALLOW_COLON = 0x02, // allow 'H:M' and 'H:M:S'
  4062. SDUMD_ALLOW_DIV = 0x04, // allow fraction 'n/d' as number
  4063. SDUMD_ALLOW_CAPITALS = 0x08, // allow upper case letters
  4064. SDUMD_ALLOW_LIST = 0x10, // allow lists like '9h12m'
  4065. SDUMD_ALLOW_SPACE_SEP = 0x20, // lists: allow spaces as list separator
  4066. SDUMD_ALLOW_PLUS_SEP = 0x40, // lists: allow '+' as list separator
  4067. SDUMD_ALLOW_MINUS_SEP = 0x80, // lists: allow '-' as list separator
  4068. SDUMD_M_DEFAULT = 0xf7,
  4069. SDUMD_M_ALL = 0xff,
  4070. }
  4071. ScanDuration_t;
  4072. //-----------------------------------------------------------------------------
  4073. char * ScanDuration
  4074. (
  4075. // Returns a pointer to the the first not used character.
  4076. // On error, it is 'source' and '*seconds' is set to 0.0.
  4077. double *seconds, // not NULL: store result (number of seconds)
  4078. ccp source, // source text
  4079. double default_factor, // default factor if no SI unit found
  4080. ScanDuration_t mode // flags
  4081. );
  4082. double GetDurationFactor ( char ch );
  4083. char * ScanSIFactor
  4084. (
  4085. // returns end of scanned string
  4086. double *num, // not NULL: store result
  4087. ccp source, // source text
  4088. double default_factor // return this if no factor found
  4089. );
  4090. //-----------------------------------------------------------------------------
  4091. // simple interfaces to ScanDuration(), SDUMD_M_DEFAULT is used as mode
  4092. double str2duration ( ccp src, char **endptr, double default_factor );
  4093. static inline u_sec_t str2sec ( ccp src, char **endptr )
  4094. { return double2sec(str2duration(src,endptr,1.0)); }
  4095. static inline u_msec_t str2msec ( ccp src, char **endptr )
  4096. { return double2msec(str2duration(src,endptr,1.0)); }
  4097. static inline u_usec_t str2usec ( ccp src, char **endptr )
  4098. { return double2usec(str2duration(src,endptr,1.0)); }
  4099. static inline u_nsec_t str2nsec ( ccp src, char **endptr )
  4100. { return double2nsec(str2duration(src,endptr,1.0)); }
  4101. static inline s_sec_t str2ssec ( ccp src, char **endptr )
  4102. { return double2ssec(str2duration(src,endptr,1.0)); }
  4103. static inline s_msec_t str2smsec ( ccp src, char **endptr )
  4104. { return double2smsec(str2duration(src,endptr,1.0)); }
  4105. static inline s_usec_t str2susec ( ccp src, char **endptr )
  4106. { return double2susec(str2duration(src,endptr,1.0)); }
  4107. static inline s_nsec_t str2snsec ( ccp src, char **endptr )
  4108. { return double2snsec(str2duration(src,endptr,1.0)); }
  4109. //
  4110. ///////////////////////////////////////////////////////////////////////////////
  4111. /////////////// Signals & Sleep ///////////////
  4112. ///////////////////////////////////////////////////////////////////////////////
  4113. extern volatile int SIGINT_level;
  4114. extern volatile int SIGHUP_level;
  4115. extern volatile int SIGALRM_level;
  4116. extern volatile int SIGCHLD_level;
  4117. extern volatile int SIGPIPE_level;
  4118. extern volatile int SIGUSR1_level;
  4119. extern volatile int SIGUSR2_level;
  4120. // no timout for SIGPIPE
  4121. extern u_sec_t SIGINT_sec;
  4122. extern u_sec_t SIGHUP_sec;
  4123. extern u_sec_t SIGALRM_sec;
  4124. extern u_sec_t SIGCHLD_sec;
  4125. extern u_sec_t SIGUSR1_sec;
  4126. extern u_sec_t SIGUSR2_sec;
  4127. extern int SIGINT_level_max;
  4128. extern bool ignore_SIGINT;
  4129. extern bool ignore_SIGHUP;
  4130. extern int redirect_signal_pid;
  4131. extern LogFile_t log_signal_file;
  4132. extern volatile int SIGINT_level;
  4133. extern volatile int SIGHUP_level;
  4134. extern volatile int SIGALRM_level;
  4135. extern volatile int SIGPIPE_level;
  4136. extern int SIGINT_level_max;
  4137. extern bool ignore_SIGINT;
  4138. extern bool ignore_SIGHUP;
  4139. void SetupSignalHandler ( int max_sigint_level, FILE *log_file );
  4140. //-----------------------------------------------------------------------------
  4141. int SleepNSec ( s_nsec_t nsec );
  4142. static inline int SleepUSec ( s_usec_t usec )
  4143. { return SleepNSec( usec * NSEC_PER_USEC ); }
  4144. static inline int SleepMSec ( s_msec_t msec )
  4145. { return SleepNSec( msec * NSEC_PER_MSEC ); }
  4146. static inline int SleepSec ( s_sec_t sec )
  4147. { return SleepNSec( sec * NSEC_PER_SEC ); }
  4148. //
  4149. ///////////////////////////////////////////////////////////////////////////////
  4150. /////////////// scan date & time ///////////////
  4151. ///////////////////////////////////////////////////////////////////////////////
  4152. // ScanInterval*() is old ==> try ScanDuration()
  4153. //-----------------------------------------------------------------------------
  4154. // new interface : all functions return first not scanned char
  4155. char * ScanIntervalTS
  4156. (
  4157. struct timespec *res_ts, // not NULL: store result here
  4158. ccp source // source text
  4159. );
  4160. char * ScanIntervalUSec
  4161. (
  4162. u_usec_t *res_usec, // not NULL: store total microseconds
  4163. ccp source // source text
  4164. );
  4165. char * ScanIntervalNSec
  4166. (
  4167. u_nsec_t *res_nsec, // not NULL: store total nanoseconds
  4168. ccp source // source text
  4169. );
  4170. //-----------------------------------------------------------------------------
  4171. // legacy interface : all functions return first not scanned char
  4172. char * ScanInterval
  4173. (
  4174. time_t *res_time, // not NULL: store seconds
  4175. u32 *res_usec, // not NULL: store microseconds of second
  4176. ccp source // source text
  4177. );
  4178. char * ScanInterval64
  4179. (
  4180. u64 *res_usec, // not NULL: store total microseconds
  4181. ccp source // source text
  4182. );
  4183. ///////////////////////////////////////////////////////////////////////////////
  4184. char * ScanDateTime
  4185. (
  4186. time_t *res_time, // not NULL: store seconds
  4187. u32 *res_usec, // not NULL: store microseconds of second
  4188. ccp source, // source text
  4189. bool allow_delta // true: allow +|- interval
  4190. );
  4191. ///////////////////////////////////////////////////////////////////////////////
  4192. char * ScanDateTime64
  4193. (
  4194. u64 *res_usec, // not NULL: store total microseconds
  4195. ccp source, // source text
  4196. bool allow_delta // true: allow +|- interval
  4197. );
  4198. //
  4199. ///////////////////////////////////////////////////////////////////////////////
  4200. /////////////// Since 2001 ///////////////
  4201. ///////////////////////////////////////////////////////////////////////////////
  4202. // Values for day and week are exact.
  4203. // Values for month, quarter and year are based on 365.2425 days/year.
  4204. //-----------------------------------------------------------------------
  4205. // name full/13 short/11 alt/10 tiny/8
  4206. //-----------------------------------------------------------------------
  4207. // hour YYYY-MM-DD HH YY-MM-DD HH DD. HH:xx MM-DD HH
  4208. // day YYYY-MM-DD << << YY-MM-DD
  4209. // week YYYYwWW << << <<
  4210. // month YYYY-MM << << <<
  4211. // quarter YYYYqQ << << <<
  4212. // year YYYY << << <<
  4213. //-----------------------------------------------------------------------
  4214. enum
  4215. {
  4216. S2001_FW_FULL = 13, ///< Standard-Text mit vollem Jahr (maximal 13 Zeichen).
  4217. S2001_FW_SHORT = 11, ///< Verkürzte Stundenangabe (maximal 11 Zeichen).
  4218. S2001_FW_ALT = 10, ///< Alternative Stundenangabe mit »:xx« (maximal 10 Zeichen).
  4219. S2001_FW_TINY = 8, ///< Verkürzte Stunden- und Wochenangabe (maximal 8 Zeichen).
  4220. S2001_DUR_HOUR = 3600, ///< Dauer einer Stunde in Sekunden.
  4221. S2001_DUR_DAY = 86400, ///< Dauer eines Tages in Sekunden.
  4222. S2001_DUR_WEEK = 604800, ///< Dauer einer Woche in Sekunden.
  4223. S2001_DUR_MONTH = 2629746, ///< Dauer eines Monats in Sekunden (365.2425/12 Tage).
  4224. S2001_DUR_QUARTER = 7889238, ///< Dauer eines Quartals in Sekunden (365.2425/4 Tage).
  4225. S2001_DUR_YEAR = 31556952, ///< Dauer eines Jahres in Sekunden (365.2425 Tage).
  4226. };
  4227. ///////////////////////////////////////////////////////////////////////////
  4228. // hour support
  4229. static inline int time2hour ( s64 time )
  4230. { return time / 3600 - 271752; }
  4231. static inline double time2hourF ( s64 time )
  4232. { return time / 3600.0 - 271752; }
  4233. static inline s64 hour2time ( int hour )
  4234. { return ( hour + 271752 ) * 3600; }
  4235. static inline int hour2duration ( int hour )
  4236. { return S2001_DUR_HOUR; }
  4237. ccp hour2text
  4238. (
  4239. int hour, // hour to print
  4240. int fw, // wanted field width assuming separators are 1 char
  4241. ccp sep_date, // NULL or separator within date
  4242. // if NULL: use '-'
  4243. ccp sep_dt // NULL or separator of between date and time
  4244. // if NULL: use ' '
  4245. );
  4246. ///////////////////////////////////////////////////////////////////////////
  4247. // day support
  4248. static inline int time2day ( s64 time )
  4249. { return time / 86400 - 11323; }
  4250. static inline double time2dayF ( s64 time )
  4251. { return time / 86400.0 - 11323; }
  4252. static inline s64 day2time ( int day )
  4253. { return ( day + 11323 ) * 86400; }
  4254. static inline int day2duration ( int day )
  4255. { return S2001_DUR_DAY; }
  4256. ccp day2text
  4257. (
  4258. int day, // day to print
  4259. int fw, // wanted field width assuming separators are 1 char
  4260. ccp sep_date, // NULL or separator within date
  4261. // if NULL: use '-'
  4262. ccp sep_dt // ignored
  4263. );
  4264. ///////////////////////////////////////////////////////////////////////////
  4265. // week support
  4266. static inline int time2week ( s64 time )
  4267. { return ( time - 978307200 ) / 604800; }
  4268. static inline double time2weekF ( s64 time )
  4269. { return ( time - 978307200 ) / 604800.0; }
  4270. static inline s64 week2time ( int week )
  4271. { return week * 604800 + 978307200; }
  4272. static inline int week2duration ( int week )
  4273. { return S2001_DUR_WEEK; }
  4274. ccp week2text
  4275. (
  4276. int week, // week to print
  4277. int fw, // wanted field width assuming separators are 1 char
  4278. ccp sep_date, // NULL or separator within date
  4279. // if NULL: use 'w'
  4280. ccp sep_dt // ignored
  4281. );
  4282. ///////////////////////////////////////////////////////////////////////////
  4283. // month support
  4284. int time2month ( time_t tim );
  4285. time_t month2time ( int month );
  4286. static inline int month2duration ( int month )
  4287. { return month2time(month+1) - month2time(month); }
  4288. ccp month2text
  4289. (
  4290. int month, // month to print
  4291. int fw, // wanted field width assuming separators are 1 char
  4292. ccp sep_date, // NULL or separator within date
  4293. // if NULL: use '-'
  4294. ccp sep_dt // ignored
  4295. );
  4296. ///////////////////////////////////////////////////////////////////////////
  4297. // quarter support
  4298. int time2quarter ( time_t tim );
  4299. time_t quarter2time ( int quarter );
  4300. static inline int quarter2duration ( int quarter )
  4301. { return quarter2time(quarter+1) - quarter2time(quarter); }
  4302. ccp quarter2text
  4303. (
  4304. int quarter, // quarter to print
  4305. int fw, // wanted field width assuming separators are 1 char
  4306. ccp sep_date, // NULL or separator within date
  4307. // if NULL: use 'q'
  4308. ccp sep_dt // ignored
  4309. );
  4310. ///////////////////////////////////////////////////////////////////////////
  4311. // year support
  4312. int time2year ( time_t tim );
  4313. time_t year2time ( int year );
  4314. static inline int year2duration ( int year )
  4315. { return year2time(year+1) - year2time(year); }
  4316. static inline ccp year2text
  4317. (
  4318. int year, // year to print
  4319. int fw, // wanted field width assuming separators are 1 char
  4320. ccp sep_date, // ignored
  4321. ccp sep_dt // ignored
  4322. )
  4323. {
  4324. return PrintCircBuf("%04d",year);
  4325. }
  4326. //
  4327. ///////////////////////////////////////////////////////////////////////////////
  4328. /////////////// usage counter ///////////////
  4329. ///////////////////////////////////////////////////////////////////////////////
  4330. #if IS_DEVELOP
  4331. #define TEST_USAGE_COUNT 0
  4332. #define USAGE_COUNT_ENABLED 0
  4333. #else
  4334. #define TEST_USAGE_COUNT 0
  4335. #define USAGE_COUNT_ENABLED 0
  4336. #endif
  4337. #if TEST_USAGE_COUNT
  4338. #define USAGE_COUNT_ENTRIES 11 // number of entries
  4339. #else
  4340. #define USAGE_COUNT_ENTRIES 30 // number of entries
  4341. #endif
  4342. #define USAGE_COUNT_FIRST_ADD 8 // first entry where values wil be added
  4343. #define USAGE_COUNT_NEXT_MIN(v) (15*(v)/8)
  4344. //-----------------------------------------------------------------------------
  4345. // [[UsageParam_t]]
  4346. typedef struct UsageParam_t
  4347. {
  4348. uint used; // number of used entries
  4349. bool enabled; // TRUE: statistics are enabled
  4350. bool is_active; // TRUE: counter is active (set by framework)
  4351. //--- not saved/restored
  4352. bool dirty; // TRUE: record needs an update @ 'update_nsec'
  4353. u_nsec_t update_nsec; // next update, based on GetTimerNSec()
  4354. u_nsec_t force_update_nsec; // force next update, based on GetTimerNSec()
  4355. }
  4356. UsageParam_t;
  4357. //-----------------------------------------------------------------------------
  4358. // [[UsageCountEntry_t]]
  4359. typedef struct UsageCountEntry_t
  4360. {
  4361. u64 count; // counter
  4362. u_nsec_t elapsed_nsec; // elapsed time, by GetTimerNSec()
  4363. u_sec_t time_sec; // time of record, by GetTimeSec(false)
  4364. float top1s; // = 100.0*(utime+stime)/elapsed for 1s
  4365. float top5s; // = 100.0*(utime+stime)/elapsed for 5s
  4366. }
  4367. __attribute__ ((packed)) UsageCountEntry_t;
  4368. //-----------------------------------------------------------------------------
  4369. // [[UsageCount_t]]
  4370. typedef struct UsageCount_t
  4371. {
  4372. UsageParam_t par; // base parameters
  4373. UsageCountEntry_t ref; // reference with absolute values
  4374. #if TEST_USAGE_COUNT
  4375. UsageCountEntry_t entry[USAGE_COUNT_ENTRIES+1]; // list of entries with delta values
  4376. #else
  4377. UsageCountEntry_t entry[USAGE_COUNT_ENTRIES]; // list of entries with delta values
  4378. #endif
  4379. }
  4380. UsageCount_t;
  4381. //-----------------------------------------------------------------------------
  4382. extern int usage_count_enabled;
  4383. void EnableUsageCount(void);
  4384. static inline void DisableUsageCount(void) { usage_count_enabled--; }
  4385. //-----------------------------------------------------------------------------
  4386. // n_rec<0: clear from end, n_rec>=0: clear from index
  4387. void ClearUsageCount ( UsageCount_t *uc, int count );
  4388. // NOW_NSEC: 0 or GetTimerNSec(), but not GetTime*()
  4389. void UpdateUsageCount ( UsageCount_t *uc, u_nsec_t now_nsec );
  4390. void UpdateUsageCountIncrement ( UsageCount_t *uc );
  4391. void UpdateUsageCountAdd ( UsageCount_t *uc, int add );
  4392. static inline void UsageCountIncrement ( UsageCount_t *uc )
  4393. { UpdateUsageCountAdd(uc,1); }
  4394. // stat about last 'nsec' nanoseconds
  4395. UsageCountEntry_t GetUsageCount ( const UsageCount_t *uc, s_nsec_t nsec );
  4396. void AddUsageCountEntry ( UsageCountEntry_t *dest, const UsageCountEntry_t *add );
  4397. //
  4398. ///////////////////////////////////////////////////////////////////////////////
  4399. /////////////// wait counter ///////////////
  4400. ///////////////////////////////////////////////////////////////////////////////
  4401. // [[UsageDurationEntry_t]]
  4402. typedef struct UsageDurationEntry_t
  4403. {
  4404. u_nsec_t elapsed_nsec; // elapsed time, by GetTimerNSec()
  4405. u_nsec_t total_nsec; // total waiting time
  4406. u_nsec_t top_nsec; // top waiting time
  4407. u64 count; // number of events
  4408. u_sec_t time_sec; // time of record, by GetTimeSec(false)
  4409. float top_cnt_1s; // top number of counts in 1 sec
  4410. float top_cnt_5s; // top number of counts in 5 sec
  4411. }
  4412. __attribute__ ((packed)) UsageDurationEntry_t;
  4413. //-----------------------------------------------------------------------------
  4414. // [[UsageDuration_t]]
  4415. typedef struct UsageDuration_t
  4416. {
  4417. UsageParam_t par; // base parameters
  4418. UsageDurationEntry_t ref; // reference with absolute values
  4419. #if TEST_USAGE_COUNT
  4420. UsageDurationEntry_t entry[USAGE_COUNT_ENTRIES+1]; // list of entries with delta values
  4421. #else
  4422. UsageDurationEntry_t entry[USAGE_COUNT_ENTRIES]; // list of entries with delta values
  4423. #endif
  4424. }
  4425. UsageDuration_t;
  4426. //-----------------------------------------------------------------------------
  4427. // n_rec<0: clear from end, n_rec>=0: clear from index
  4428. void ClearUsageDuration ( UsageDuration_t *ud, int count );
  4429. // NOW_NSEC: 0 or GetTimerNSec(), but not GetTime*()
  4430. void UpdateUsageDuration ( UsageDuration_t *ud, u_nsec_t now_nsec );
  4431. void UpdateUsageDurationAdd ( UsageDuration_t *ud, int add, u_nsec_t wait_nsec, u_nsec_t top_nsec );
  4432. void UpdateUsageDurationIncrement ( UsageDuration_t *ud, u_nsec_t wait_nsec );
  4433. void UsageDurationIncrement ( UsageDuration_t *ud, u_nsec_t wait_nsec );
  4434. // stat about last 'nsec' nanoseconds
  4435. UsageDurationEntry_t GetUsageDuration ( const UsageDuration_t *ud, s_nsec_t nsec );
  4436. void AddUsageDurationEntry ( UsageDurationEntry_t *dest, const UsageDurationEntry_t *add );
  4437. //
  4438. ///////////////////////////////////////////////////////////////////////////////
  4439. /////////////// usage counter mgr ///////////////
  4440. ///////////////////////////////////////////////////////////////////////////////
  4441. // [[ListUsageFunc]]
  4442. typedef struct UsageCtrl_t UsageCtrl_t;
  4443. enum
  4444. {
  4445. LUC_PM_STANDARD, // standard view
  4446. LUC_PM_RAW, // raw values, not supported by ListUsageCount()
  4447. LUC_PM_SUMMARY, // summary
  4448. LUC_PM__USER // base value for user defined modes
  4449. };
  4450. typedef void (*ListUsageFunc)
  4451. (
  4452. PrintMode_t *pm, // valid print mode
  4453. const UsageCtrl_t *uci, // valid object to list
  4454. int print_mode, // see LUC_PM_*
  4455. s_nsec_t limit_nsec // >0: limit output until # is reached
  4456. );
  4457. //-----------------------------------------------------------------------------
  4458. typedef void (*UpdateUsageFunc)
  4459. (
  4460. const UsageCtrl_t *uci, // valid object to update
  4461. u_nsec_t now_usec // NULL or current time by GetTimerNSec()
  4462. );
  4463. //-----------------------------------------------------------------------------
  4464. // [[UsageCtrl_t]]
  4465. typedef struct UsageCtrl_t
  4466. {
  4467. UsageParam_t *par; // higher prioritiy than uc->par and ud->par
  4468. UsageCount_t *uc; // not NULL for usage counters
  4469. UsageDuration_t *ud; // not NULL for wait counters
  4470. UpdateUsageFunc update_func; // not NULL: Call this function to update
  4471. ListUsageFunc list_func; // not NULL: Call this function to list
  4472. ccp title; // NULL or title
  4473. ccp key1; // first key, upper case
  4474. ccp key2; // NULL or second key, upper case
  4475. ccp srt_load; // NULL or prefix vor SRT reading to allow prefix changes
  4476. ccp srt_prefix; // NULL prefix or SRT reading + writing
  4477. // If NULL: don't save/restore
  4478. // 'srt_load' is scanned before 'srt_prefix'
  4479. float *color_val; // 6 values for mark,info,gint,warn,err,bad
  4480. // if NULL then use system list
  4481. u_nsec_t *color_dur; // 6 values for mark,info,gint,warn,err,bad
  4482. // if NULL then use system list
  4483. }
  4484. UsageCtrl_t;
  4485. //-----------------------------------------------------------------------------
  4486. extern PointerList_t usage_count_mgr;
  4487. // NOW_NSEC: 0 or GetTimerNSec(), but not GetTime*()
  4488. u_nsec_t MaintainUsageByMgr ( u_nsec_t now_nsec );
  4489. void UpdateByUCI ( const UsageCtrl_t *uci, u_nsec_t now_nsec );
  4490. void UpdateUsageByMgr ( u_nsec_t now_nsec );
  4491. void AddToUsageMgr ( const UsageCtrl_t *uci );
  4492. void ListUsageCount
  4493. (
  4494. PrintMode_t *p_pm, // NULL or print mode
  4495. const UsageCtrl_t *uci, // NULL or object to list
  4496. int print_mode, // see LUC_PM_*
  4497. s_nsec_t limit_nsec // >0: limit output until # is reached
  4498. );
  4499. void ListUsageDuration
  4500. (
  4501. PrintMode_t *p_pm, // NULL or print mode
  4502. const UsageCtrl_t *uci, // NULL or object to list
  4503. int print_mode, // see LUC_PM_*
  4504. s_nsec_t limit_nsec // >0: limit output until # is reached
  4505. );
  4506. static inline UsageParam_t * GetUsageParam ( const UsageCtrl_t *uci )
  4507. { DASSERT(uci); return uci->par ? uci->par : uci->uc ? &uci->uc->par : uci->ud ? &uci->ud->par : 0; }
  4508. static inline char GetUsageTypeChar ( const UsageCtrl_t *uci )
  4509. { return !uci ? '-' : uci->uc ? 'C' : uci->ud ? 'D' : uci->par ? 'x' : '?'; }
  4510. void SaveCurrentStateByUsageCountMgr ( FILE *f, uint fw_name );
  4511. void RestoreStateByUsageCountMgr ( RestoreState_t *rs );
  4512. ///////////////////////////////////////////////////////////////////////////////
  4513. // [[IntervalInfo_t]]
  4514. typedef struct IntervalInfo_t
  4515. {
  4516. u_nsec_t nsec;
  4517. u_usec_t usec;
  4518. ccp name;
  4519. }
  4520. IntervalInfo_t;
  4521. extern const IntervalInfo_t interval_info[];
  4522. //
  4523. ///////////////////////////////////////////////////////////////////////////////
  4524. /////////////// cpu usage ///////////////
  4525. ///////////////////////////////////////////////////////////////////////////////
  4526. #if TEST_USAGE_COUNT
  4527. #define CPU_USAGE_ENTRIES 11 // number of entries
  4528. #else
  4529. #define CPU_USAGE_ENTRIES 30 // number of entries
  4530. #endif
  4531. #if IS_DEVELOP
  4532. #define CPU_USAGE_ENABLED 0 // initial value for cpu_usage.par.enabled
  4533. #else
  4534. #define CPU_USAGE_ENABLED 0 // initial value for cpu_usage.par.enabled
  4535. #endif
  4536. #define CPU_USAGE_FIRST_ADD 8 // first entry where values wil be added
  4537. #define CPU_USAGE_NEXT_MIN(v) (15*(v)/8)
  4538. //-----------------------------------------------------------------------------
  4539. // [[CpuUsageEntry_t]]
  4540. typedef struct CpuUsageEntry_t
  4541. {
  4542. u_usec_t elapsed_usec; // elapsed time, by GetTimerUSec()
  4543. u_usec_t utime_usec; // user CPU time used
  4544. u_usec_t stime_usec; // system CPU time used
  4545. u_sec_t time_sec; // time of record, by GetTimeUSec(false)
  4546. float top1s; // = 100.0*(utime+stime)/elapsed for 1s
  4547. float top5s; // = 100.0*(utime+stime)/elapsed for 5s
  4548. u32 n_wait; // number of waits (poll() or select())
  4549. float topw1s; // top number of waits in 1 sec
  4550. float topw5s; // top number of waits in 5 sec
  4551. }
  4552. __attribute__ ((packed)) CpuUsageEntry_t;
  4553. //-----------------------------------------------------------------------------
  4554. // [[CpuUsage_t]]
  4555. typedef struct CpuUsage_t
  4556. {
  4557. UsageParam_t par; // base parameters
  4558. CpuUsageEntry_t ref; // reference with absolute values
  4559. #if TEST_USAGE_COUNT
  4560. CpuUsageEntry_t entry[CPU_USAGE_ENTRIES+1]; // list of entries with delta values
  4561. #else
  4562. CpuUsageEntry_t entry[CPU_USAGE_ENTRIES]; // list of entries with delta values
  4563. #endif
  4564. }
  4565. CpuUsage_t;
  4566. //-----------------------------------------------------------------------------
  4567. extern CpuUsage_t cpu_usage;
  4568. extern const UsageCtrl_t cpu_usage_ctrl;
  4569. void UpdateCpuUsage(void);
  4570. void UpdateCpuUsageByUCI ( const UsageCtrl_t *, u_nsec_t ); // both params ignored
  4571. void UpdateCpuUsageIncrement(void);
  4572. void ListCpuUsage
  4573. (
  4574. PrintMode_t *p_pm, // NULL or print mode
  4575. const UsageCtrl_t *uci, // ignored!
  4576. int print_mode, // see LUC_PM_*
  4577. s_nsec_t limit_nsec // >0: limit output until # is reached
  4578. );
  4579. // stat about last 'usec' microseconds
  4580. CpuUsageEntry_t GetCpuUsage ( s_usec_t usec );
  4581. uint GetCpuUsagePercent ( s_usec_t usec );
  4582. void AddCpuEntry ( CpuUsageEntry_t *dest, const CpuUsageEntry_t *add );
  4583. static inline uint GetCpuEntryPercent ( const CpuUsageEntry_t *entry )
  4584. {
  4585. DASSERT(entry);
  4586. return entry->elapsed_usec
  4587. ? 100 * ( entry->utime_usec + entry->stime_usec + entry->elapsed_usec/200 )
  4588. / entry->elapsed_usec
  4589. : 0;
  4590. }
  4591. static inline double GetCpuEntryRatio ( const CpuUsageEntry_t *entry )
  4592. {
  4593. DASSERT(entry);
  4594. return entry->elapsed_usec
  4595. ? (double)(entry->utime_usec + entry->stime_usec ) / entry->elapsed_usec
  4596. : 0.0;
  4597. }
  4598. //-----------------------------------------------------------------------------
  4599. // get percent, returns previuis valus if delay is <10ms
  4600. double get_rusage_percent (void);
  4601. //
  4602. ///////////////////////////////////////////////////////////////////////////////
  4603. /////////////// sockaddr support ///////////////
  4604. ///////////////////////////////////////////////////////////////////////////////
  4605. // [[sockaddr_in46_t]]
  4606. typedef struct sockaddr_in46_t
  4607. {
  4608. union
  4609. {
  4610. sa_family_t family; // is first member of each sockaddr_* structure
  4611. sockaddr_in4_t in4;
  4612. sockaddr_in6_t in6;
  4613. };
  4614. }
  4615. sockaddr_in46_t;
  4616. //-----------------------------------------------------------------------------
  4617. // [[sockaddr_dclib_t]]
  4618. typedef struct sockaddr_dclib_t
  4619. {
  4620. union
  4621. {
  4622. sa_family_t family; // is first member of each sockaddr_* structure
  4623. sockaddr_in4_t in4;
  4624. sockaddr_in6_t in6;
  4625. sockaddr_un_t un;
  4626. };
  4627. }
  4628. sockaddr_dclib_t;
  4629. //-----------------------------------------------------------------------------
  4630. // [[sockaddr_info_t]]
  4631. typedef struct sockaddr_info_t
  4632. {
  4633. sockaddr_t *sa; // pointer to sockaddr or sockaddr_*
  4634. uint size; // size of '*sa'
  4635. }
  4636. sockaddr_info_t;
  4637. ///////////////////////////////////////////////////////////////////////////////
  4638. // [[doxygen]]
  4639. static inline sockaddr_info_t CreateSockaddrInfo ( cvp sa, uint size )
  4640. {
  4641. sockaddr_info_t i =
  4642. {
  4643. .sa = (sockaddr_t*)sa,
  4644. .size = size
  4645. };
  4646. return i;
  4647. }
  4648. //-----------------------------------------------------------------------------
  4649. // [[doxygen]]
  4650. static inline void SetupSockaddrInfo ( sockaddr_info_t *sai, cvp sa, uint size )
  4651. {
  4652. DASSERT(sai);
  4653. sai->sa = (sockaddr_t*)sa;
  4654. sai->size = size ? size : sizeof(sockaddr_in_t);
  4655. }
  4656. //
  4657. ///////////////////////////////////////////////////////////////////////////////
  4658. /////////////// ScanIP4 ///////////////
  4659. ///////////////////////////////////////////////////////////////////////////////
  4660. // [[ipv4_class_t]]
  4661. typedef enum ipv4_class_t
  4662. {
  4663. CIP4_ERROR = -1, // error
  4664. CIP4_INVALID = 0, // not an IPv4
  4665. CIP4_NUMERIC, // 32 bit number only
  4666. CIP4_ABBREV, // abbreviated IPv4 (trailing point)
  4667. CIP4_CLASS_A, // IPv4 in class-A notation
  4668. CIP4_CLASS_B, // IPv4 in class-B notation
  4669. CIP4_CLASS_C, // IPv4 in class-C notation
  4670. }
  4671. ipv4_class_t;
  4672. //-----------------------------------------------------------------------------
  4673. ipv4_class_t ScanIP4
  4674. (
  4675. ipv4_t *ret_ip4, // not NULL: return numeric IPv4 here
  4676. ccp addr, // address to analyze
  4677. int addr_len // length of addr; if <0: use strlen(addr)
  4678. );
  4679. //-----------------------------------------------------------------------------
  4680. char * NormalizeIP4
  4681. (
  4682. // Return a pointer to dest if valid IPv4,
  4683. // Otherwise return 0 and buf is not modifieid.
  4684. char *buf, // result buffer, can be 'addr'
  4685. // if NULL: use a local circulary static buffer
  4686. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4687. bool c_notation, // TRUE: force lass-C notation (a.b.c.d)
  4688. ccp addr, // address to analyze
  4689. int addr_len // length of addr; if <0: use strlen(addr)
  4690. );
  4691. //-----------------------------------------------------------------------------
  4692. static inline ipv4_class_t CheckIP4
  4693. (
  4694. ccp addr, // address to analyze
  4695. int addr_len // length of addr; if <0: use strlen(addr)
  4696. )
  4697. {
  4698. return ScanIP4(0,addr,addr_len);
  4699. }
  4700. //-----------------------------------------------------------------------------
  4701. int dclib_aton ( ccp addr, struct in_addr *inp );
  4702. //
  4703. ///////////////////////////////////////////////////////////////////////////////
  4704. /////////////// PrintIP4*() ///////////////
  4705. ///////////////////////////////////////////////////////////////////////////////
  4706. #define FW_IPV4_N 10 // 4294967295
  4707. #define FW_IPV4_A 12 // 255.16777215
  4708. #define FW_IPV4_B 13 // 255.255.65535
  4709. #define FW_IPV4_C 15 // 255.255.255.255
  4710. #define FW_IPV4_PORT 5 // 65535
  4711. #define FW_IPV4_N_PORT (FW_IPV4_N+1+FW_IPV4_PORT)
  4712. #define FW_IPV4_A_PORT (FW_IPV4_A+1+FW_IPV4_PORT)
  4713. #define FW_IPV4_B_PORT (FW_IPV4_B+1+FW_IPV4_PORT)
  4714. #define FW_IPV4_C_PORT (FW_IPV4_C+1+FW_IPV4_PORT)
  4715. //-----------------------------------------------------------------------------
  4716. char * PrintIP4N
  4717. (
  4718. // print as unsigned number (CIP4_NUMERIC)
  4719. char *buf, // result buffer
  4720. // NULL: use a local circulary static buffer
  4721. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4722. u32 ip4, // IP4 to print
  4723. s32 port // 0..0xffff: add ':port'
  4724. );
  4725. char * PrintIP4A
  4726. (
  4727. // print in A-notation (CIP4_CLASS_A)
  4728. char *buf, // result buffer
  4729. // NULL: use a local circulary static buffer
  4730. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4731. u32 ip4, // IP4 to print
  4732. s32 port // 0..0xffff: add ':port'
  4733. );
  4734. char * PrintIP4B
  4735. (
  4736. // print in B-notation (CIP4_CLASS_B)
  4737. char *buf, // result buffer
  4738. // NULL: use a local circulary static buffer
  4739. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4740. u32 ip4, // IP4 to print
  4741. s32 port // 0..0xffff: add ':port'
  4742. );
  4743. //-----------------------------------------------------------------------------
  4744. // print in C-notation (usual notation)
  4745. char * PrintIP4
  4746. (
  4747. char *buf, // result buffer
  4748. // NULL: use a local circulary static buffer
  4749. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4750. u32 ip4, // IP4 to print
  4751. s32 port // 0..0xffff: add ':port'
  4752. );
  4753. char * PrintLeftIP4
  4754. (
  4755. char *buf, // result buffer
  4756. // NULL: use a local circulary static buffer
  4757. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4758. u32 ip4, // IP4 to print
  4759. s32 port // 0..0xffff: add ':port'
  4760. );
  4761. char * PrintRightIP4
  4762. (
  4763. char *buf, // result buffer
  4764. // NULL: use a local circulary static buffer
  4765. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4766. u32 ip4, // IP4 to print
  4767. s32 port, // 0..0xffff: add ':port'
  4768. uint port_mode // 0: 'ip:port', 1: 'ip :port', 2: 'ip : port'
  4769. );
  4770. char * PrintAlignedIP4
  4771. (
  4772. char *buf, // result buffer
  4773. // NULL: use a local circulary static buffer
  4774. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4775. u32 ip4, // IP4 to print
  4776. s32 port // 0..0xffff: add ':port'
  4777. );
  4778. //-----------------------------------------------------------------------------
  4779. // print by enum ipv4_class_t
  4780. char * PrintIP4ByMode
  4781. (
  4782. char *buf, // result buffer
  4783. // NULL: use a local circulary static buffer
  4784. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4785. u32 ip4, // IP4 to print
  4786. ipv4_class_t mode, // CIP4_NUMERIC | CIP4_CLASS_A | CIP4_CLASS_B:
  4787. // force numeric or class-A/B output; otherwise class-C output
  4788. s32 port // 0..0xffff: add ':port'
  4789. );
  4790. //-----------------------------------------------------------------------------
  4791. struct sockaddr_in;
  4792. static inline char * PrintIP4sa
  4793. (
  4794. char *buf, // result buffer
  4795. // NULL: use a local circulary static buffer
  4796. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4797. const struct sockaddr_in *sa // socket address
  4798. )
  4799. {
  4800. return sa
  4801. ? PrintIP4(buf,buf_size,
  4802. ntohl(sa->sin_addr.s_addr), ntohs(sa->sin_port) )
  4803. : "-";
  4804. }
  4805. static inline char * PrintRightIP4sa
  4806. (
  4807. char *buf, // result buffer
  4808. // NULL: use a local circulary static buffer
  4809. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4810. struct sockaddr_in *sa // socket address
  4811. )
  4812. {
  4813. DASSERT(sa);
  4814. return PrintRightIP4(buf,buf_size,
  4815. ntohl(sa->sin_addr.s_addr), ntohs(sa->sin_port), 0 );
  4816. }
  4817. static inline char * PrintAlignedIP4sa
  4818. (
  4819. char *buf, // result buffer
  4820. // NULL: use a local circulary static buffer
  4821. size_t buf_size, // size of 'buf', ignored if buf==NULL
  4822. struct sockaddr_in *sa // socket address
  4823. )
  4824. {
  4825. DASSERT(sa);
  4826. return PrintAlignedIP4(buf,buf_size,
  4827. ntohl(sa->sin_addr.s_addr), ntohs(sa->sin_port) );
  4828. }
  4829. //
  4830. ///////////////////////////////////////////////////////////////////////////////
  4831. /////////////// dynamic data support ///////////////
  4832. ///////////////////////////////////////////////////////////////////////////////
  4833. // [[DynData_t]]
  4834. typedef struct DynData_t
  4835. {
  4836. u8 *data; // pointer to data, alloced
  4837. uint len; // length of used data
  4838. uint size; // size of allocated data
  4839. }
  4840. DynData_t;
  4841. //-----------------------------------------------------------------------------
  4842. void ResetDD ( DynData_t *dd );
  4843. void InsertDD ( DynData_t *dd, const void *data, uint data_size );
  4844. ///////////////////////////////////////////////////////////////////////////////
  4845. // [[DynDataList_t]]
  4846. typedef struct DynDataList_t
  4847. {
  4848. DynData_t *list; // pointer to the data list
  4849. uint used; // number of used data elements
  4850. uint size; // number of allocated pointers in 'list'
  4851. }
  4852. DynDataList_t;
  4853. //-----------------------------------------------------------------------------
  4854. void ResetDDL ( DynDataList_t *ddl );
  4855. DynData_t *InsertDDL
  4856. (
  4857. DynDataList_t *ddl, // valid dynamic data list
  4858. uint index, // element index to change
  4859. const void *data, // NULL or data to assign
  4860. uint data_size // size of data
  4861. );
  4862. DynData_t *GetDDL
  4863. (
  4864. DynDataList_t *ddl, // valid dynamic data list
  4865. uint index, // element index to get
  4866. uint create // >0: create an empty element if not exist
  4867. // >index: create at least # elements
  4868. );
  4869. //
  4870. ///////////////////////////////////////////////////////////////////////////////
  4871. /////////////// struct StringField_t ///////////////
  4872. ///////////////////////////////////////////////////////////////////////////////
  4873. // [[StringField_t]]
  4874. typedef struct StringField_t
  4875. {
  4876. ccp * field; // pointer to the string field
  4877. uint used; // number of used titles in the title field
  4878. uint size; // number of allocated pointers in 'field'
  4879. int (*func_cmp)( ccp s1, ccp s2 ); // compare function, default is strcmp()
  4880. } StringField_t;
  4881. //-----------------------------------------------------------------------------
  4882. static inline void InitializeStringField ( StringField_t * sf )
  4883. { DASSERT(sf); memset(sf,0,sizeof(*sf)); }
  4884. void ResetStringField ( StringField_t * sf );
  4885. void MoveStringField ( StringField_t * dest, StringField_t * src );
  4886. int FindStringFieldIndex ( const StringField_t * sf, ccp key, int not_found_value );
  4887. ccp FindStringField ( const StringField_t * sf, ccp key );
  4888. // return: true if item inserted/deleted
  4889. bool InsertStringField ( StringField_t * sf, ccp key, bool move_key );
  4890. bool RemoveStringField ( StringField_t * sf, ccp key );
  4891. uint RemoveStringFieldByIndex ( StringField_t * sf, int index, int n );
  4892. // helper function
  4893. ccp * InsertStringFieldHelper ( StringField_t * sf, int idx );
  4894. // append at the end and do not sort
  4895. void AppendStringField ( StringField_t * sf, ccp key, bool move_key );
  4896. // append at the end if not already exists, do not sort
  4897. void AppendUniqueStringField ( StringField_t * sf, ccp key, bool move_key );
  4898. // insert or append a path (path1+path2) with optional wildcards by SearchPaths()
  4899. uint InsertStringFieldExpand ( StringField_t * sf, ccp path1, ccp path2, bool allow_hidden );
  4900. uint AppendStringFieldExpand ( StringField_t * sf, ccp path1, ccp path2, bool allow_hidden );
  4901. // re-sort field using sf->func_cmp()
  4902. void SortStringField ( StringField_t * sf );
  4903. // return the index of the (next) item
  4904. uint FindStringFieldHelper ( const StringField_t * sf, bool * found, ccp key );
  4905. // find first pattern that matches
  4906. ccp MatchStringField ( const StringField_t * sf, ccp key );
  4907. //-----------------------------------------------------------------------------
  4908. // file support
  4909. enumError LoadStringField
  4910. (
  4911. StringField_t * sf, // string field
  4912. bool init_sf, // true: initialize 'sf' first
  4913. bool sort, // true: sort 'sf'
  4914. ccp filename, // filename of source file
  4915. bool silent // true: don't print open/read errors
  4916. );
  4917. enumError SaveStringField
  4918. (
  4919. StringField_t * sf, // valid string field
  4920. ccp filename, // filename of dest file
  4921. bool rm_if_empty // true: rm dest file if 'sf' is empty
  4922. );
  4923. enumError WriteStringField
  4924. (
  4925. FILE * f, // open destination file
  4926. ccp filename, // NULL or filename (needed on write error)
  4927. StringField_t * sf, // valid string field
  4928. ccp prefix, // not NULL: insert prefix before each line
  4929. ccp eol // end of line text (if NULL: use LF)
  4930. );
  4931. //-----------------------------------------------------------------------------
  4932. // save-state support
  4933. void SaveCurrentStateStringField
  4934. (
  4935. FILE *f, // output file
  4936. ccp name_prefix, // NULL or prefix of name, up to 40 chars
  4937. uint tab_pos, // tab pos of '='
  4938. const StringField_t *sf, // valid string field
  4939. EncodeMode_t emode // encoding mode
  4940. );
  4941. struct RestoreState_t;
  4942. void RestoreStateStringField
  4943. (
  4944. struct RestoreState_t *rs, // info data, may be modified
  4945. ccp name_prefix, // NULL or prefix of name, up to 40 chars
  4946. StringField_t *sf, // string field
  4947. bool init_sf, // true: initialize 'sf', otherwise reset
  4948. EncodeMode_t emode // encoding mode
  4949. );
  4950. //
  4951. ///////////////////////////////////////////////////////////////////////////////
  4952. /////////////// struct ParamField_t ///////////////
  4953. ///////////////////////////////////////////////////////////////////////////////
  4954. // [[ParamFieldItem_t]]
  4955. typedef struct ParamFieldItem_t
  4956. {
  4957. ccp key; // string as main key
  4958. uint num; // user defined numeric parameter
  4959. void *data; // user defined pointer
  4960. } ParamFieldItem_t;
  4961. //-----------------------------------------------------------------------------
  4962. // [[ParamField_t]]
  4963. typedef struct ParamField_t
  4964. {
  4965. ParamFieldItem_t * field; // pointer to the string field
  4966. uint used; // number of used titles in the title field
  4967. uint size; // number of allocated pointers in 'field'
  4968. bool free_data; // true: unused data will be free'd
  4969. // initialized with 'false'
  4970. int (*func_cmp)( ccp s1, ccp s2 ); // compare function, default is strcmp()
  4971. } ParamField_t;
  4972. //-----------------------------------------------------------------------------
  4973. static inline void InitializeParamField ( ParamField_t * pf )
  4974. { DASSERT(pf); memset(pf,0,sizeof(*pf)); }
  4975. void ResetParamField ( ParamField_t * pf );
  4976. void MoveParamField ( ParamField_t * dest, ParamField_t * src );
  4977. int FindParamFieldIndex ( const ParamField_t * pf, ccp key, int not_found_value );
  4978. ParamFieldItem_t * FindParamField ( const ParamField_t * pf, ccp key );
  4979. ParamFieldItem_t * FindParamFieldByNum ( const ParamField_t * pf, uint num );
  4980. ParamFieldItem_t * FindInsertParamField
  4981. ( ParamField_t * pf, ccp key, bool move_key, uint num, bool *old_found );
  4982. ParamFieldItem_t * IncrementParamField ( ParamField_t * pf, ccp key, bool move_key );
  4983. // Insert: Insert only if not found, Replace: Insert or replace data
  4984. // return: true if item inserted/deleted
  4985. bool InsertParamField ( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
  4986. bool ReplaceParamField( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
  4987. bool RemoveParamField ( ParamField_t * pf, ccp key );
  4988. // append at the end and do not sort
  4989. ParamFieldItem_t * AppendParamField
  4990. ( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
  4991. // insert or append a path (path1+path2) with optional wildcards by SearchPaths()
  4992. uint InsertParamFieldExpand
  4993. ( ParamField_t * pf, ccp path1, ccp path2, bool allow_hidden, uint num, cvp data );
  4994. uint AppendParamFieldExpand
  4995. ( ParamField_t * pf, ccp path1, ccp path2, bool allow_hidden, uint num, cvp data );
  4996. // return the index of the (next) item
  4997. uint FindParamFieldHelper ( const ParamField_t * pf, bool * found, ccp key );
  4998. // find first pattern that matches
  4999. ParamFieldItem_t * MatchParamField ( const ParamField_t * pf, ccp key );
  5000. //-----------------------------------------------------------------------------
  5001. // get values and set marker by 'num |= mark'
  5002. ccp GetParamFieldStr ( ParamField_t *pf, uint mark, ccp key, ccp def );
  5003. int GetParamFieldInt ( ParamField_t *pf, uint mark, ccp key, int def );
  5004. int GetParamFieldIntMM ( ParamField_t *pf, uint mark, ccp key, int def, int min, int max );
  5005. //
  5006. ///////////////////////////////////////////////////////////////////////////////
  5007. /////////////// struct exmem_list_t ///////////////
  5008. ///////////////////////////////////////////////////////////////////////////////
  5009. // [[exmem_key_t]]
  5010. typedef struct exmem_key_t
  5011. {
  5012. ccp key; // string as main key => data.is_key_alloced
  5013. exmem_t data; // data
  5014. }
  5015. exmem_key_t;
  5016. //-----------------------------------------------------------------------------
  5017. // [[exmem_list_t]]
  5018. typedef struct exmem_list_t
  5019. {
  5020. exmem_key_t *list; // data list
  5021. uint used; // number of used titles in the title field
  5022. uint size; // number of allocated pointers in 'field'
  5023. bool is_unsorted; // true: list is not sorted (Append() was used)
  5024. int (*func_cmp)( ccp s1, ccp s2 ); // compare function, default is strcmp()
  5025. }
  5026. exmem_list_t;
  5027. //-----------------------------------------------------------------------------
  5028. static inline void InitializeEML ( exmem_list_t * eml )
  5029. { DASSERT(eml); memset(eml,0,sizeof(*eml)); }
  5030. void ResetEML ( exmem_list_t * eml );
  5031. void MoveEML ( exmem_list_t * dest, exmem_list_t * src );
  5032. // return the index of the (next) item
  5033. uint FindHelperEML ( const exmem_list_t * eml, ccp key, bool *found );
  5034. int FindIndexEML ( const exmem_list_t * eml, ccp key, int not_found_value );
  5035. exmem_key_t * FindEML ( const exmem_list_t * eml, ccp key );
  5036. exmem_key_t * FindAttribEML ( const exmem_list_t * eml, u32 attrib );
  5037. exmem_key_t * FindInsertEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key, bool *old_found );
  5038. // Insert if not found, ignore othwerwise. Return true if item inserted
  5039. bool InsertEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
  5040. const exmem_t *data, CopyMode_t cm_data );
  5041. // Insert or replace content. Return true if item inserted
  5042. bool ReplaceEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
  5043. const exmem_t *data, CopyMode_t cm_data );
  5044. // Replace content if found. Return true if item found
  5045. bool OverwriteEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
  5046. const exmem_t *data, CopyMode_t cm_data );
  5047. // Append at the end and do not sort
  5048. exmem_key_t * AppendEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
  5049. const exmem_t *data, CopyMode_t cm_data );
  5050. // Return true if item found and removed
  5051. bool RemoveByIndexEML ( exmem_list_t * eml, int index );
  5052. bool RemoveByKeyEML ( exmem_list_t * eml, ccp key );
  5053. // find first pattern that matches
  5054. exmem_key_t * MatchEML ( const exmem_list_t * eml, ccp key );
  5055. void DumpEML ( FILE *f, int indent, const exmem_list_t * eml, ccp info );
  5056. //-----------------------------------------------------------------------------
  5057. exmem_t ResolveSymbolsEML ( const exmem_list_t * eml, ccp source );
  5058. uint ResolveAllSymbolsEML ( exmem_list_t * eml );
  5059. // add symbols 'home', 'etc', 'install' = 'prog' and 'cwd'
  5060. void AddStandardSymbolsEML ( exmem_list_t * eml, bool overwrite );
  5061. //
  5062. ///////////////////////////////////////////////////////////////////////////////
  5063. /////////////// MultiColumn ///////////////
  5064. ///////////////////////////////////////////////////////////////////////////////
  5065. // [[MultiColumn_t]]
  5066. typedef struct MultiColumn_t
  5067. {
  5068. FILE *f; // NULL or output file
  5069. const ColorSet_t
  5070. *colset; // NULL or color set for the frame
  5071. ccp prefix; // NULL or line prefix
  5072. int indent; // indention after prefix
  5073. ccp sep; // NULL or separator for frame_mode 0 and 1
  5074. ccp eol; // NULL or end-of-line string
  5075. int fw; // max field width
  5076. int min_rows; // minimal number of rows before MC
  5077. int max_cols; // >0: maximal number columns
  5078. int frame_mode; // 0:ASCII, 1:single line, 2:double line
  5079. bool print_header; // TRUE: print column header
  5080. bool print_footer; // TRUE: print footer line
  5081. ccp head_key; // NULL or name of key column, default="Name"
  5082. ccp head_val; // NULL or name of value column, default="Value"
  5083. int debug; // >0: print basic debug info
  5084. // >1: be verbose
  5085. exmem_list_t list; // list of parameters to print
  5086. }
  5087. MultiColumn_t;
  5088. //-----------------------------------------------------------------------------
  5089. void ResetMultiColumn ( MultiColumn_t *mc );
  5090. // return the number of printed lines including header and footer, or -1 on error
  5091. int PrintMultiColumn ( const MultiColumn_t *mc );
  5092. // Wrapper for short definition lines
  5093. // opt == 0 align right value
  5094. // opt >= 1 align left and try field width of # for value
  5095. exmem_key_t * PutLineMC ( MultiColumn_t *mc, uint opt, ccp key, ccp value, CopyMode_t cm_value );
  5096. exmem_key_t * PrintLineMC ( MultiColumn_t *mc, uint opt, ccp key, ccp format, ... )
  5097. __attribute__ ((__format__(__printf__,4,5)));
  5098. //
  5099. ///////////////////////////////////////////////////////////////////////////////
  5100. /////////////// Memory Map ///////////////
  5101. ///////////////////////////////////////////////////////////////////////////////
  5102. // [[MemMapItem_t]]
  5103. typedef struct MemMapItem_t
  5104. {
  5105. u64 off; // offset
  5106. u64 size; // size
  5107. u8 overlap; // system info: item overlaps other items
  5108. u8 index; // user defined index
  5109. char info[62]; // user defined info text
  5110. } MemMapItem_t;
  5111. //-----------------------------------------------------------------------------
  5112. // [[MemMap_t]]
  5113. typedef struct MemMap_t
  5114. {
  5115. MemMapItem_t ** field; // pointer to the item field
  5116. uint used; // number of used titles in the item field
  5117. uint size; // number of allocated pointers in 'field'
  5118. u64 begin; // first address
  5119. } MemMap_t;
  5120. //-----------------------------------------------------------------------------
  5121. // Memory maps allow duplicate entries.
  5122. // The off+size pair is used as key.
  5123. // The entries are sorted by off and size (small values first).
  5124. //-----------------------------------------------------------------------------
  5125. void InitializeMemMap ( MemMap_t * mm );
  5126. void ResetMemMap ( MemMap_t * mm );
  5127. void CopyMemMap
  5128. (
  5129. MemMap_t * mm1, // merged mem map, not NULL, cleared
  5130. const MemMap_t * mm2, // NULL or second mem map
  5131. bool use_tie // TRUE: use InsertMemMapTie()
  5132. );
  5133. void MergeMemMap
  5134. (
  5135. MemMap_t * mm1, // merged mem map, not NULL, not cleared
  5136. const MemMap_t * mm2, // NULL or second mem map
  5137. bool use_tie // TRUE: use InsertMemMapTie()
  5138. );
  5139. MemMapItem_t * FindMemMap
  5140. (
  5141. // returns NULL or the pointer to the one! matched key (={off,size})
  5142. MemMap_t * mm,
  5143. off_t off,
  5144. off_t size
  5145. );
  5146. uint InsertMemMapIndex
  5147. (
  5148. // returns the index of the new item
  5149. MemMap_t * mm, // mem map pointer
  5150. off_t off, // offset of area
  5151. off_t size // size of area
  5152. );
  5153. MemMapItem_t * InsertMemMap
  5154. (
  5155. // returns a pointer to a new item (never NULL)
  5156. MemMap_t * mm, // mem map pointer
  5157. off_t off, // offset of area
  5158. off_t size // size of area
  5159. );
  5160. MemMapItem_t * InsertMemMapTie
  5161. (
  5162. // returns a pointer to a new or existing item (never NULL)
  5163. MemMap_t * mm, // mem map pointer
  5164. off_t off, // offset of area
  5165. off_t size // size of area
  5166. );
  5167. void InsertMemMapWrapper
  5168. (
  5169. void * param, // user defined parameter
  5170. u64 offset, // offset of object
  5171. u64 size, // size of object
  5172. ccp info // info about object
  5173. );
  5174. // Remove all entires with key. Return number of delete entries
  5175. //uint RemoveMemMap ( MemMap_t * mm, off_t off, off_t size );
  5176. // Return the index of the found or next item
  5177. uint FindMemMapHelper ( MemMap_t * mm, off_t off, off_t size );
  5178. // Calculate overlaps. Return number of items with overlap.
  5179. uint CalcOverlapMemMap ( MemMap_t * mm );
  5180. u64 FindFreeSpaceMemMap
  5181. (
  5182. // return address or NULL on not-found
  5183. const MemMap_t * mm,
  5184. u64 addr_beg, // first possible address
  5185. u64 addr_end, // last possible address
  5186. u64 size, // minimal size
  5187. u64 align, // aligning
  5188. u64 *space // not NULL: store available space here
  5189. );
  5190. // Print out memory map
  5191. void PrintMemMap ( MemMap_t * mm, FILE * f, int indent, ccp info_head );
  5192. //
  5193. ///////////////////////////////////////////////////////////////////////////////
  5194. /////////////// Memory Map: Scan addresses ///////////////
  5195. ///////////////////////////////////////////////////////////////////////////////
  5196. // [[ScanAddr_t]]
  5197. typedef struct ScanAddr_t
  5198. {
  5199. uint stat; // 0:invalid, 1:single address, 2:range
  5200. uint addr; // address
  5201. uint size; // size inf bytes
  5202. } ScanAddr_t;
  5203. //-----------------------------------------------------------------------------
  5204. char * ScanAddress
  5205. (
  5206. // returns first not scanned char of 'arg'
  5207. ScanAddr_t * result, // result, initialized by ScanAddress()
  5208. ccp arg, // format: ADDR | ADDR:END | ADDR#SIZE
  5209. uint default_base // base for numbers without '0x' prefix
  5210. // 0: C like with octal support
  5211. // 10: standard value for decimal numbers
  5212. // 16: standard value for hex numbers
  5213. );
  5214. //-----------------------------------------------------------------------------
  5215. uint InsertAddressMemMap
  5216. (
  5217. // returns the number of added addresses
  5218. MemMap_t * mm, // mem map pointer
  5219. bool use_tie, // TRUE: use InsertMemMapTie()
  5220. ccp arg, // comma separated list of addresses
  5221. // formats: ADDR | ADDR:END | ADDR#SIZE
  5222. uint default_base // base for numbers without '0x' prefix
  5223. // 0: C like with octal support
  5224. // 10: standard value for decimal numbers
  5225. // 16: standard value for hex numbers
  5226. );
  5227. //
  5228. ///////////////////////////////////////////////////////////////////////////////
  5229. /////////////// DataBuf_t ///////////////
  5230. ///////////////////////////////////////////////////////////////////////////////
  5231. struct DataBuf_t;
  5232. typedef enumError (*DataBufFill_t)
  5233. (
  5234. // function to fill the buffer
  5235. struct DataBuf_t* db, // valid pointer to related DataBuf_t to fill
  5236. uint need, // number of bytes needed => wait for more data
  5237. int mode // user mode, null on auto fill
  5238. );
  5239. //-----------------------------------------------------------------------------
  5240. // [[DataBuf_t]]
  5241. typedef struct DataBuf_t
  5242. {
  5243. uint size; // size of buffer
  5244. uint used; // number of used bytes
  5245. u64 offset; // current file offset, related to 'data'
  5246. u8 *buf; // pointer to buffer, cyclic usage
  5247. u8 *buf_end; // pointer to buffer end := buf + size
  5248. u8 *data; // pointer to data
  5249. u8 *data_end; // pointer to end of data
  5250. //--- user data
  5251. DataBufFill_t fill_func; // function to fill buffer
  5252. void *user_data; // NULL or pointer to user data for 'fill_func'
  5253. }
  5254. DataBuf_t;
  5255. ///////////////////////////////////////////////////////////////////////////////
  5256. // management
  5257. void InitializeDataBuf
  5258. ( DataBuf_t *db, uint buf_size, DataBufFill_t func, void *user_data );
  5259. void ResetDataBuf ( DataBuf_t *db );
  5260. void ResizeDataBuf ( DataBuf_t *db, uint new_buf_size );
  5261. void ClearDataBuf ( DataBuf_t *db, uint new_buf_size_if_not_null );
  5262. void EmptyDataBuf ( DataBuf_t *db );
  5263. void PackDataBuf ( DataBuf_t *db );
  5264. ///////////////////////////////////////////////////////////////////////////////
  5265. // debugging
  5266. bool IsValidDataBuf ( DataBuf_t *db );
  5267. bool DumpDataBuf ( FILE *f, uint indent, DataBuf_t *db, bool if_invalid );
  5268. // fill the buffer with a test pattern:
  5269. // '-' for unused bytes
  5270. // ">0123456789<" in a longer or shorter form for used bytes
  5271. void FillPatternDataBuf ( DataBuf_t *db );
  5272. ///////////////////////////////////////////////////////////////////////////////
  5273. // insert and remove data
  5274. static inline enumError FillDataBuf( DataBuf_t *db, uint need, int mode )
  5275. {
  5276. return db && db->fill_func ? db->fill_func(db,need,mode) : ERR_WARNING;
  5277. }
  5278. uint InsertDataBuf
  5279. (
  5280. // Insert at top of buffer.
  5281. // Return the number of inserted bytes
  5282. DataBuf_t *db, // valid pointer to data buffer
  5283. const void *data, // data to insert
  5284. uint data_size, // size of 'data'
  5285. bool all_or_none // true: insert complete data or nothing
  5286. );
  5287. uint AppendDataBuf
  5288. (
  5289. // Append data at end of buffer
  5290. // Return the number of inserted bytes
  5291. DataBuf_t *db, // valid pointer to data buffer
  5292. const void *data, // data to insert
  5293. uint data_size, // size of 'data'
  5294. bool all_or_none // true: insert complete data or nothing
  5295. );
  5296. ///////////////////////////////////////////////////////////////////////////////
  5297. void * GetPtrDataBuf
  5298. (
  5299. // Return a pointer to the data and make sure,
  5300. // that the data is not wrapped. Return NULL if failed.
  5301. DataBuf_t *db, // valid pointer to data buffer
  5302. uint data_size, // number of needed bytes
  5303. uint align, // >1: Data alignment is also needed.
  5304. // Only 2,4,8,16,... are allowed, but not verified.
  5305. // Begin of buffer is always well aligned.
  5306. bool drop // true: On success, drop data from buffer
  5307. // In real, the data is available and only
  5308. // the pointers and counters are updated.
  5309. );
  5310. uint CopyDataBuf
  5311. (
  5312. // Copy data from buffer, but don't remove it
  5313. // Return the number of copied bytes
  5314. DataBuf_t *db, // valid pointer to data buffer
  5315. void *dest, // destination buffer wit at least 'max_size' space
  5316. uint min_read, // return with 0 read bytes if less bytes available
  5317. // if 'min_read' > 'size', NULL is returned
  5318. uint max_read // try to read upto 'max_read' bytes
  5319. );
  5320. uint GetDataBuf
  5321. (
  5322. // Copy data from buffer and remove it
  5323. // Return the number of copied bytes
  5324. DataBuf_t *db, // valid pointer to data buffer
  5325. void *dest, // destination buffer wit at least 'max_size' space
  5326. uint min_read, // return with 0 read bytes if less bytes available
  5327. uint max_read // try to read upto 'max_read' bytes
  5328. );
  5329. uint SkipDataBuf
  5330. (
  5331. // Skip 'skip_size' from input stream. Read more data if needed.
  5332. // Return the number of really skiped bytes
  5333. // If <skip_size is returned, no more data is available.
  5334. DataBuf_t *db, // valid pointer to data buffer
  5335. uint skip_size // number of bytes to drop
  5336. );
  5337. uint DropDataBuf
  5338. (
  5339. // Remove upto 'drop_size' bytes from buffer.
  5340. // Return the number of dropped bytes.
  5341. DataBuf_t *db, // valid pointer to data buffer
  5342. uint drop_size // number of bytes to drop
  5343. );
  5344. //
  5345. ///////////////////////////////////////////////////////////////////////////////
  5346. /////////////// ResizeElement_t, ResizeHelper_t ///////////////
  5347. ///////////////////////////////////////////////////////////////////////////////
  5348. // [[ResizeElement_t]]
  5349. typedef struct ResizeElement_t
  5350. {
  5351. uint n_elem;
  5352. uint factor;
  5353. }
  5354. ResizeElement_t;
  5355. //-----------------------------------------------------------------------------
  5356. // [[ResizeHelper_t]]
  5357. typedef struct ResizeHelper_t
  5358. {
  5359. //--- basic data
  5360. uint src_size; // size of source
  5361. uint dest_size; // size of dest
  5362. //--- calculated data
  5363. uint sum_factor; // sum of all factors
  5364. uint half_factor; // half of 'sum_factor2'
  5365. uint idx_inc; // increment of 'src_idx'
  5366. uint frac_inc; // increment of 'src_frac'
  5367. uint frac_next; // if 'frac>=frac_next': increment 'src_idx'
  5368. //--- iteration data
  5369. uint dest_idx; // dest index: (0..dest_size(
  5370. uint src_idx; // src index: (0..src_size(
  5371. uint src_frac; // (0..frac_next(
  5372. ResizeElement_t // list terminates with n_elem=0
  5373. elem[4]; // ==> max 3 elements are used
  5374. }
  5375. ResizeHelper_t;
  5376. //-----------------------------------------------------------------------------
  5377. void InitializeResize
  5378. (
  5379. ResizeHelper_t *r, // data structure
  5380. uint s_size, // size of source
  5381. uint d_size // size of dest
  5382. );
  5383. bool FirstResize ( ResizeHelper_t *r );
  5384. bool NextResize ( ResizeHelper_t *r );
  5385. //
  5386. ///////////////////////////////////////////////////////////////////////////////
  5387. /////////////// restore configuration ///////////////
  5388. ///////////////////////////////////////////////////////////////////////////////
  5389. // [[RestoreStateLog_t]]
  5390. typedef enum RestoreStateLog_t
  5391. {
  5392. RSL_WARNINGS = 0x01, // general warnings
  5393. RSL_MISSED_NAMES = 0x02, // hints about missed names
  5394. RSL_UNUSED_NAMES = 0x04, // hints about unused names
  5395. RSL_ALL = 0x07 // all flags
  5396. }
  5397. RestoreStateLog_t;
  5398. //-----------------------------------------------------------------------------
  5399. // [[RestoreState_t]]
  5400. typedef struct RestoreState_t
  5401. {
  5402. ccp sect; // section name
  5403. ccp path; // section sub path
  5404. int index; // index or -1
  5405. ParamField_t param; // name=value parameters
  5406. cvp user_param; // pointer provided as parameter by user
  5407. cvp user_info; // pointer to deliver insfos between stages
  5408. RestoreStateLog_t log_mode; // log mode
  5409. FILE *log_file; // log file
  5410. }
  5411. RestoreState_t;
  5412. ///////////////////////////////////////////////////////////////////////////////
  5413. static inline void InitializeRestoreState ( RestoreState_t *rs )
  5414. { DASSERT(rs); memset(rs,0,sizeof(*rs)); }
  5415. void ResetRestoreState ( RestoreState_t *rs );
  5416. ///////////////////////////////////////////////////////////////////////////////
  5417. // [[RestoreStateFunc]]
  5418. typedef void (*RestoreStateFunc)
  5419. (
  5420. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  5421. cvp user_table // pointer provided by RestoreStateTab_t[]
  5422. );
  5423. //-----------------------------------------------------------------------------
  5424. // [[RestoreStateTab_t]]
  5425. typedef struct RestoreStateTab_t
  5426. {
  5427. ccp name; // name of section
  5428. RestoreStateFunc func; // function to call
  5429. cvp user_table; // any user provided pointer
  5430. }
  5431. RestoreStateTab_t;
  5432. ///////////////////////////////////////////////////////////////////////////////
  5433. enumError ScanRestoreState
  5434. (
  5435. RestoreState_t *rs, // valid control
  5436. void *data, // file data, modified, terminated by NULL or LF
  5437. uint size, // size of file data
  5438. void **end_data // not NULL: store end of analysed here
  5439. );
  5440. ///////////////////////////////////////////////////////////////////////////////
  5441. enumError RestoreState
  5442. (
  5443. const RestoreStateTab_t
  5444. *table, // section table, terminated by name==0
  5445. void *data, // file data, modified, terminated by NULL or LF
  5446. uint size, // size of file data
  5447. RestoreStateLog_t log_mode, // print warnings (bit field)
  5448. FILE *log_file, // error file; if NULL use stderr
  5449. cvp user_param // pointer provided by user
  5450. );
  5451. ///////////////////////////////////////////////////////////////////////////////
  5452. // print into cyclic buffer
  5453. ccp PrintRestoreStateSection ( const RestoreState_t *rs );
  5454. ///////////////////////////////////////////////////////////////////////////////
  5455. ///////////////////////////////////////////////////////////////////////////////
  5456. ParamFieldItem_t * GetParamField
  5457. (
  5458. const RestoreState_t *rs, // valid restore-state structure
  5459. ccp name // name of member
  5460. );
  5461. //-----------------------------------------------------------------------------
  5462. int GetParamFieldINT
  5463. (
  5464. const RestoreState_t *rs, // valid restore-state structure
  5465. ccp name, // name of member
  5466. int not_found // return this value if not found
  5467. );
  5468. //-----------------------------------------------------------------------------
  5469. uint GetParamFieldUINT
  5470. (
  5471. const RestoreState_t *rs, // valid restore-state structure
  5472. ccp name, // name of member
  5473. uint not_found // return this value if not found
  5474. );
  5475. //-----------------------------------------------------------------------------
  5476. u64 GetParamFieldS64
  5477. (
  5478. const RestoreState_t *rs, // valid restore-state structure
  5479. ccp name, // name of member
  5480. s64 not_found // return this value if not found
  5481. );
  5482. //-----------------------------------------------------------------------------
  5483. u64 GetParamFieldU64
  5484. (
  5485. const RestoreState_t *rs, // valid restore-state structure
  5486. ccp name, // name of member
  5487. u64 not_found // return this value if not found
  5488. );
  5489. //-----------------------------------------------------------------------------
  5490. float GetParamFieldFLOAT
  5491. (
  5492. const RestoreState_t *rs, // valid restore-state structure
  5493. ccp name, // name of member
  5494. float not_found // return this value if not found
  5495. );
  5496. //-----------------------------------------------------------------------------
  5497. double GetParamFieldDBL
  5498. (
  5499. const RestoreState_t *rs, // valid restore-state structure
  5500. ccp name, // name of member
  5501. double not_found // return this value if not found
  5502. );
  5503. //-----------------------------------------------------------------------------
  5504. long double GetParamFieldLDBL
  5505. (
  5506. const RestoreState_t *rs, // valid restore-state structure
  5507. ccp name, // name of member
  5508. long double not_found // return this value if not found
  5509. );
  5510. //-----------------------------------------------------------------------------
  5511. int GetParamFieldBUF
  5512. (
  5513. // returns >=0: length of read data; -1:nothing done (not_found==NULL)
  5514. char *buf, // buffer to store result
  5515. uint buf_size, // size of buffer
  5516. const RestoreState_t *rs, // valid restore-state structure
  5517. ccp name, // name of member
  5518. EncodeMode_t decode, // decoding mode, fall back to OFF
  5519. // supported: STRING, UTF8, BASE64, BASE64X
  5520. ccp not_found // not NULL: store this value if not found
  5521. );
  5522. //-----------------------------------------------------------------------------
  5523. mem_t GetParamFieldMEM
  5524. (
  5525. // Returns the decoded 'source'. Result is NULL-terminated.
  5526. // It points either to 'buf' or is alloced (on buf==NULL or too less space)
  5527. // If alloced (mem.ptr!=buf) => call FreeMem(&mem)
  5528. char *buf, // buffer to store result
  5529. uint buf_size, // size of buffer
  5530. const RestoreState_t *rs, // valid restore-state structure
  5531. ccp name, // name of member
  5532. EncodeMode_t decode, // decoding mode, fall back to OFF
  5533. // supported: STRING, UTF8, BASE64, BASE64X
  5534. mem_t not_found // not NULL: return this value
  5535. );
  5536. //
  5537. ///////////////////////////////////////////////////////////////////////////////
  5538. /////////////// save + restore config by table ///////////////
  5539. ///////////////////////////////////////////////////////////////////////////////
  5540. // [[SaveRestoreType_t]]
  5541. typedef enum SaveRestoreType_t
  5542. {
  5543. SRT__TERM, // list terminator
  5544. SRT_BOOL, // type bool
  5545. SRT_UINT, // unsigned int of any size (%llu)
  5546. SRT_HEX, // unsigned int of any size as hex (%#llx)
  5547. SRT_COUNT, // unsigned int of any size (%llu), used as array counter
  5548. SRT_INT, // signed int of any size (%lld)
  5549. SRT_FLOAT, // float (%.8g) or double (%.16g) or long double (%.20g)
  5550. SRT_XFLOAT, // float or double or long double as hex-float (%a/%La)
  5551. SRT_STRING_SIZE, // string with max size, var is char[]
  5552. SRT_STRING_ALLOC, // alloced string, var is ccp or char*
  5553. SRT_MEM, // alloced string, var is mem_t
  5554. SRT_DEF_ARRAY, // define/end an array of structs
  5555. SRT_MODE__BEGIN, //--- begin of modes
  5556. SRT_MODE_ASSIGN, // load option: assign numeric values (default)
  5557. SRT_MODE_ADD, // load option: add numeric values
  5558. SRT_MODE__END, //--- end of modes
  5559. SRT__IS_LIST, //----- from here: print lists; also used as separator
  5560. SRT_STRING_FIELD, // var is StringField_t
  5561. SRT_PARAM_FIELD, // var is ParamField_t
  5562. SRT_F_SIZE = 0x100, // factor for implicit size-modes for numerical types
  5563. }
  5564. SaveRestoreType_t;
  5565. ///////////////////////////////////////////////////////////////////////////////
  5566. // [[SaveRestoreTab_t]]
  5567. typedef struct SaveRestoreTab_t
  5568. {
  5569. uint offset; // offset of variable
  5570. uint size; // sizeof( var or string )
  5571. ccp name; // name in configuration file
  5572. union
  5573. {
  5574. struct
  5575. {
  5576. s16 n_elem; // >0: is array with N elements
  5577. // <0: is array with -N elements, use last SRT_COUNT
  5578. u8 type; // SaveRestoreType_t
  5579. u8 emode; // EncodeMode_t
  5580. };
  5581. //struct SaveRestoreTab_t *ref;
  5582. };
  5583. }
  5584. __attribute__ ((packed)) SaveRestoreTab_t;
  5585. //-----------------------------------------------------------------------------
  5586. // At the very beginning of the table, define 'SRT_NAME' by 2 lines:
  5587. // #undef SRT_NAME
  5588. // #define SRT_NAME name_of_the_struct
  5589. #define DEF_SRT_VAR(v,ne,n,t,e) {offsetof(SRT_NAME,v),sizeof(((SRT_NAME*)0)->v),n, \
  5590. .n_elem=ne,.type=t,.emode=e}
  5591. #define DEF_SRT_BOOL(v,n) DEF_SRT_VAR(v,1,n,SRT_BOOL,0)
  5592. #define DEF_SRT_UINT(v,n) DEF_SRT_VAR(v,1,n,SRT_UINT,0)
  5593. #define DEF_SRT_HEX(v,n) DEF_SRT_VAR(v,1,n,SRT_HEX,0)
  5594. #define DEF_SRT_COUNT(v,n) DEF_SRT_VAR(v,1,n,SRT_COUNT,0)
  5595. #define DEF_SRT_INT(v,n) DEF_SRT_VAR(v,1,n,SRT_INT,0)
  5596. #define DEF_SRT_FLOAT(v,n) DEF_SRT_VAR(v,1,n,SRT_FLOAT,0)
  5597. #define DEF_SRT_XFLOAT(v,n) DEF_SRT_VAR(v,1,n,SRT_XFLOAT,0)
  5598. #define DEF_SRT_STR_SIZE(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_SIZE,e)
  5599. #define DEF_SRT_STR_ALLOC(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_ALLOC,e)
  5600. #define DEF_SRT_MEM(v,n,e) DEF_SRT_VAR(v,1,n,SRT_MEM,e)
  5601. #define DEF_SRT_STRING_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_FIELD,e)
  5602. #define DEF_SRT_PARAM_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_PARAM_FIELD,e)
  5603. //--- n elements : if n<0, then n_elem=-n && use last SRT_COUNT
  5604. #define DEF_SRT_BOOL_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_BOOL,0)
  5605. #define DEF_SRT_UINT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_UINT,0)
  5606. #define DEF_SRT_HEX_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_HEX,0)
  5607. #define DEF_SRT_INT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_INT,0)
  5608. #define DEF_SRT_FLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_FLOAT,0)
  5609. #define DEF_SRT_XFLOAT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_XFLOAT,0)
  5610. #define DEF_SRT_STR_SIZE_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_SIZE,e)
  5611. #define DEF_SRT_STR_ALLOC_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_STRING_ALLOC,e)
  5612. #define DEF_SRT_MEM_N(v,ne,n,e) DEF_SRT_VAR(v,ne,n,SRT_MEM,e)
  5613. //--- auto array
  5614. #define DEF_SRT_ARRAY(v,n,t,e) \
  5615. {offsetof(SRT_NAME,v), sizeof(((SRT_NAME*)0)->v[0]), n, \
  5616. .n_elem=sizeof(((SRT_NAME*)0)->v)/sizeof(*((SRT_NAME*)0)->v), .type=t, .emode=e }
  5617. #define DEF_SRT_BOOL_A(v,n) DEF_SRT_ARRAY(v,n,SRT_BOOL,0)
  5618. #define DEF_SRT_UINT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_UINT,0)
  5619. #define DEF_SRT_HEX_A(v,n) DEF_SRT_ARRAY(v,n,SRT_HEX,0)
  5620. #define DEF_SRT_INT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_INT,0)
  5621. #define DEF_SRT_FLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_FLOAT,0)
  5622. #define DEF_SRT_XFLOAT_A(v,n) DEF_SRT_ARRAY(v,n,SRT_XFLOAT,0)
  5623. #define DEF_SRT_STR_SIZE_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_SIZE,e)
  5624. #define DEF_SRT_STR_ALLOC_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_ALLOC,e)
  5625. #define DEF_SRT_MEM_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_MEM,e)
  5626. //--- auto array, use last SRT_COUNT for element-count
  5627. #define DEF_SRT_ARRAY_C(v,n,t,e) \
  5628. {offsetof(SRT_NAME,v), sizeof(((SRT_NAME*)0)->v[0]), n, \
  5629. .n_elem=-(s16)(sizeof(((SRT_NAME*)0)->v)/sizeof(*((SRT_NAME*)0)->v)), .type=t, .emode=e }
  5630. #define DEF_SRT_BOOL_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_BOOL,0)
  5631. #define DEF_SRT_UINT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_UINT,0)
  5632. #define DEF_SRT_HEX_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_HEX,0)
  5633. #define DEF_SRT_INT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_INT,0)
  5634. #define DEF_SRT_FLOAT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_FLOAT,0)
  5635. #define DEF_SRT_XFLOAT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_XFLOAT,0)
  5636. #define DEF_SRT_STR_SIZE_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_STRING_SIZE,e)
  5637. #define DEF_SRT_STR_ALLOC_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_STRING_ALLOC,e)
  5638. #define DEF_SRT_MEM_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_MEM,e)
  5639. //--- array of structs
  5640. #define DEF_SRT_ARRAY_FL(f,l) \
  5641. {offsetof(SRT_NAME,f), sizeof(((SRT_NAME*)0)->f), 0, \
  5642. .n_elem=(offsetof(SRT_NAME,l)-offsetof(SRT_NAME,f))/sizeof(((SRT_NAME*)0)->f)+1, \
  5643. .type=SRT_DEF_ARRAY }
  5644. #define DEF_SRT_ARRAY_FLC(f,l) \
  5645. {offsetof(SRT_NAME,f), sizeof(((SRT_NAME*)0)->f), 0, \
  5646. .n_elem=-(s16)((offsetof(SRT_NAME,l)-offsetof(SRT_NAME,f)) \
  5647. /sizeof(((SRT_NAME*)0)->f)+1), .type=SRT_DEF_ARRAY }
  5648. #define DEF_SRT_ARRAY_N(v,ne) DEF_SRT_VAR(v[0],ne,0,SRT_DEF_ARRAY,0)
  5649. #define DEF_SRT_ARRAY_A(v) DEF_SRT_ARRAY(v,0,SRT_DEF_ARRAY,0)
  5650. #define DEF_SRT_ARRAY_AC(v) DEF_SRT_ARRAY_C(v,0,SRT_DEF_ARRAY,0)
  5651. #define DEF_SRT_ARRAY_END() {0,0,0,.type=SRT_DEF_ARRAY}
  5652. //--- global array of structs
  5653. #define DEF_SRT_ARRAY_GN(ne) {0,sizeof(SRT_NAME),0,.n_elem=ne,.type=SRT_DEF_ARRAY}
  5654. #define DEF_SRT_ARRAY_GA(v) {0,sizeof(*v),0,.n_elem=sizeof(v)/sizeof(*v),.type=SRT_DEF_ARRAY}
  5655. //--- modes
  5656. #define DEF_SRT_MODE_ASSIGN() {0,0,0,.type=SRT_MODE_ASSIGN}
  5657. #define DEF_SRT_MODE_ADD() {0,0,0,.type=SRT_MODE_ADD}
  5658. //--- special
  5659. #define DEF_SRT_SEPARATOR() {0,0,0,.type=SRT__IS_LIST}
  5660. #define DEF_SRT_COMMENT(c) {0,0,c,.type=SRT__IS_LIST}
  5661. #define DEF_SRT_TERM() {0,0,0,.type=SRT__TERM}
  5662. ///////////////////////////////////////////////////////////////////////////////
  5663. extern int srt_auto_dump;
  5664. extern FILE *srt_auto_dump_file;
  5665. void DumpStateTable
  5666. (
  5667. FILE *f, // valid output file
  5668. int indent,
  5669. const SaveRestoreTab_t
  5670. *srt // list of variables
  5671. );
  5672. void SaveCurrentStateByTable
  5673. (
  5674. FILE *f, // valid output file
  5675. cvp data0, // valid pointer to source struct
  5676. const SaveRestoreTab_t
  5677. *srt, // list of variables
  5678. ccp prefix, // NULL or prefix for names
  5679. uint fw_name // field width of name, 0=AUTO
  5680. // tabs are used for multiple of 8 and for AUTO
  5681. );
  5682. void RestoreStateByTable
  5683. (
  5684. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  5685. void *data0, // valid pointer to destination struct
  5686. const SaveRestoreTab_t
  5687. *srt, // list of variables
  5688. ccp prefix // NULL or prefix for names
  5689. );
  5690. ///////////////////////////////////////////////////////////////////////////////
  5691. ///////////////////////////////////////////////////////////////////////////////
  5692. extern const SaveRestoreTab_t SRT_UsageCount[];
  5693. extern const SaveRestoreTab_t SRT_UsageDuration[];
  5694. extern const SaveRestoreTab_t SRT_CpuUsage[];
  5695. //
  5696. ///////////////////////////////////////////////////////////////////////////////
  5697. /////////////// GrowBuffer_t ///////////////
  5698. ///////////////////////////////////////////////////////////////////////////////
  5699. // [[GrowBuffer_t]]
  5700. typedef struct GrowBuffer_t
  5701. {
  5702. // allways: gb->ptr[gb->used] == 0
  5703. u8 *buf; // NULL or data buffer
  5704. uint size; // size of 'buf'
  5705. uint grow_size; // >0: auto grow buffer by multiple of this
  5706. uint max_size; // >0: max size for auto grow
  5707. u8 *ptr; // pointer to first valid byte
  5708. uint used; // number of valid bytes behind 'ptr'
  5709. uint max_used; // max 'used' value
  5710. uint disabled; // disable rading from TCP socket
  5711. }
  5712. GrowBuffer_t;
  5713. ///////////////////////////////////////////////////////////////////////////////
  5714. void LogGrowBuffer
  5715. (
  5716. FILE *f, // output file
  5717. int indent, // indention
  5718. const GrowBuffer_t *gb, // valid grow-buffer
  5719. ccp format, // format string for vfprintf()
  5720. ... // arguments for 'vfprintf(format,...)'
  5721. )
  5722. __attribute__ ((__format__(__printf__,4,5)));
  5723. //-----------------------------------------------------------------------------
  5724. void InitializeGrowBuffer ( GrowBuffer_t *gb, uint max_buf_size );
  5725. void ResetGrowBuffer ( GrowBuffer_t *gb );
  5726. uint ClearGrowBuffer ( GrowBuffer_t *gb ); // returns available space
  5727. uint PurgeGrowBuffer ( GrowBuffer_t *gb ); // returns available space
  5728. //-----------------------------------------------------------------------------
  5729. uint GetSpaceGrowBuffer
  5730. (
  5731. // returns the maximum possible space
  5732. const GrowBuffer_t *gb // valid grow-buffer object
  5733. );
  5734. //-----------------------------------------------------------------------------
  5735. uint PrepareGrowBuffer
  5736. (
  5737. // returns the number of available space, smaller than or equal 'size'
  5738. GrowBuffer_t *gb, // valid grow-buffer object
  5739. uint size, // needed size
  5740. bool force // always alloc enough space and return 'size'
  5741. );
  5742. uint InsertGrowBuffer
  5743. (
  5744. // returns the number of inserted bytes
  5745. GrowBuffer_t *gb, // valid grow-buffer object
  5746. const void *data, // data to insert
  5747. uint size // size of 'data'
  5748. );
  5749. static inline uint InsertCharGrowBuffer
  5750. (
  5751. // returns the number of inserted bytes (0 on fail, 1 else)
  5752. GrowBuffer_t *gb, // valid grow-buffer object
  5753. char ch // any character including NULL
  5754. )
  5755. {
  5756. return InsertGrowBuffer(gb,&ch,1);
  5757. }
  5758. static inline uint InsertMemGrowBuffer
  5759. (
  5760. // returns the number of inserted bytes
  5761. GrowBuffer_t *gb, // valid grow-buffer object
  5762. mem_t mem // any data
  5763. )
  5764. {
  5765. return InsertGrowBuffer(gb,mem.ptr,mem.len);
  5766. }
  5767. uint InsertCapNGrowBuffer
  5768. (
  5769. // insert 'cap_1' or 'cap_n' depending of 'n' and the existence of 'cap_*'
  5770. // returns the number of inserted bytes
  5771. GrowBuffer_t *gb, // valid grow-buffer object
  5772. int n, // repeat number; if <1: insert nothing
  5773. mem_t cap_1, // default for N=1
  5774. mem_t cap_n // default for N>1
  5775. );
  5776. uint WriteCapN
  5777. (
  5778. // print 'cap_1' or 'cap_n' depending of 'n' and the existence of 'cap_*'
  5779. // returns the number of printed bytes
  5780. FILE *f, // valid FILE
  5781. int n, // repeat number; if <1: insert nothing
  5782. mem_t cap_1, // default for N=1
  5783. mem_t cap_n // default for N>1
  5784. );
  5785. uint InsertCatchedGrowBuffer
  5786. (
  5787. // returns the number of inserted bytes
  5788. GrowBuffer_t *gb, // valid grow-buffer object
  5789. SavedStdFiles_t *ssf // saved output and catched data
  5790. );
  5791. ///////////////////////////////////////////////////////////////////////////////
  5792. uint PrintArgGrowBuffer
  5793. (
  5794. // returns the number of inserted bytes
  5795. GrowBuffer_t *gb, // valid grow-buffer object
  5796. ccp format, // format string for vfprintf()
  5797. va_list arg // arguments for 'vsnprintf(format,...)'
  5798. );
  5799. uint PrintGrowBuffer
  5800. (
  5801. // returns the number of inserted bytes
  5802. GrowBuffer_t *gb, // valid grow-buffer object
  5803. ccp format, // format string for vfprintf()
  5804. ... // arguments for 'vsnprintf(format,...)'
  5805. )
  5806. __attribute__ ((__format__(__printf__,2,3)));
  5807. //-----------------------------------------------------------------------------
  5808. uint ConvertToCrLfGrowBuffer
  5809. (
  5810. // returns the number of inserted CR bytes
  5811. GrowBuffer_t *gb, // valid grow-buffer object
  5812. uint begin // index to begin with conversion
  5813. );
  5814. //-----------------------------------------------------------------------------
  5815. uint DropGrowBuffer
  5816. (
  5817. // returns the number of dropped bytes
  5818. GrowBuffer_t *gb, // valid grow-buffer object
  5819. uint size // number of bytes to drop
  5820. );
  5821. //-----------------------------------------------------------------------------
  5822. #ifndef __APPLE__
  5823. FILE * OpenFileGrowBuffer
  5824. (
  5825. // returns a FILE opened by fmemopen() => call CloseFileGrowBuffer()
  5826. GrowBuffer_t *gb, // valid grow-buffer object
  5827. uint size // needed size
  5828. );
  5829. int CloseFileGrowBuffer
  5830. (
  5831. // returns the number of wirtten bytes, or -1 on error
  5832. GrowBuffer_t *gb, // valid grow-buffer object
  5833. FILE *f // FILE returned by OpenFileGrowBuffer()
  5834. );
  5835. #endif // !__APPLE__
  5836. //-----------------------------------------------------------------------------
  5837. void SaveCurrentStateGrowBuffer
  5838. (
  5839. FILE *f, // output file
  5840. ccp name_prefix, // NULL or prefix of name
  5841. uint tab_pos, // tab pos of '='
  5842. const GrowBuffer_t *gb // valid grow-buffer
  5843. );
  5844. void RestoreStateGrowBuffer
  5845. (
  5846. GrowBuffer_t *gb, // valid grow-buffer
  5847. ccp name_prefix, // NULL or prefix of name
  5848. RestoreState_t *rs // info data, can be modified (cleaned after call)
  5849. );
  5850. //-----------------------------------------------------------------------------
  5851. int WriteDirectGrowBuffer
  5852. (
  5853. // write() data direct without blocking and without calling any notifier.
  5854. // If output buf is not empty or send failed, append the data to 'gb'.
  5855. // Returns the number of bytes added to the grow buffer or -1 on error.
  5856. // The data is send+stored completely (returns 'size') or not at all
  5857. // (returns '0'). -1 is returned if the socket is invalid.
  5858. GrowBuffer_t *gb, // grow buffer to cache data
  5859. int fd, // destination file
  5860. bool flush_output, // true: try to flush 'gb' before
  5861. cvp data, // data to send
  5862. uint size, // size of 'data', If NULL && flush: flush only
  5863. uint *send_count // not NULL: add num of sent bytes
  5864. );
  5865. //-----------------------------------------------------------------------------
  5866. int SendDirectGrowBuffer
  5867. (
  5868. // send() data direct without blocking and without calling any notifier.
  5869. // If output buf is not empty or send failed, append the data to 'gb'.
  5870. // Returns the number of bytes added to the grow buffer or -1 on error.
  5871. // The data is send+stored completely (returns 'size') or not at all
  5872. // (returns '0'). -1 is returned if the socket is invalid.
  5873. GrowBuffer_t *gb, // grow buffer to cache data
  5874. int sock, // destination socket
  5875. bool flush_output, // true: try to flush 'gb' before
  5876. cvp data, // data to send
  5877. uint size, // size of 'data', If NULL && flush: flush only
  5878. uint *send_count // not NULL: add num of sent bytes
  5879. );
  5880. //-----------------------------------------------------------------------------
  5881. static inline int FlushGrowBuffer
  5882. (
  5883. // Try to flush the bufer using SendDirectGrowBuffer() withour new data.
  5884. GrowBuffer_t *gb, // grow buffer to cache data
  5885. int sock, // destination socket
  5886. uint *send_count // not NULL: add num of sent bytes
  5887. )
  5888. {
  5889. return SendDirectGrowBuffer(gb,sock,true,0,0,send_count);
  5890. }
  5891. //
  5892. ///////////////////////////////////////////////////////////////////////////////
  5893. /////////////// misc ///////////////
  5894. ///////////////////////////////////////////////////////////////////////////////
  5895. #define CONVERT_TO_STRING1(a) #a
  5896. #define CONVERT_TO_STRING(a) CONVERT_TO_STRING1(a)
  5897. extern int opt_new; // default 0
  5898. float double2float ( double d ); // reduce precision
  5899. uint CreateUniqueIdN ( int range );
  5900. static inline uint CreateUniqueId(void) { return CreateUniqueIdN(1); }
  5901. static inline uint CreateUniqueIdNBO(void) { return htonl(CreateUniqueIdN(1)); }
  5902. void Sha1Hex2Bin ( sha1_hash_t bin, ccp src, ccp end );
  5903. void Sha1Bin2Hex ( sha1_hex_t hex, cvp bin );
  5904. // return CircBuf()
  5905. ccp GetSha1Hex ( cvp bin );
  5906. ///////////////////////////////////////////////////////////////////////////////
  5907. static uint snprintfS ( char *buf, size_t size, ccp format, ... )
  5908. __attribute__ ((__format__(__printf__,3,4)));
  5909. static inline uint snprintfS ( char *buf, size_t size, ccp format, ... )
  5910. {
  5911. va_list arg;
  5912. va_start(arg,format);
  5913. const int res = vsnprintf(buf,size,format,arg);
  5914. va_end(arg);
  5915. return res < 0 ? 0 : res < size ? res : size - 1;
  5916. }
  5917. static char * snprintfE ( char *buf, char *end, ccp format, ... )
  5918. __attribute__ ((__format__(__printf__,3,4)));
  5919. static inline char * snprintfE ( char *buf, char *end, ccp format, ... )
  5920. {
  5921. const int size = end - buf;
  5922. DASSERT( size > 0 );
  5923. va_list arg;
  5924. va_start(arg,format);
  5925. const int res = vsnprintf(buf,size,format,arg);
  5926. va_end(arg);
  5927. return buf + ( res < 0 ? 0 : res < size ? res : size - 1 );
  5928. }
  5929. ///////////////////////////////////////////////////////////////////////////////
  5930. void * dc_memrchr ( cvp src, int ch, size_t size );
  5931. bool IsMemConst ( cvp mem, uint size, u8 val );
  5932. #ifdef __APPLE__
  5933. #define memrchr dc_memrchr
  5934. #endif
  5935. //
  5936. ///////////////////////////////////////////////////////////////////////////////
  5937. /////////////// E N D ///////////////
  5938. ///////////////////////////////////////////////////////////////////////////////
  5939. #endif // DCLIB_BASICS_H