diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bfece6..a25ed68 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,16 +4,16 @@ cmake_minimum_required(VERSION 3.10) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) -set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD 11) add_definitions(-DCMAKE_EXPORT_COMPILE_COMMANDS=ON) if (NOT MSVC) - set(WARNING_FLAGS_C -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef -Wmisleading-indentation -Wnull-dereference -Wswitch-default -Wstrict-overflow=5 -Wconversion -Wno-sign-conversion -Wsign-promo -Wcast-align -Wcast-qual -Wdouble-promotion -Wformat=2 -Winit-self -Wdisabled-optimization -Wno-unused-function) + set(WARNING_FLAGS_C -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef -Wmisleading-indentation -Wnull-dereference -Wswitch-default -Wstrict-overflow=5 -Wconversion -Wno-sign-conversion -Wcast-align -Wcast-qual -Wdouble-promotion -Wformat=2 -Winit-self -Wdisabled-optimization -Wno-unused-function) set(WARNING_FLAGS_CXX -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef -Wmisleading-indentation -Wnull-dereference -Wswitch-default -Wstrict-overflow=5 -Wconversion -Wno-sign-conversion -Wsign-promo -Wcast-align -Wcast-qual -Wdouble-promotion -Wformat=2 -Winit-self -Wdisabled-optimization -Woverloaded-virtual -Wredundant-decls -Wctor-dtor-privacy -Wno-unused-function) - set(DBG_FLAGS -fsanitize=undefined,address -g3 -glldb -Og) + set(DBG_FLAGS -fsanitize=undefined,address -g3 -Og) else () set(WARNING_FLAGS_C /W4) set(WARNING_FLAGS_CXX /W4) @@ -45,7 +45,7 @@ set(LIBGUF_IMPLS ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_alloc_libc_impl.c foreach(current_target IN LISTS TARGETS) add_executable(${current_target} ${current_target}/${current_target}.c ${LIBGUF_IMPLS}) set_target_properties(${current_target} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) - target_include_directories(${current_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/" "${CMAKE_CURRENT_SOURCE_DIR}/libguf/src/") + target_include_directories(${current_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/" "${CMAKE_CURRENT_SOURCE_DIR}/libguf/") target_compile_options(${current_target} PRIVATE ${WARNING_FLAGS_C} $<$:${DBG_FLAGS}>) target_link_options(${current_target} PRIVATE ${WARNING_FLAGS_C} $<$:${DBG_FLAGS}>) diff --git a/README.md b/README.md new file mode 100755 index 0000000..9bfea6d --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# Advent of Code 2025 +C99 solutions to the puzzles of [Advent of Code 2025](https://adventofcode.com/2025) using my [libguf](https://git.tilde.town/fruit/libguf). + +(Previous years: [2024](https://github.com/zeichensystem/advent-of-code-2024), [2023](https://github.com/zeichensystem/advent-of-code-2023)) + +As the creator of Advent of Code does not allow/encourage sharing your own puzzle inputs, I only put example puzzle inputs into [input/](input/) publicly, so you can at least run those if you don't have your own puzzle inputs. + +My answers are correct for my puzzle inputs (and for the example inputs), but in my experience it is definitely possible to come up with *incorrect* code which may produce the *correct* answers for your own puzzle input, but which might not work for all other possible/legal puzzle inputs. (I put the answers to my puzzle inputs and to the example inputs as comments at the very top of the source-files for each day.) + +## How to build and run +You need at least a C99 compiler and cmake. + +### 1. Configure cmake and generate build systems +Navigate to the top level of this repository (the directory where [CMakeLists.txt](CMakeLists.txt) is located) and create your build directories, for instance: + +`mkdir -p build/Release build/Debug` + +Then, run: + +`cmake -DCMAKE_BUILD_TYPE=Release -S . -B build/Release` + +`cmake -DCMAKE_BUILD_TYPE=Debug -S . -B build/Debug` + +to generate the release build system into your build directory `build/Release` (and the debug build system into your build directory `build/Debug`). (If you do not run the commands at the top level of this repository, you have to run them with `-S path-to-this-repo` instead of `-S .` like above.) + +You can also set `-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=` if you want to use a custom output directory for the compiled binaries; by default, they will be put into the `bin/` directory at the root of this repository. + +### 2. Build +Run + +`cmake --build build/Release --target day-nn` + +to build the release-mode executable for `day-nn` (or run `cmake --build build/Release` to build the release-mode executables for all days, but this might take a while). + +The resulting executable will be called `day-nn` (or `day-nn_dbg` for debug builds). By default, it will be put into the `bin/` directory at the root of this repository (or into the directory you specified with `-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=` in step 1). + +(For example: Run `cmake --build build/Release --target day-03` to build the release-mode executable which solves Day 3. It will be put into `bin/day-03` by default. Or run `cmake --build build/Debug --target day-03` to build the debug-mode executable `bin/day-03_dbg` instead, assuming you generated the debug build system into 'build/Debug' in step 1.) + +### 3. Run +Run `bin/day-nn input_day_nn.txt` to compute and print the solutions (part 1 and part 2) for *day-nn* (with `input_day_nn.txt` being your puzzle input for that day). If you don't have your own puzzle inputs, you can use the example inputs from the [input/](input/) directory. + +``` +Usage: day-nn [-help] puzzle_input [-v] + -v: use verbose output (optional) + -help: print this help, ignore the rest, and quit (optional) + puzzle_input: your puzzle input file (optional/ignored if -help is used) +``` + +You can also build and run *day-nn* in one step with `cmake --build build/Release --target run-day-nn`, but this assumes you have saved your puzzle input for *day-nn* as `input/day-nn.txt` within this repository. + +If you don't have your own puzzle inputs but still want to test the executable for *day-nn*, you can build and run with `cmake --build build/Release --target run-day-nn-example` (which uses the puzzle's example input `input/day-nn-example.txt` automatically). + +For example: `cmake --build build/Release --target run-day-02-example` to build and run the release-mode executable for *day-02* with the example input [input/day-02-example.txt](input/day-02-example.txt) diff --git a/libguf/test/data/bartleby.txt b/libguf/test/data/bartleby.txt deleted file mode 100755 index 119a5aa..0000000 --- a/libguf/test/data/bartleby.txt +++ /dev/null @@ -1,1941 +0,0 @@ -The Project Gutenberg eBook of Bartleby, the Scrivener: A Story of Wall-Street - -This ebook is for the use of anyone anywhere in the United States and -most other parts of the world at no cost and with almost no restrictions -whatsoever. You may copy it, give it away or re-use it under the terms -of the Project Gutenberg License included with this ebook or online -at www.gutenberg.org. If you are not located in the United States, -you will have to check the laws of the country where you are located -before using this eBook. - -Title: Bartleby, the Scrivener: A Story of Wall-Street - -Author: Herman Melville - -Release date: February 1, 2004 [eBook #11231] - Most recently updated: October 28, 2024 - -Language: English - -Credits: Steve J. Nelson and Clara T. Nelson - - -*** START OF THE PROJECT GUTENBERG EBOOK BARTLEBY, THE SCRIVENER: A STORY OF WALL-STREET *** -Bartleby, The Scrivener - -A STORY OF WALL-STREET. - -by Herman Melville - - - - -I am a rather elderly man. The nature of my avocations for the last -thirty years has brought me into more than ordinary contact with what -would seem an interesting and somewhat singular set of men, of whom as -yet nothing that I know of has ever been written:—I mean the -law-copyists or scriveners. I have known very many of them, -professionally and privately, and if I pleased, could relate divers -histories, at which good-natured gentlemen might smile, and sentimental -souls might weep. But I waive the biographies of all other scriveners -for a few passages in the life of Bartleby, who was a scrivener of the -strangest I ever saw or heard of. While of other law-copyists I might -write the complete life, of Bartleby nothing of that sort can be done. -I believe that no materials exist for a full and satisfactory biography -of this man. It is an irreparable loss to literature. Bartleby was one -of those beings of whom nothing is ascertainable, except from the -original sources, and in his case those are very small. What my own -astonished eyes saw of Bartleby, _that_ is all I know of him, except, -indeed, one vague report which will appear in the sequel. - -Ere introducing the scrivener, as he first appeared to me, it is fit I -make some mention of myself, my employés, my business, my chambers, and -general surroundings; because some such description is indispensable to -an adequate understanding of the chief character about to be presented. - -Imprimis: I am a man who, from his youth upwards, has been filled with -a profound conviction that the easiest way of life is the best. Hence, -though I belong to a profession proverbially energetic and nervous, -even to turbulence, at times, yet nothing of that sort have I ever -suffered to invade my peace. I am one of those unambitious lawyers who -never addresses a jury, or in any way draws down public applause; but -in the cool tranquility of a snug retreat, do a snug business among -rich men’s bonds and mortgages and title-deeds. All who know me, -consider me an eminently _safe_ man. The late John Jacob Astor, a -personage little given to poetic enthusiasm, had no hesitation in -pronouncing my first grand point to be prudence; my next, method. I do -not speak it in vanity, but simply record the fact, that I was not -unemployed in my profession by the late John Jacob Astor; a name which, -I admit, I love to repeat, for it hath a rounded and orbicular sound to -it, and rings like unto bullion. I will freely add, that I was not -insensible to the late John Jacob Astor’s good opinion. - -Some time prior to the period at which this little history begins, my -avocations had been largely increased. The good old office, now extinct -in the State of New York, of a Master in Chancery, had been conferred -upon me. It was not a very arduous office, but very pleasantly -remunerative. I seldom lose my temper; much more seldom indulge in -dangerous indignation at wrongs and outrages; but I must be permitted -to be rash here and declare, that I consider the sudden and violent -abrogation of the office of Master in Chancery, by the new -Constitution, as a—premature act; inasmuch as I had counted upon a -life-lease of the profits, whereas I only received those of a few short -years. But this is by the way. - -My chambers were up stairs at No.—Wall-street. At one end they looked -upon the white wall of the interior of a spacious sky-light shaft, -penetrating the building from top to bottom. This view might have been -considered rather tame than otherwise, deficient in what landscape -painters call “life.” But if so, the view from the other end of my -chambers offered, at least, a contrast, if nothing more. In that -direction my windows commanded an unobstructed view of a lofty brick -wall, black by age and everlasting shade; which wall required no -spy-glass to bring out its lurking beauties, but for the benefit of all -near-sighted spectators, was pushed up to within ten feet of my window -panes. Owing to the great height of the surrounding buildings, and my -chambers being on the second floor, the interval between this wall and -mine not a little resembled a huge square cistern. - -At the period just preceding the advent of Bartleby, I had two persons -as copyists in my employment, and a promising lad as an office-boy. -First, Turkey; second, Nippers; third, Ginger Nut. These may seem -names, the like of which are not usually found in the Directory. In -truth they were nicknames, mutually conferred upon each other by my -three clerks, and were deemed expressive of their respective persons or -characters. Turkey was a short, pursy Englishman of about my own age, -that is, somewhere not far from sixty. In the morning, one might say, -his face was of a fine florid hue, but after twelve o’clock, -meridian—his dinner hour—it blazed like a grate full of Christmas -coals; and continued blazing—but, as it were, with a gradual wane—till -6 o’clock, P.M. or thereabouts, after which I saw no more of the -proprietor of the face, which gaining its meridian with the sun, seemed -to set with it, to rise, culminate, and decline the following day, with -the like regularity and undiminished glory. There are many singular -coincidences I have known in the course of my life, not the least among -which was the fact, that exactly when Turkey displayed his fullest -beams from his red and radiant countenance, just then, too, at that -critical moment, began the daily period when I considered his business -capacities as seriously disturbed for the remainder of the twenty-four -hours. Not that he was absolutely idle, or averse to business then; far -from it. The difficulty was, he was apt to be altogether too energetic. -There was a strange, inflamed, flurried, flighty recklessness of -activity about him. He would be incautious in dipping his pen into his -inkstand. All his blots upon my documents, were dropped there after -twelve o’clock, meridian. Indeed, not only would he be reckless and -sadly given to making blots in the afternoon, but some days he went -further, and was rather noisy. At such times, too, his face flamed with -augmented blazonry, as if cannel coal had been heaped on anthracite. He -made an unpleasant racket with his chair; spilled his sand-box; in -mending his pens, impatiently split them all to pieces, and threw them -on the floor in a sudden passion; stood up and leaned over his table, -boxing his papers about in a most indecorous manner, very sad to behold -in an elderly man like him. Nevertheless, as he was in many ways a most -valuable person to me, and all the time before twelve o’clock, -meridian, was the quickest, steadiest creature too, accomplishing a -great deal of work in a style not easy to be matched—for these reasons, -I was willing to overlook his eccentricities, though indeed, -occasionally, I remonstrated with him. I did this very gently, however, -because, though the civilest, nay, the blandest and most reverential of -men in the morning, yet in the afternoon he was disposed, upon -provocation, to be slightly rash with his tongue, in fact, insolent. -Now, valuing his morning services as I did, and resolved not to lose -them; yet, at the same time made uncomfortable by his inflamed ways -after twelve o’clock; and being a man of peace, unwilling by my -admonitions to call forth unseemly retorts from him; I took upon me, -one Saturday noon (he was always worse on Saturdays), to hint to him, -very kindly, that perhaps now that he was growing old, it might be well -to abridge his labors; in short, he need not come to my chambers after -twelve o’clock, but, dinner over, had best go home to his lodgings and -rest himself till teatime. But no; he insisted upon his afternoon -devotions. His countenance became intolerably fervid, as he -oratorically assured me—gesticulating with a long ruler at the other -end of the room—that if his services in the morning were useful, how -indispensable, then, in the afternoon? - -“With submission, sir,” said Turkey on this occasion, “I consider -myself your right-hand man. In the morning I but marshal and deploy my -columns; but in the afternoon I put myself at their head, and gallantly -charge the foe, thus!”—and he made a violent thrust with the ruler. - -“But the blots, Turkey,” intimated I. - -“True,—but, with submission, sir, behold these hairs! I am getting old. -Surely, sir, a blot or two of a warm afternoon is not to be severely -urged against gray hairs. Old age—even if it blot the page—is -honorable. With submission, sir, we _both_ are getting old.” - -This appeal to my fellow-feeling was hardly to be resisted. At all -events, I saw that go he would not. So I made up my mind to let him -stay, resolving, nevertheless, to see to it, that during the afternoon -he had to do with my less important papers. - -Nippers, the second on my list, was a whiskered, sallow, and, upon the -whole, rather piratical-looking young man of about five and twenty. I -always deemed him the victim of two evil powers—ambition and -indigestion. The ambition was evinced by a certain impatience of the -duties of a mere copyist, an unwarrantable usurpation of strictly -professional affairs, such as the original drawing up of legal -documents. The indigestion seemed betokened in an occasional nervous -testiness and grinning irritability, causing the teeth to audibly grind -together over mistakes committed in copying; unnecessary maledictions, -hissed, rather than spoken, in the heat of business; and especially by -a continual discontent with the height of the table where he worked. -Though of a very ingenious mechanical turn, Nippers could never get -this table to suit him. He put chips under it, blocks of various sorts, -bits of pasteboard, and at last went so far as to attempt an exquisite -adjustment by final pieces of folded blotting paper. But no invention -would answer. If, for the sake of easing his back, he brought the table -lid at a sharp angle well up towards his chin, and wrote there like a -man using the steep roof of a Dutch house for his desk:—then he -declared that it stopped the circulation in his arms. If now he lowered -the table to his waistbands, and stooped over it in writing, then there -was a sore aching in his back. In short, the truth of the matter was, -Nippers knew not what he wanted. Or, if he wanted any thing, it was to -be rid of a scrivener’s table altogether. Among the manifestations of -his diseased ambition was a fondness he had for receiving visits from -certain ambiguous-looking fellows in seedy coats, whom he called his -clients. Indeed I was aware that not only was he, at times, -considerable of a ward-politician, but he occasionally did a little -business at the Justices’ courts, and was not unknown on the steps of -the Tombs. I have good reason to believe, however, that one individual -who called upon him at my chambers, and who, with a grand air, he -insisted was his client, was no other than a dun, and the alleged -title-deed, a bill. But with all his failings, and the annoyances he -caused me, Nippers, like his compatriot Turkey, was a very useful man -to me; wrote a neat, swift hand; and, when he chose, was not deficient -in a gentlemanly sort of deportment. Added to this, he always dressed -in a gentlemanly sort of way; and so, incidentally, reflected credit -upon my chambers. Whereas with respect to Turkey, I had much ado to -keep him from being a reproach to me. His clothes were apt to look oily -and smell of eating-houses. He wore his pantaloons very loose and baggy -in summer. His coats were execrable; his hat not to be handled. But -while the hat was a thing of indifference to me, inasmuch as his -natural civility and deference, as a dependent Englishman, always led -him to doff it the moment he entered the room, yet his coat was another -matter. Concerning his coats, I reasoned with him; but with no effect. -The truth was, I suppose, that a man of so small an income, could not -afford to sport such a lustrous face and a lustrous coat at one and the -same time. As Nippers once observed, Turkey’s money went chiefly for -red ink. One winter day I presented Turkey with a highly-respectable -looking coat of my own, a padded gray coat, of a most comfortable -warmth, and which buttoned straight up from the knee to the neck. I -thought Turkey would appreciate the favor, and abate his rashness and -obstreperousness of afternoons. But no. I verily believe that buttoning -himself up in so downy and blanket-like a coat had a pernicious effect -upon him; upon the same principle that too much oats are bad for -horses. In fact, precisely as a rash, restive horse is said to feel his -oats, so Turkey felt his coat. It made him insolent. He was a man whom -prosperity harmed. - -Though concerning the self-indulgent habits of Turkey I had my own -private surmises, yet touching Nippers I was well persuaded that -whatever might be his faults in other respects, he was, at least, a -temperate young man. But indeed, nature herself seemed to have been his -vintner, and at his birth charged him so thoroughly with an irritable, -brandy-like disposition, that all subsequent potations were needless. -When I consider how, amid the stillness of my chambers, Nippers would -sometimes impatiently rise from his seat, and stooping over his table, -spread his arms wide apart, seize the whole desk, and move it, and jerk -it, with a grim, grinding motion on the floor, as if the table were a -perverse voluntary agent, intent on thwarting and vexing him; I plainly -perceive that for Nippers, brandy and water were altogether -superfluous. - -It was fortunate for me that, owing to its peculiar -cause—indigestion—the irritability and consequent nervousness of -Nippers, were mainly observable in the morning, while in the afternoon -he was comparatively mild. So that Turkey’s paroxysms only coming on -about twelve o’clock, I never had to do with their eccentricities at -one time. Their fits relieved each other like guards. When Nippers’ was -on, Turkey’s was off; and _vice versa_. This was a good natural -arrangement under the circumstances. - -Ginger Nut, the third on my list, was a lad some twelve years old. His -father was a carman, ambitious of seeing his son on the bench instead -of a cart, before he died. So he sent him to my office as student at -law, errand boy, and cleaner and sweeper, at the rate of one dollar a -week. He had a little desk to himself, but he did not use it much. Upon -inspection, the drawer exhibited a great array of the shells of various -sorts of nuts. Indeed, to this quick-witted youth the whole noble -science of the law was contained in a nut-shell. Not the least among -the employments of Ginger Nut, as well as one which he discharged with -the most alacrity, was his duty as cake and apple purveyor for Turkey -and Nippers. Copying law papers being proverbially dry, husky sort of -business, my two scriveners were fain to moisten their mouths very -often with Spitzenbergs to be had at the numerous stalls nigh the -Custom House and Post Office. Also, they sent Ginger Nut very -frequently for that peculiar cake—small, flat, round, and very -spicy—after which he had been named by them. Of a cold morning when -business was but dull, Turkey would gobble up scores of these cakes, as -if they were mere wafers—indeed they sell them at the rate of six or -eight for a penny—the scrape of his pen blending with the crunching of -the crisp particles in his mouth. Of all the fiery afternoon blunders -and flurried rashnesses of Turkey, was his once moistening a -ginger-cake between his lips, and clapping it on to a mortgage for a -seal. I came within an ace of dismissing him then. But he mollified me -by making an oriental bow, and saying—“With submission, sir, it was -generous of me to find you in stationery on my own account.” - -Now my original business—that of a conveyancer and title hunter, and -drawer-up of recondite documents of all sorts—was considerably -increased by receiving the master’s office. There was now great work -for scriveners. Not only must I push the clerks already with me, but I -must have additional help. In answer to my advertisement, a motionless -young man one morning, stood upon my office threshold, the door being -open, for it was summer. I can see that figure now—pallidly neat, -pitiably respectable, incurably forlorn! It was Bartleby. - -After a few words touching his qualifications, I engaged him, glad to -have among my corps of copyists a man of so singularly sedate an -aspect, which I thought might operate beneficially upon the flighty -temper of Turkey, and the fiery one of Nippers. - -I should have stated before that ground glass folding-doors divided my -premises into two parts, one of which was occupied by my scriveners, -the other by myself. According to my humor I threw open these doors, or -closed them. I resolved to assign Bartleby a corner by the -folding-doors, but on my side of them, so as to have this quiet man -within easy call, in case any trifling thing was to be done. I placed -his desk close up to a small side-window in that part of the room, a -window which originally had afforded a lateral view of certain grimy -back-yards and bricks, but which, owing to subsequent erections, -commanded at present no view at all, though it gave some light. Within -three feet of the panes was a wall, and the light came down from far -above, between two lofty buildings, as from a very small opening in a -dome. Still further to a satisfactory arrangement, I procured a high -green folding screen, which might entirely isolate Bartleby from my -sight, though not remove him from my voice. And thus, in a manner, -privacy and society were conjoined. - -At first Bartleby did an extraordinary quantity of writing. As if long -famishing for something to copy, he seemed to gorge himself on my -documents. There was no pause for digestion. He ran a day and night -line, copying by sun-light and by candle-light. I should have been -quite delighted with his application, had he been cheerfully -industrious. But he wrote on silently, palely, mechanically. - -It is, of course, an indispensable part of a scrivener’s business to -verify the accuracy of his copy, word by word. Where there are two or -more scriveners in an office, they assist each other in this -examination, one reading from the copy, the other holding the original. -It is a very dull, wearisome, and lethargic affair. I can readily -imagine that to some sanguine temperaments it would be altogether -intolerable. For example, I cannot credit that the mettlesome poet -Byron would have contentedly sat down with Bartleby to examine a law -document of, say five hundred pages, closely written in a crimpy hand. - -Now and then, in the haste of business, it had been my habit to assist -in comparing some brief document myself, calling Turkey or Nippers for -this purpose. One object I had in placing Bartleby so handy to me -behind the screen, was to avail myself of his services on such trivial -occasions. It was on the third day, I think, of his being with me, and -before any necessity had arisen for having his own writing examined, -that, being much hurried to complete a small affair I had in hand, I -abruptly called to Bartleby. In my haste and natural expectancy of -instant compliance, I sat with my head bent over the original on my -desk, and my right hand sideways, and somewhat nervously extended with -the copy, so that immediately upon emerging from his retreat, Bartleby -might snatch it and proceed to business without the least delay. - -In this very attitude did I sit when I called to him, rapidly stating -what it was I wanted him to do—namely, to examine a small paper with -me. Imagine my surprise, nay, my consternation, when without moving -from his privacy, Bartleby in a singularly mild, firm voice, replied, -“I would prefer not to.” - -I sat awhile in perfect silence, rallying my stunned faculties. -Immediately it occurred to me that my ears had deceived me, or Bartleby -had entirely misunderstood my meaning. I repeated my request in the -clearest tone I could assume. But in quite as clear a one came the -previous reply, “I would prefer not to.” - -“Prefer not to,” echoed I, rising in high excitement, and crossing the -room with a stride. “What do you mean? Are you moon-struck? I want you -to help me compare this sheet here—take it,” and I thrust it towards -him. - -“I would prefer not to,” said he. - -I looked at him steadfastly. His face was leanly composed; his gray eye -dimly calm. Not a wrinkle of agitation rippled him. Had there been the -least uneasiness, anger, impatience or impertinence in his manner; in -other words, had there been any thing ordinarily human about him, -doubtless I should have violently dismissed him from the premises. But -as it was, I should have as soon thought of turning my pale -plaster-of-paris bust of Cicero out of doors. I stood gazing at him -awhile, as he went on with his own writing, and then reseated myself at -my desk. This is very strange, thought I. What had one best do? But my -business hurried me. I concluded to forget the matter for the present, -reserving it for my future leisure. So calling Nippers from the other -room, the paper was speedily examined. - -A few days after this, Bartleby concluded four lengthy documents, being -quadruplicates of a week’s testimony taken before me in my High Court -of Chancery. It became necessary to examine them. It was an important -suit, and great accuracy was imperative. Having all things arranged I -called Turkey, Nippers and Ginger Nut from the next room, meaning to -place the four copies in the hands of my four clerks, while I should -read from the original. Accordingly Turkey, Nippers and Ginger Nut had -taken their seats in a row, each with his document in hand, when I -called to Bartleby to join this interesting group. - -“Bartleby! quick, I am waiting.” - -I heard a slow scrape of his chair legs on the uncarpeted floor, and -soon he appeared standing at the entrance of his hermitage. - -“What is wanted?” said he mildly. - -“The copies, the copies,” said I hurriedly. “We are going to examine -them. There”—and I held towards him the fourth quadruplicate. - -“I would prefer not to,” he said, and gently disappeared behind the -screen. - -For a few moments I was turned into a pillar of salt, standing at the -head of my seated column of clerks. Recovering myself, I advanced -towards the screen, and demanded the reason for such extraordinary -conduct. - -“_Why_ do you refuse?” - -“I would prefer not to.” - -With any other man I should have flown outright into a dreadful -passion, scorned all further words, and thrust him ignominiously from -my presence. But there was something about Bartleby that not only -strangely disarmed me, but in a wonderful manner touched and -disconcerted me. I began to reason with him. - -“These are your own copies we are about to examine. It is labor saving -to you, because one examination will answer for your four papers. It is -common usage. Every copyist is bound to help examine his copy. Is it -not so? Will you not speak? Answer!” - -“I prefer not to,” he replied in a flute-like tone. It seemed to me -that while I had been addressing him, he carefully revolved every -statement that I made; fully comprehended the meaning; could not -gainsay the irresistible conclusions; but, at the same time, some -paramount consideration prevailed with him to reply as he did. - -“You are decided, then, not to comply with my request—a request made -according to common usage and common sense?” - -He briefly gave me to understand that on that point my judgment was -sound. Yes: his decision was irreversible. - -It is not seldom the case that when a man is browbeaten in some -unprecedented and violently unreasonable way, he begins to stagger in -his own plainest faith. He begins, as it were, vaguely to surmise that, -wonderful as it may be, all the justice and all the reason is on the -other side. Accordingly, if any disinterested persons are present, he -turns to them for some reinforcement for his own faltering mind. - -“Turkey,” said I, “what do you think of this? Am I not right?” - -“With submission, sir,” said Turkey, with his blandest tone, “I think -that you are.” - -“Nippers,” said I, “what do _you_ think of it?” - -“I think I should kick him out of the office.” - -(The reader of nice perceptions will here perceive that, it being -morning, Turkey’s answer is couched in polite and tranquil terms, but -Nippers replies in ill-tempered ones. Or, to repeat a previous -sentence, Nippers’ ugly mood was on duty and Turkey’s off.) - -“Ginger Nut,” said I, willing to enlist the smallest suffrage in my -behalf, “what do you think of it?” - -“I think, sir, he’s a little _luny_,” replied Ginger Nut with a grin. - -“You hear what they say,” said I, turning towards the screen, “come -forth and do your duty.” - -But he vouchsafed no reply. I pondered a moment in sore perplexity. But -once more business hurried me. I determined again to postpone the -consideration of this dilemma to my future leisure. With a little -trouble we made out to examine the papers without Bartleby, though at -every page or two, Turkey deferentially dropped his opinion that this -proceeding was quite out of the common; while Nippers, twitching in his -chair with a dyspeptic nervousness, ground out between his set teeth -occasional hissing maledictions against the stubborn oaf behind the -screen. And for his (Nippers’) part, this was the first and the last -time he would do another man’s business without pay. - -Meanwhile Bartleby sat in his hermitage, oblivious to every thing but -his own peculiar business there. - -Some days passed, the scrivener being employed upon another lengthy -work. His late remarkable conduct led me to regard his ways narrowly. I -observed that he never went to dinner; indeed that he never went any -where. As yet I had never of my personal knowledge known him to be -outside of my office. He was a perpetual sentry in the corner. At about -eleven o’clock though, in the morning, I noticed that Ginger Nut would -advance toward the opening in Bartleby’s screen, as if silently -beckoned thither by a gesture invisible to me where I sat. The boy -would then leave the office jingling a few pence, and reappear with a -handful of ginger-nuts which he delivered in the hermitage, receiving -two of the cakes for his trouble. - -He lives, then, on ginger-nuts, thought I; never eats a dinner, -properly speaking; he must be a vegetarian then; but no; he never eats -even vegetables, he eats nothing but ginger-nuts. My mind then ran on -in reveries concerning the probable effects upon the human constitution -of living entirely on ginger-nuts. Ginger-nuts are so called because -they contain ginger as one of their peculiar constituents, and the -final flavoring one. Now what was ginger? A hot, spicy thing. Was -Bartleby hot and spicy? Not at all. Ginger, then, had no effect upon -Bartleby. Probably he preferred it should have none. - -Nothing so aggravates an earnest person as a passive resistance. If the -individual so resisted be of a not inhumane temper, and the resisting -one perfectly harmless in his passivity; then, in the better moods of -the former, he will endeavor charitably to construe to his imagination -what proves impossible to be solved by his judgment. Even so, for the -most part, I regarded Bartleby and his ways. Poor fellow! thought I, he -means no mischief; it is plain he intends no insolence; his aspect -sufficiently evinces that his eccentricities are involuntary. He is -useful to me. I can get along with him. If I turn him away, the chances -are he will fall in with some less indulgent employer, and then he will -be rudely treated, and perhaps driven forth miserably to starve. Yes. -Here I can cheaply purchase a delicious self-approval. To befriend -Bartleby; to humor him in his strange willfulness, will cost me little -or nothing, while I lay up in my soul what will eventually prove a -sweet morsel for my conscience. But this mood was not invariable with -me. The passiveness of Bartleby sometimes irritated me. I felt -strangely goaded on to encounter him in new opposition, to elicit some -angry spark from him answerable to my own. But indeed I might as well -have essayed to strike fire with my knuckles against a bit of Windsor -soap. But one afternoon the evil impulse in me mastered me, and the -following little scene ensued: - -“Bartleby,” said I, “when those papers are all copied, I will compare -them with you.” - -“I would prefer not to.” - -“How? Surely you do not mean to persist in that mulish vagary?” - -No answer. - -I threw open the folding-doors near by, and turning upon Turkey and -Nippers, exclaimed in an excited manner— - -“He says, a second time, he won’t examine his papers. What do you think -of it, Turkey?” - -It was afternoon, be it remembered. Turkey sat glowing like a brass -boiler, his bald head steaming, his hands reeling among his blotted -papers. - -“Think of it?” roared Turkey; “I think I’ll just step behind his -screen, and black his eyes for him!” - -So saying, Turkey rose to his feet and threw his arms into a pugilistic -position. He was hurrying away to make good his promise, when I -detained him, alarmed at the effect of incautiously rousing Turkey’s -combativeness after dinner. - -“Sit down, Turkey,” said I, “and hear what Nippers has to say. What do -you think of it, Nippers? Would I not be justified in immediately -dismissing Bartleby?” - -“Excuse me, that is for you to decide, sir. I think his conduct quite -unusual, and indeed unjust, as regards Turkey and myself. But it may -only be a passing whim.” - -“Ah,” exclaimed I, “you have strangely changed your mind then—you speak -very gently of him now.” - -“All beer,” cried Turkey; “gentleness is effects of beer—Nippers and I -dined together to-day. You see how gentle _I_ am, sir. Shall I go and -black his eyes?” - -“You refer to Bartleby, I suppose. No, not to-day, Turkey,” I replied; -“pray, put up your fists.” - -I closed the doors, and again advanced towards Bartleby. I felt -additional incentives tempting me to my fate. I burned to be rebelled -against again. I remembered that Bartleby never left the office. - -“Bartleby,” said I, “Ginger Nut is away; just step round to the Post -Office, won’t you? (it was but a three minute walk,) and see if there -is any thing for me.” - -“I would prefer not to.” - -“You _will_ not?” - -“I _prefer_ not.” - -I staggered to my desk, and sat there in a deep study. My blind -inveteracy returned. Was there any other thing in which I could procure -myself to be ignominiously repulsed by this lean, penniless wight?—my -hired clerk? What added thing is there, perfectly reasonable, that he -will be sure to refuse to do? - -“Bartleby!” - -No answer. - -“Bartleby,” in a louder tone. - -No answer. - -“Bartleby,” I roared. - -Like a very ghost, agreeably to the laws of magical invocation, at the -third summons, he appeared at the entrance of his hermitage. - -“Go to the next room, and tell Nippers to come to me.” - -“I prefer not to,” he respectfully and slowly said, and mildly -disappeared. - -“Very good, Bartleby,” said I, in a quiet sort of serenely severe -self-possessed tone, intimating the unalterable purpose of some -terrible retribution very close at hand. At the moment I half intended -something of the kind. But upon the whole, as it was drawing towards my -dinner-hour, I thought it best to put on my hat and walk home for the -day, suffering much from perplexity and distress of mind. - -Shall I acknowledge it? The conclusion of this whole business was, that -it soon became a fixed fact of my chambers, that a pale young -scrivener, by the name of Bartleby, and a desk there; that he copied -for me at the usual rate of four cents a folio (one hundred words); but -he was permanently exempt from examining the work done by him, that -duty being transferred to Turkey and Nippers, one of compliment -doubtless to their superior acuteness; moreover, said Bartleby was -never on any account to be dispatched on the most trivial errand of any -sort; and that even if entreated to take upon him such a matter, it was -generally understood that he would prefer not to—in other words, that -he would refuse pointblank. - -As days passed on, I became considerably reconciled to Bartleby. His -steadiness, his freedom from all dissipation, his incessant industry -(except when he chose to throw himself into a standing revery behind -his screen), his great stillness, his unalterableness of demeanor under -all circumstances, made him a valuable acquisition. One prime thing was -this,—_he was always there;_—first in the morning, continually through -the day, and the last at night. I had a singular confidence in his -honesty. I felt my most precious papers perfectly safe in his hands. -Sometimes to be sure I could not, for the very soul of me, avoid -falling into sudden spasmodic passions with him. For it was exceeding -difficult to bear in mind all the time those strange peculiarities, -privileges, and unheard of exemptions, forming the tacit stipulations -on Bartleby’s part under which he remained in my office. Now and then, -in the eagerness of dispatching pressing business, I would -inadvertently summon Bartleby, in a short, rapid tone, to put his -finger, say, on the incipient tie of a bit of red tape with which I was -about compressing some papers. Of course, from behind the screen the -usual answer, “I prefer not to,” was sure to come; and then, how could -a human creature with the common infirmities of our nature, refrain -from bitterly exclaiming upon such perverseness—such unreasonableness. -However, every added repulse of this sort which I received only tended -to lessen the probability of my repeating the inadvertence. - -Here it must be said, that according to the custom of most legal -gentlemen occupying chambers in densely-populated law buildings, there -were several keys to my door. One was kept by a woman residing in the -attic, which person weekly scrubbed and daily swept and dusted my -apartments. Another was kept by Turkey for convenience sake. The third -I sometimes carried in my own pocket. The fourth I knew not who had. - -Now, one Sunday morning I happened to go to Trinity Church, to hear a -celebrated preacher, and finding myself rather early on the ground, I -thought I would walk around to my chambers for a while. Luckily I had -my key with me; but upon applying it to the lock, I found it resisted -by something inserted from the inside. Quite surprised, I called out; -when to my consternation a key was turned from within; and thrusting -his lean visage at me, and holding the door ajar, the apparition of -Bartleby appeared, in his shirt sleeves, and otherwise in a strangely -tattered dishabille, saying quietly that he was sorry, but he was -deeply engaged just then, and—preferred not admitting me at present. In -a brief word or two, he moreover added, that perhaps I had better walk -round the block two or three times, and by that time he would probably -have concluded his affairs. - -Now, the utterly unsurmised appearance of Bartleby, tenanting my -law-chambers of a Sunday morning, with his cadaverously gentlemanly -_nonchalance_, yet withal firm and self-possessed, had such a strange -effect upon me, that incontinently I slunk away from my own door, and -did as desired. But not without sundry twinges of impotent rebellion -against the mild effrontery of this unaccountable scrivener. Indeed, it -was his wonderful mildness chiefly, which not only disarmed me, but -unmanned me, as it were. For I consider that one, for the time, is a -sort of unmanned when he tranquilly permits his hired clerk to dictate -to him, and order him away from his own premises. Furthermore, I was -full of uneasiness as to what Bartleby could possibly be doing in my -office in his shirt sleeves, and in an otherwise dismantled condition -of a Sunday morning. Was any thing amiss going on? Nay, that was out of -the question. It was not to be thought of for a moment that Bartleby -was an immoral person. But what could he be doing there?—copying? Nay -again, whatever might be his eccentricities, Bartleby was an eminently -decorous person. He would be the last man to sit down to his desk in -any state approaching to nudity. Besides, it was Sunday; and there was -something about Bartleby that forbade the supposition that he would by -any secular occupation violate the proprieties of the day. - -Nevertheless, my mind was not pacified; and full of a restless -curiosity, at last I returned to the door. Without hindrance I inserted -my key, opened it, and entered. Bartleby was not to be seen. I looked -round anxiously, peeped behind his screen; but it was very plain that -he was gone. Upon more closely examining the place, I surmised that for -an indefinite period Bartleby must have ate, dressed, and slept in my -office, and that too without plate, mirror, or bed. The cushioned seat -of a rickety old sofa in one corner bore the faint impress of a lean, -reclining form. Rolled away under his desk, I found a blanket; under -the empty grate, a blacking box and brush; on a chair, a tin basin, -with soap and a ragged towel; in a newspaper a few crumbs of -ginger-nuts and a morsel of cheese. Yes, thought I, it is evident -enough that Bartleby has been making his home here, keeping bachelor’s -hall all by himself. Immediately then the thought came sweeping across -me, What miserable friendlessness and loneliness are here revealed! His -poverty is great; but his solitude, how horrible! Think of it. Of a -Sunday, Wall-street is deserted as Petra; and every night of every day -it is an emptiness. This building too, which of week-days hums with -industry and life, at nightfall echoes with sheer vacancy, and all -through Sunday is forlorn. And here Bartleby makes his home; sole -spectator of a solitude which he has seen all populous—a sort of -innocent and transformed Marius brooding among the ruins of Carthage! - -For the first time in my life a feeling of overpowering stinging -melancholy seized me. Before, I had never experienced aught but a -not-unpleasing sadness. The bond of a common humanity now drew me -irresistibly to gloom. A fraternal melancholy! For both I and Bartleby -were sons of Adam. I remembered the bright silks and sparkling faces I -had seen that day, in gala trim, swan-like sailing down the Mississippi -of Broadway; and I contrasted them with the pallid copyist, and thought -to myself, Ah, happiness courts the light, so we deem the world is gay; -but misery hides aloof, so we deem that misery there is none. These sad -fancyings—chimeras, doubtless, of a sick and silly brain—led on to -other and more special thoughts, concerning the eccentricities of -Bartleby. Presentiments of strange discoveries hovered round me. The -scrivener’s pale form appeared to me laid out, among uncaring -strangers, in its shivering winding sheet. - -Suddenly I was attracted by Bartleby’s closed desk, the key in open -sight left in the lock. - -I mean no mischief, seek the gratification of no heartless curiosity, -thought I; besides, the desk is mine, and its contents too, so I will -make bold to look within. Every thing was methodically arranged, the -papers smoothly placed. The pigeon holes were deep, and removing the -files of documents, I groped into their recesses. Presently I felt -something there, and dragged it out. It was an old bandanna -handkerchief, heavy and knotted. I opened it, and saw it was a savings’ -bank. - -I now recalled all the quiet mysteries which I had noted in the man. I -remembered that he never spoke but to answer; that though at intervals -he had considerable time to himself, yet I had never seen him -reading—no, not even a newspaper; that for long periods he would stand -looking out, at his pale window behind the screen, upon the dead brick -wall; I was quite sure he never visited any refectory or eating house; -while his pale face clearly indicated that he never drank beer like -Turkey, or tea and coffee even, like other men; that he never went any -where in particular that I could learn; never went out for a walk, -unless indeed that was the case at present; that he had declined -telling who he was, or whence he came, or whether he had any relatives -in the world; that though so thin and pale, he never complained of ill -health. And more than all, I remembered a certain unconscious air of -pallid—how shall I call it?—of pallid haughtiness, say, or rather an -austere reserve about him, which had positively awed me into my tame -compliance with his eccentricities, when I had feared to ask him to do -the slightest incidental thing for me, even though I might know, from -his long-continued motionlessness, that behind his screen he must be -standing in one of those dead-wall reveries of his. - -Revolving all these things, and coupling them with the recently -discovered fact that he made my office his constant abiding place and -home, and not forgetful of his morbid moodiness; revolving all these -things, a prudential feeling began to steal over me. My first emotions -had been those of pure melancholy and sincerest pity; but just in -proportion as the forlornness of Bartleby grew and grew to my -imagination, did that same melancholy merge into fear, that pity into -repulsion. So true it is, and so terrible too, that up to a certain -point the thought or sight of misery enlists our best affections; but, -in certain special cases, beyond that point it does not. They err who -would assert that invariably this is owing to the inherent selfishness -of the human heart. It rather proceeds from a certain hopelessness of -remedying excessive and organic ill. To a sensitive being, pity is not -seldom pain. And when at last it is perceived that such pity cannot -lead to effectual succor, common sense bids the soul rid of it. What I -saw that morning persuaded me that the scrivener was the victim of -innate and incurable disorder. I might give alms to his body; but his -body did not pain him; it was his soul that suffered, and his soul I -could not reach. - -I did not accomplish the purpose of going to Trinity Church that -morning. Somehow, the things I had seen disqualified me for the time -from church-going. I walked homeward, thinking what I would do with -Bartleby. Finally, I resolved upon this;—I would put certain calm -questions to him the next morning, touching his history, etc., and if -he declined to answer them openly and unreservedly (and I supposed he -would prefer not), then to give him a twenty dollar bill over and above -whatever I might owe him, and tell him his services were no longer -required; but that if in any other way I could assist him, I would be -happy to do so, especially if he desired to return to his native place, -wherever that might be, I would willingly help to defray the expenses. -Moreover, if, after reaching home, he found himself at any time in want -of aid, a letter from him would be sure of a reply. - -The next morning came. - -“Bartleby,” said I, gently calling to him behind his screen. - -No reply. - -“Bartleby,” said I, in a still gentler tone, “come here; I am not going -to ask you to do any thing you would prefer not to do—I simply wish to -speak to you.” - -Upon this he noiselessly slid into view. - -“Will you tell me, Bartleby, where you were born?” - -“I would prefer not to.” - -“Will you tell me _any thing_ about yourself?” - -“I would prefer not to.” - -“But what reasonable objection can you have to speak to me? I feel -friendly towards you.” - -He did not look at me while I spoke, but kept his glance fixed upon my -bust of Cicero, which as I then sat, was directly behind me, some six -inches above my head. - -“What is your answer, Bartleby?” said I, after waiting a considerable -time for a reply, during which his countenance remained immovable, only -there was the faintest conceivable tremor of the white attenuated -mouth. - -“At present I prefer to give no answer,” he said, and retired into his -hermitage. - -It was rather weak in me I confess, but his manner on this occasion -nettled me. Not only did there seem to lurk in it a certain calm -disdain, but his perverseness seemed ungrateful, considering the -undeniable good usage and indulgence he had received from me. - -Again I sat ruminating what I should do. Mortified as I was at his -behavior, and resolved as I had been to dismiss him when I entered my -offices, nevertheless I strangely felt something superstitious knocking -at my heart, and forbidding me to carry out my purpose, and denouncing -me for a villain if I dared to breathe one bitter word against this -forlornest of mankind. At last, familiarly drawing my chair behind his -screen, I sat down and said: “Bartleby, never mind then about revealing -your history; but let me entreat you, as a friend, to comply as far as -may be with the usages of this office. Say now you will help to examine -papers to-morrow or next day: in short, say now that in a day or two -you will begin to be a little reasonable:—say so, Bartleby.” - -“At present I would prefer not to be a little reasonable,” was his -mildly cadaverous reply. - -Just then the folding-doors opened, and Nippers approached. He seemed -suffering from an unusually bad night’s rest, induced by severer -indigestion than common. He overheard those final words of Bartleby. - -“_Prefer not_, eh?” gritted Nippers—“I’d _prefer_ him, if I were you, -sir,” addressing me—“I’d _prefer_ him; I’d give him preferences, the -stubborn mule! What is it, sir, pray, that he _prefers_ not to do now?” - -Bartleby moved not a limb. - -“Mr. Nippers,” said I, “I’d prefer that you would withdraw for the -present.” - -Somehow, of late I had got into the way of involuntarily using this -word “prefer” upon all sorts of not exactly suitable occasions. And I -trembled to think that my contact with the scrivener had already and -seriously affected me in a mental way. And what further and deeper -aberration might it not yet produce? This apprehension had not been -without efficacy in determining me to summary means. - -As Nippers, looking very sour and sulky, was departing, Turkey blandly -and deferentially approached. - -“With submission, sir,” said he, “yesterday I was thinking about -Bartleby here, and I think that if he would but prefer to take a quart -of good ale every day, it would do much towards mending him, and -enabling him to assist in examining his papers.” - -“So you have got the word too,” said I, slightly excited. - -“With submission, what word, sir,” asked Turkey, respectfully crowding -himself into the contracted space behind the screen, and by so doing, -making me jostle the scrivener. “What word, sir?” - -“I would prefer to be left alone here,” said Bartleby, as if offended -at being mobbed in his privacy. - -“_That’s_ the word, Turkey,” said I—“that’s it.” - -“Oh, _prefer_? oh yes—queer word. I never use it myself. But, sir, as I -was saying, if he would but prefer—” - -“Turkey,” interrupted I, “you will please withdraw.” - -“Oh certainly, sir, if you prefer that I should.” - -As he opened the folding-door to retire, Nippers at his desk caught a -glimpse of me, and asked whether I would prefer to have a certain paper -copied on blue paper or white. He did not in the least roguishly accent -the word prefer. It was plain that it involuntarily rolled from his -tongue. I thought to myself, surely I must get rid of a demented man, -who already has in some degree turned the tongues, if not the heads of -myself and clerks. But I thought it prudent not to break the dismission -at once. - -The next day I noticed that Bartleby did nothing but stand at his -window in his dead-wall revery. Upon asking him why he did not write, -he said that he had decided upon doing no more writing. - -“Why, how now? what next?” exclaimed I, “do no more writing?” - -“No more.” - -“And what is the reason?” - -“Do you not see the reason for yourself,” he indifferently replied. - -I looked steadfastly at him, and perceived that his eyes looked dull -and glazed. Instantly it occurred to me, that his unexampled diligence -in copying by his dim window for the first few weeks of his stay with -me might have temporarily impaired his vision. - -I was touched. I said something in condolence with him. I hinted that -of course he did wisely in abstaining from writing for a while; and -urged him to embrace that opportunity of taking wholesome exercise in -the open air. This, however, he did not do. A few days after this, my -other clerks being absent, and being in a great hurry to dispatch -certain letters by the mail, I thought that, having nothing else -earthly to do, Bartleby would surely be less inflexible than usual, and -carry these letters to the post-office. But he blankly declined. So, -much to my inconvenience, I went myself. - -Still added days went by. Whether Bartleby’s eyes improved or not, I -could not say. To all appearance, I thought they did. But when I asked -him if they did, he vouchsafed no answer. At all events, he would do no -copying. At last, in reply to my urgings, he informed me that he had -permanently given up copying. - -“What!” exclaimed I; “suppose your eyes should get entirely well—better -than ever before—would you not copy then?” - -“I have given up copying,” he answered, and slid aside. - -He remained as ever, a fixture in my chamber. Nay—if that were -possible—he became still more of a fixture than before. What was to be -done? He would do nothing in the office: why should he stay there? In -plain fact, he had now become a millstone to me, not only useless as a -necklace, but afflictive to bear. Yet I was sorry for him. I speak less -than truth when I say that, on his own account, he occasioned me -uneasiness. If he would but have named a single relative or friend, I -would instantly have written, and urged their taking the poor fellow -away to some convenient retreat. But he seemed alone, absolutely alone -in the universe. A bit of wreck in the mid Atlantic. At length, -necessities connected with my business tyrannized over all other -considerations. Decently as I could, I told Bartleby that in six days’ -time he must unconditionally leave the office. I warned him to take -measures, in the interval, for procuring some other abode. I offered to -assist him in this endeavor, if he himself would but take the first -step towards a removal. “And when you finally quit me, Bartleby,” added -I, “I shall see that you go not away entirely unprovided. Six days from -this hour, remember.” - -At the expiration of that period, I peeped behind the screen, and lo! -Bartleby was there. - -I buttoned up my coat, balanced myself; advanced slowly towards him, -touched his shoulder, and said, “The time has come; you must quit this -place; I am sorry for you; here is money; but you must go.” - -“I would prefer not,” he replied, with his back still towards me. - -“You _must_.” - -He remained silent. - -Now I had an unbounded confidence in this man’s common honesty. He had -frequently restored to me sixpences and shillings carelessly dropped -upon the floor, for I am apt to be very reckless in such shirt-button -affairs. The proceeding then which followed will not be deemed -extraordinary. - -“Bartleby,” said I, “I owe you twelve dollars on account; here are -thirty-two; the odd twenty are yours.—Will you take it?” and I handed -the bills towards him. - -But he made no motion. - -“I will leave them here then,” putting them under a weight on the -table. Then taking my hat and cane and going to the door I tranquilly -turned and added—“After you have removed your things from these -offices, Bartleby, you will of course lock the door—since every one is -now gone for the day but you—and if you please, slip your key -underneath the mat, so that I may have it in the morning. I shall not -see you again; so good-bye to you. If hereafter in your new place of -abode I can be of any service to you, do not fail to advise me by -letter. Good-bye, Bartleby, and fare you well.” - -But he answered not a word; like the last column of some ruined temple, -he remained standing mute and solitary in the middle of the otherwise -deserted room. - -As I walked home in a pensive mood, my vanity got the better of my -pity. I could not but highly plume myself on my masterly management in -getting rid of Bartleby. Masterly I call it, and such it must appear to -any dispassionate thinker. The beauty of my procedure seemed to consist -in its perfect quietness. There was no vulgar bullying, no bravado of -any sort, no choleric hectoring, and striding to and fro across the -apartment, jerking out vehement commands for Bartleby to bundle himself -off with his beggarly traps. Nothing of the kind. Without loudly -bidding Bartleby depart—as an inferior genius might have done—I -_assumed_ the ground that depart he must; and upon that assumption -built all I had to say. The more I thought over my procedure, the more -I was charmed with it. Nevertheless, next morning, upon awakening, I -had my doubts,—I had somehow slept off the fumes of vanity. One of the -coolest and wisest hours a man has, is just after he awakes in the -morning. My procedure seemed as sagacious as ever.—but only in theory. -How it would prove in practice—there was the rub. It was truly a -beautiful thought to have assumed Bartleby’s departure; but, after all, -that assumption was simply my own, and none of Bartleby’s. The great -point was, not whether I had assumed that he would quit me, but whether -he would prefer so to do. He was more a man of preferences than -assumptions. - -After breakfast, I walked down town, arguing the probabilities _pro_ -and _con_. One moment I thought it would prove a miserable failure, and -Bartleby would be found all alive at my office as usual; the next -moment it seemed certain that I should see his chair empty. And so I -kept veering about. At the corner of Broadway and Canal-street, I saw -quite an excited group of people standing in earnest conversation. - -“I’ll take odds he doesn’t,” said a voice as I passed. - -“Doesn’t go?—done!” said I, “put up your money.” - -I was instinctively putting my hand in my pocket to produce my own, -when I remembered that this was an election day. The words I had -overheard bore no reference to Bartleby, but to the success or -non-success of some candidate for the mayoralty. In my intent frame of -mind, I had, as it were, imagined that all Broadway shared in my -excitement, and were debating the same question with me. I passed on, -very thankful that the uproar of the street screened my momentary -absent-mindedness. - -As I had intended, I was earlier than usual at my office door. I stood -listening for a moment. All was still. He must be gone. I tried the -knob. The door was locked. Yes, my procedure had worked to a charm; he -indeed must be vanished. Yet a certain melancholy mixed with this: I -was almost sorry for my brilliant success. I was fumbling under the -door mat for the key, which Bartleby was to have left there for me, -when accidentally my knee knocked against a panel, producing a -summoning sound, and in response a voice came to me from within—“Not -yet; I am occupied.” - -It was Bartleby. - -I was thunderstruck. For an instant I stood like the man who, pipe in -mouth, was killed one cloudless afternoon long ago in Virginia, by a -summer lightning; at his own warm open window he was killed, and -remained leaning out there upon the dreamy afternoon, till some one -touched him, when he fell. - -“Not gone!” I murmured at last. But again obeying that wondrous -ascendancy which the inscrutable scrivener had over me, and from which -ascendancy, for all my chafing, I could not completely escape, I slowly -went down stairs and out into the street, and while walking round the -block, considered what I should next do in this unheard-of perplexity. -Turn the man out by an actual thrusting I could not; to drive him away -by calling him hard names would not do; calling in the police was an -unpleasant idea; and yet, permit him to enjoy his cadaverous triumph -over me,—this too I could not think of. What was to be done? or, if -nothing could be done, was there any thing further that I could -_assume_ in the matter? Yes, as before I had prospectively assumed that -Bartleby would depart, so now I might retrospectively assume that -departed he was. In the legitimate carrying out of this assumption, I -might enter my office in a great hurry, and pretending not to see -Bartleby at all, walk straight against him as if he were air. Such a -proceeding would in a singular degree have the appearance of a -home-thrust. It was hardly possible that Bartleby could withstand such -an application of the doctrine of assumptions. But upon second thoughts -the success of the plan seemed rather dubious. I resolved to argue the -matter over with him again. - -“Bartleby,” said I, entering the office, with a quietly severe -expression, “I am seriously displeased. I am pained, Bartleby. I had -thought better of you. I had imagined you of such a gentlemanly -organization, that in any delicate dilemma a slight hint would have -suffice—in short, an assumption. But it appears I am deceived. Why,” I -added, unaffectedly starting, “you have not even touched that money -yet,” pointing to it, just where I had left it the evening previous. - -He answered nothing. - -“Will you, or will you not, quit me?” I now demanded in a sudden -passion, advancing close to him. - -“I would prefer _not_ to quit you,” he replied, gently emphasizing the -_not_. - -“What earthly right have you to stay here? Do you pay any rent? Do you -pay my taxes? Or is this property yours?” - -He answered nothing. - -“Are you ready to go on and write now? Are your eyes recovered? Could -you copy a small paper for me this morning? or help examine a few -lines? or step round to the post-office? In a word, will you do any -thing at all, to give a coloring to your refusal to depart the -premises?” - -He silently retired into his hermitage. - -I was now in such a state of nervous resentment that I thought it but -prudent to check myself at present from further demonstrations. -Bartleby and I were alone. I remembered the tragedy of the unfortunate -Adams and the still more unfortunate Colt in the solitary office of the -latter; and how poor Colt, being dreadfully incensed by Adams, and -imprudently permitting himself to get wildly excited, was at unawares -hurried into his fatal act—an act which certainly no man could possibly -deplore more than the actor himself. Often it had occurred to me in my -ponderings upon the subject, that had that altercation taken place in -the public street, or at a private residence, it would not have -terminated as it did. It was the circumstance of being alone in a -solitary office, up stairs, of a building entirely unhallowed by -humanizing domestic associations—an uncarpeted office, doubtless, of a -dusty, haggard sort of appearance;—this it must have been, which -greatly helped to enhance the irritable desperation of the hapless -Colt. - -But when this old Adam of resentment rose in me and tempted me -concerning Bartleby, I grappled him and threw him. How? Why, simply by -recalling the divine injunction: “A new commandment give I unto you, -that ye love one another.” Yes, this it was that saved me. Aside from -higher considerations, charity often operates as a vastly wise and -prudent principle—a great safeguard to its possessor. Men have -committed murder for jealousy’s sake, and anger’s sake, and hatred’s -sake, and selfishness’ sake, and spiritual pride’s sake; but no man -that ever I heard of, ever committed a diabolical murder for sweet -charity’s sake. Mere self-interest, then, if no better motive can be -enlisted, should, especially with high-tempered men, prompt all beings -to charity and philanthropy. At any rate, upon the occasion in -question, I strove to drown my exasperated feelings towards the -scrivener by benevolently construing his conduct. Poor fellow, poor -fellow! thought I, he don’t mean any thing; and besides, he has seen -hard times, and ought to be indulged. - -I endeavored also immediately to occupy myself, and at the same time to -comfort my despondency. I tried to fancy that in the course of the -morning, at such time as might prove agreeable to him, Bartleby, of his -own free accord, would emerge from his hermitage, and take up some -decided line of march in the direction of the door. But no. Half-past -twelve o’clock came; Turkey began to glow in the face, overturn his -inkstand, and become generally obstreperous; Nippers abated down into -quietude and courtesy; Ginger Nut munched his noon apple; and Bartleby -remained standing at his window in one of his profoundest dead-wall -reveries. Will it be credited? Ought I to acknowledge it? That -afternoon I left the office without saying one further word to him. - -Some days now passed, during which, at leisure intervals I looked a -little into “Edwards on the Will,” and “Priestly on Necessity.” Under -the circumstances, those books induced a salutary feeling. Gradually I -slid into the persuasion that these troubles of mine touching the -scrivener, had been all predestinated from eternity, and Bartleby was -billeted upon me for some mysterious purpose of an all-wise Providence, -which it was not for a mere mortal like me to fathom. Yes, Bartleby, -stay there behind your screen, thought I; I shall persecute you no -more; you are harmless and noiseless as any of these old chairs; in -short, I never feel so private as when I know you are here. At last I -see it, I feel it; I penetrate to the predestinated purpose of my life. -I am content. Others may have loftier parts to enact; but my mission in -this world, Bartleby, is to furnish you with office-room for such -period as you may see fit to remain. - -I believe that this wise and blessed frame of mind would have continued -with me, had it not been for the unsolicited and uncharitable remarks -obtruded upon me by my professional friends who visited the rooms. But -thus it often is, that the constant friction of illiberal minds wears -out at last the best resolves of the more generous. Though to be sure, -when I reflected upon it, it was not strange that people entering my -office should be struck by the peculiar aspect of the unaccountable -Bartleby, and so be tempted to throw out some sinister observations -concerning him. Sometimes an attorney having business with me, and -calling at my office and finding no one but the scrivener there, would -undertake to obtain some sort of precise information from him touching -my whereabouts; but without heeding his idle talk, Bartleby would -remain standing immovable in the middle of the room. So after -contemplating him in that position for a time, the attorney would -depart, no wiser than he came. - -Also, when a Reference was going on, and the room full of lawyers and -witnesses and business was driving fast; some deeply occupied legal -gentleman present, seeing Bartleby wholly unemployed, would request him -to run round to his (the legal gentleman’s) office and fetch some -papers for him. Thereupon, Bartleby would tranquilly decline, and yet -remain idle as before. Then the lawyer would give a great stare, and -turn to me. And what could I say? At last I was made aware that all -through the circle of my professional acquaintance, a whisper of wonder -was running round, having reference to the strange creature I kept at -my office. This worried me very much. And as the idea came upon me of -his possibly turning out a long-lived man, and keep occupying my -chambers, and denying my authority; and perplexing my visitors; and -scandalizing my professional reputation; and casting a general gloom -over the premises; keeping soul and body together to the last upon his -savings (for doubtless he spent but half a dime a day), and in the end -perhaps outlive me, and claim possession of my office by right of his -perpetual occupancy: as all these dark anticipations crowded upon me -more and more, and my friends continually intruded their relentless -remarks upon the apparition in my room; a great change was wrought in -me. I resolved to gather all my faculties together, and for ever rid me -of this intolerable incubus. - -Ere revolving any complicated project, however, adapted to this end, I -first simply suggested to Bartleby the propriety of his permanent -departure. In a calm and serious tone, I commended the idea to his -careful and mature consideration. But having taken three days to -meditate upon it, he apprised me that his original determination -remained the same; in short, that he still preferred to abide with me. - -What shall I do? I now said to myself, buttoning up my coat to the last -button. What shall I do? what ought I to do? what does conscience say I -_should_ do with this man, or rather ghost. Rid myself of him, I must; -go, he shall. But how? You will not thrust him, the poor, pale, passive -mortal,—you will not thrust such a helpless creature out of your door? -you will not dishonor yourself by such cruelty? No, I will not, I -cannot do that. Rather would I let him live and die here, and then -mason up his remains in the wall. What then will you do? For all your -coaxing, he will not budge. Bribes he leaves under your own paperweight -on your table; in short, it is quite plain that he prefers to cling to -you. - -Then something severe, something unusual must be done. What! surely you -will not have him collared by a constable, and commit his innocent -pallor to the common jail? And upon what ground could you procure such -a thing to be done?—a vagrant, is he? What! he a vagrant, a wanderer, -who refuses to budge? It is because he will _not_ be a vagrant, then, -that you seek to count him _as_ a vagrant. That is too absurd. No -visible means of support: there I have him. Wrong again: for -indubitably he _does_ support himself, and that is the only -unanswerable proof that any man can show of his possessing the means so -to do. No more then. Since he will not quit me, I must quit him. I will -change my offices; I will move elsewhere; and give him fair notice, -that if I find him on my new premises I will then proceed against him -as a common trespasser. - -Acting accordingly, next day I thus addressed him: “I find these -chambers too far from the City Hall; the air is unwholesome. In a word, -I propose to remove my offices next week, and shall no longer require -your services. I tell you this now, in order that you may seek another -place.” - -He made no reply, and nothing more was said. - -On the appointed day I engaged carts and men, proceeded to my chambers, -and having but little furniture, every thing was removed in a few -hours. Throughout, the scrivener remained standing behind the screen, -which I directed to be removed the last thing. It was withdrawn; and -being folded up like a huge folio, left him the motionless occupant of -a naked room. I stood in the entry watching him a moment, while -something from within me upbraided me. - -I re-entered, with my hand in my pocket—and—and my heart in my mouth. - -“Good-bye, Bartleby; I am going—good-bye, and God some way bless you; -and take that,” slipping something in his hand. But it dropped upon the -floor, and then,—strange to say—I tore myself from him whom I had so -longed to be rid of. - -Established in my new quarters, for a day or two I kept the door -locked, and started at every footfall in the passages. When I returned -to my rooms after any little absence, I would pause at the threshold -for an instant, and attentively listen, ere applying my key. But these -fears were needless. Bartleby never came nigh me. - -I thought all was going well, when a perturbed looking stranger visited -me, inquiring whether I was the person who had recently occupied rooms -at No.—Wall-street. - -Full of forebodings, I replied that I was. - -“Then sir,” said the stranger, who proved a lawyer, “you are -responsible for the man you left there. He refuses to do any copying; -he refuses to do any thing; he says he prefers not to; and he refuses -to quit the premises.” - -“I am very sorry, sir,” said I, with assumed tranquility, but an inward -tremor, “but, really, the man you allude to is nothing to me—he is no -relation or apprentice of mine, that you should hold me responsible for -him.” - -“In mercy’s name, who is he?” - -“I certainly cannot inform you. I know nothing about him. Formerly I -employed him as a copyist; but he has done nothing for me now for some -time past.” - -“I shall settle him then,—good morning, sir.” - -Several days passed, and I heard nothing more; and though I often felt -a charitable prompting to call at the place and see poor Bartleby, yet -a certain squeamishness of I know not what withheld me. - -All is over with him, by this time, thought I at last, when through -another week no further intelligence reached me. But coming to my room -the day after, I found several persons waiting at my door in a high -state of nervous excitement. - -“That’s the man—here he comes,” cried the foremost one, whom I -recognized as the lawyer who had previously called upon me alone. - -“You must take him away, sir, at once,” cried a portly person among -them, advancing upon me, and whom I knew to be the landlord of -No.—Wall-street. “These gentlemen, my tenants, cannot stand it any -longer; Mr. B—” pointing to the lawyer, “has turned him out of his -room, and he now persists in haunting the building generally, sitting -upon the banisters of the stairs by day, and sleeping in the entry by -night. Every body is concerned; clients are leaving the offices; some -fears are entertained of a mob; something you must do, and that without -delay.” - -Aghast at this torrent, I fell back before it, and would fain have -locked myself in my new quarters. In vain I persisted that Bartleby was -nothing to me—no more than to any one else. In vain:—I was the last -person known to have any thing to do with him, and they held me to the -terrible account. Fearful then of being exposed in the papers (as one -person present obscurely threatened) I considered the matter, and at -length said, that if the lawyer would give me a confidential interview -with the scrivener, in his (the lawyer’s) own room, I would that -afternoon strive my best to rid them of the nuisance they complained -of. - -Going up stairs to my old haunt, there was Bartleby silently sitting -upon the banister at the landing. - -“What are you doing here, Bartleby?” said I. - -“Sitting upon the banister,” he mildly replied. - -I motioned him into the lawyer’s room, who then left us. - -“Bartleby,” said I, “are you aware that you are the cause of great -tribulation to me, by persisting in occupying the entry after being -dismissed from the office?” - -No answer. - -“Now one of two things must take place. Either you must do something, -or something must be done to you. Now what sort of business would you -like to engage in? Would you like to re-engage in copying for some -one?” - -“No; I would prefer not to make any change.” - -“Would you like a clerkship in a dry-goods store?” - -“There is too much confinement about that. No, I would not like a -clerkship; but I am not particular.” - -“Too much confinement,” I cried, “why you keep yourself confined all -the time!” - -“I would prefer not to take a clerkship,” he rejoined, as if to settle -that little item at once. - -“How would a bar-tender’s business suit you? There is no trying of the -eyesight in that.” - -“I would not like it at all; though, as I said before, I am not -particular.” - -His unwonted wordiness inspirited me. I returned to the charge. - -“Well then, would you like to travel through the country collecting -bills for the merchants? That would improve your health.” - -“No, I would prefer to be doing something else.” - -“How then would going as a companion to Europe, to entertain some young -gentleman with your conversation,—how would that suit you?” - -“Not at all. It does not strike me that there is any thing definite -about that. I like to be stationary. But I am not particular.” - -“Stationary you shall be then,” I cried, now losing all patience, and -for the first time in all my exasperating connection with him fairly -flying into a passion. “If you do not go away from these premises -before night, I shall feel bound—indeed I _am_ bound—to—to—to quit the -premises myself!” I rather absurdly concluded, knowing not with what -possible threat to try to frighten his immobility into compliance. -Despairing of all further efforts, I was precipitately leaving him, -when a final thought occurred to me—one which had not been wholly -unindulged before. - -“Bartleby,” said I, in the kindest tone I could assume under such -exciting circumstances, “will you go home with me now—not to my office, -but my dwelling—and remain there till we can conclude upon some -convenient arrangement for you at our leisure? Come, let us start now, -right away.” - -“No: at present I would prefer not to make any change at all.” - -I answered nothing; but effectually dodging every one by the suddenness -and rapidity of my flight, rushed from the building, ran up Wall-street -towards Broadway, and jumping into the first omnibus was soon removed -from pursuit. As soon as tranquility returned I distinctly perceived -that I had now done all that I possibly could, both in respect to the -demands of the landlord and his tenants, and with regard to my own -desire and sense of duty, to benefit Bartleby, and shield him from rude -persecution. I now strove to be entirely care-free and quiescent; and -my conscience justified me in the attempt; though indeed it was not so -successful as I could have wished. So fearful was I of being again -hunted out by the incensed landlord and his exasperated tenants, that, -surrendering my business to Nippers, for a few days I drove about the -upper part of the town and through the suburbs, in my rockaway; crossed -over to Jersey City and Hoboken, and paid fugitive visits to -Manhattanville and Astoria. In fact I almost lived in my rockaway for -the time. - -When again I entered my office, lo, a note from the landlord lay upon -the desk. I opened it with trembling hands. It informed me that the -writer had sent to the police, and had Bartleby removed to the Tombs as -a vagrant. Moreover, since I knew more about him than any one else, he -wished me to appear at that place, and make a suitable statement of the -facts. These tidings had a conflicting effect upon me. At first I was -indignant; but at last almost approved. The landlord’s energetic, -summary disposition had led him to adopt a procedure which I do not -think I would have decided upon myself; and yet as a last resort, under -such peculiar circumstances, it seemed the only plan. - -As I afterwards learned, the poor scrivener, when told that he must be -conducted to the Tombs, offered not the slightest obstacle, but in his -pale unmoving way, silently acquiesced. - -Some of the compassionate and curious bystanders joined the party; and -headed by one of the constables arm in arm with Bartleby, the silent -procession filed its way through all the noise, and heat, and joy of -the roaring thoroughfares at noon. - -The same day I received the note I went to the Tombs, or to speak more -properly, the Halls of Justice. Seeking the right officer, I stated the -purpose of my call, and was informed that the individual I described -was indeed within. I then assured the functionary that Bartleby was a -perfectly honest man, and greatly to be compassionated, however -unaccountably eccentric. I narrated all I knew, and closed by -suggesting the idea of letting him remain in as indulgent confinement -as possible till something less harsh might be done—though indeed I -hardly knew what. At all events, if nothing else could be decided upon, -the alms-house must receive him. I then begged to have an interview. - -Being under no disgraceful charge, and quite serene and harmless in all -his ways, they had permitted him freely to wander about the prison, and -especially in the inclosed grass-platted yard thereof. And so I found -him there, standing all alone in the quietest of the yards, his face -towards a high wall, while all around, from the narrow slits of the -jail windows, I thought I saw peering out upon him the eyes of -murderers and thieves. - -“Bartleby!” - -“I know you,” he said, without looking round,—“and I want nothing to -say to you.” - -“It was not I that brought you here, Bartleby,” said I, keenly pained -at his implied suspicion. “And to you, this should not be so vile a -place. Nothing reproachful attaches to you by being here. And see, it -is not so sad a place as one might think. Look, there is the sky, and -here is the grass.” - -“I know where I am,” he replied, but would say nothing more, and so I -left him. - -As I entered the corridor again, a broad meat-like man, in an apron, -accosted me, and jerking his thumb over his shoulder said—“Is that your -friend?” - -“Yes.” - -“Does he want to starve? If he does, let him live on the prison fare, -that’s all.” - -“Who are you?” asked I, not knowing what to make of such an -unofficially speaking person in such a place. - -“I am the grub-man. Such gentlemen as have friends here, hire me to -provide them with something good to eat.” - -“Is this so?” said I, turning to the turnkey. - -He said it was. - -“Well then,” said I, slipping some silver into the grub-man’s hands -(for so they called him). “I want you to give particular attention to -my friend there; let him have the best dinner you can get. And you must -be as polite to him as possible.” - -“Introduce me, will you?” said the grub-man, looking at me with an -expression which seemed to say he was all impatience for an opportunity -to give a specimen of his breeding. - -Thinking it would prove of benefit to the scrivener, I acquiesced; and -asking the grub-man his name, went up with him to Bartleby. - -“Bartleby, this is Mr. Cutlets; you will find him very useful to you.” - -“Your sarvant, sir, your sarvant,” said the grub-man, making a low -salutation behind his apron. “Hope you find it pleasant here, -sir;—spacious grounds—cool apartments, sir—hope you’ll stay with us -some time—try to make it agreeable. May Mrs. Cutlets and I have the -pleasure of your company to dinner, sir, in Mrs. Cutlets’ private -room?” - -“I prefer not to dine to-day,” said Bartleby, turning away. “It would -disagree with me; I am unused to dinners.” So saying he slowly moved to -the other side of the inclosure, and took up a position fronting the -dead-wall. - -“How’s this?” said the grub-man, addressing me with a stare of -astonishment. “He’s odd, aint he?” - -“I think he is a little deranged,” said I, sadly. - -“Deranged? deranged is it? Well now, upon my word, I thought that -friend of yourn was a gentleman forger; they are always pale and -genteel-like, them forgers. I can’t pity’em—can’t help it, sir. Did you -know Monroe Edwards?” he added touchingly, and paused. Then, laying his -hand pityingly on my shoulder, sighed, “he died of consumption at -Sing-Sing. So you weren’t acquainted with Monroe?” - -“No, I was never socially acquainted with any forgers. But I cannot -stop longer. Look to my friend yonder. You will not lose by it. I will -see you again.” - -Some few days after this, I again obtained admission to the Tombs, and -went through the corridors in quest of Bartleby; but without finding -him. - -“I saw him coming from his cell not long ago,” said a turnkey, “may be -he’s gone to loiter in the yards.” - -So I went in that direction. - -“Are you looking for the silent man?” said another turnkey passing me. -“Yonder he lies—sleeping in the yard there. ’Tis not twenty minutes -since I saw him lie down.” - -The yard was entirely quiet. It was not accessible to the common -prisoners. The surrounding walls, of amazing thickness, kept off all -sounds behind them. The Egyptian character of the masonry weighed upon -me with its gloom. But a soft imprisoned turf grew under foot. The -heart of the eternal pyramids, it seemed, wherein, by some strange -magic, through the clefts, grass-seed, dropped by birds, had sprung. - -Strangely huddled at the base of the wall, his knees drawn up, and -lying on his side, his head touching the cold stones, I saw the wasted -Bartleby. But nothing stirred. I paused; then went close up to him; -stooped over, and saw that his dim eyes were open; otherwise he seemed -profoundly sleeping. Something prompted me to touch him. I felt his -hand, when a tingling shiver ran up my arm and down my spine to my -feet. - -The round face of the grub-man peered upon me now. “His dinner is -ready. Won’t he dine to-day, either? Or does he live without dining?” - -“Lives without dining,” said I, and closed his eyes. - -“Eh!—He’s asleep, aint he?” - -“With kings and counselors,” murmured I. - - -There would seem little need for proceeding further in this history. -Imagination will readily supply the meager recital of poor Bartleby’s -interment. But ere parting with the reader, let me say, that if this -little narrative has sufficiently interested him, to awaken curiosity -as to who Bartleby was, and what manner of life he led prior to the -present narrator’s making his acquaintance, I can only reply, that in -such curiosity I fully share, but am wholly unable to gratify it. Yet -here I hardly know whether I should divulge one little item of rumor, -which came to my ear a few months after the scrivener’s decease. Upon -what basis it rested, I could never ascertain; and hence, how true it -is I cannot now tell. But inasmuch as this vague report has not been -without certain strange suggestive interest to me, however sad, it may -prove the same with some others; and so I will briefly mention it. The -report was this: that Bartleby had been a subordinate clerk in the Dead -Letter Office at Washington, from which he had been suddenly removed by -a change in the administration. When I think over this rumor, I cannot -adequately express the emotions which seize me. Dead letters! does it -not sound like dead men? Conceive a man by nature and misfortune prone -to a pallid hopelessness, can any business seem more fitted to heighten -it than that of continually handling these dead letters, and assorting -them for the flames? For by the cart-load they are annually burned. -Sometimes from out the folded paper the pale clerk takes a ring:—the -finger it was meant for, perhaps, moulders in the grave; a bank-note -sent in swiftest charity:—he whom it would relieve, nor eats nor -hungers any more; pardon for those who died despairing; hope for those -who died unhoping; good tidings for those who died stifled by -unrelieved calamities. On errands of life, these letters speed to -death. - -Ah Bartleby! Ah humanity! - - - -*** END OF THE PROJECT GUTENBERG EBOOK BARTLEBY, THE SCRIVENER: A STORY OF WALL-STREET *** - - - - -Updated editions will replace the previous one—the old editions will -be renamed. - -Creating the works from print editions not protected by U.S. copyright -law means that no one owns a United States copyright in these works, -so the Foundation (and you!) can copy and distribute it in the United -States without permission and without paying copyright -royalties. Special rules, set forth in the General Terms of Use part -of this license, apply to copying and distributing Project -Gutenberg™ electronic works to protect the PROJECT GUTENBERG™ -concept and trademark. Project Gutenberg is a registered trademark, -and may not be used if you charge for an eBook, except by following -the terms of the trademark license, including paying royalties for use -of the Project Gutenberg trademark. If you do not charge anything for -copies of this eBook, complying with the trademark license is very -easy. You may use this eBook for nearly any purpose such as creation -of derivative works, reports, performances and research. Project -Gutenberg eBooks may be modified and printed and given away—you may -do practically ANYTHING in the United States with eBooks not protected -by U.S. copyright law. Redistribution is subject to the trademark -license, especially commercial redistribution. - - -START: FULL LICENSE - -THE FULL PROJECT GUTENBERG LICENSE - -PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK - -To protect the Project Gutenberg™ mission of promoting the free -distribution of electronic works, by using or distributing this work -(or any other work associated in any way with the phrase “Project -Gutenberg”), you agree to comply with all the terms of the Full -Project Gutenberg™ License available with this file or online at -www.gutenberg.org/license. - -Section 1. General Terms of Use and Redistributing Project Gutenberg™ -electronic works - -1.A. By reading or using any part of this Project Gutenberg™ -electronic work, you indicate that you have read, understand, agree to -and accept all the terms of this license and intellectual property -(trademark/copyright) agreement. If you do not agree to abide by all -the terms of this agreement, you must cease using and return or -destroy all copies of Project Gutenberg™ electronic works in your -possession. If you paid a fee for obtaining a copy of or access to a -Project Gutenberg™ electronic work and you do not agree to be bound -by the terms of this agreement, you may obtain a refund from the person -or entity to whom you paid the fee as set forth in paragraph 1.E.8. - -1.B. “Project Gutenberg” is a registered trademark. It may only be -used on or associated in any way with an electronic work by people who -agree to be bound by the terms of this agreement. There are a few -things that you can do with most Project Gutenberg™ electronic works -even without complying with the full terms of this agreement. See -paragraph 1.C below. There are a lot of things you can do with Project -Gutenberg™ electronic works if you follow the terms of this -agreement and help preserve free future access to Project Gutenberg™ -electronic works. See paragraph 1.E below. - -1.C. The Project Gutenberg Literary Archive Foundation (“the -Foundation” or PGLAF), owns a compilation copyright in the collection -of Project Gutenberg™ electronic works. Nearly all the individual -works in the collection are in the public domain in the United -States. If an individual work is unprotected by copyright law in the -United States and you are located in the United States, we do not -claim a right to prevent you from copying, distributing, performing, -displaying or creating derivative works based on the work as long as -all references to Project Gutenberg are removed. Of course, we hope -that you will support the Project Gutenberg™ mission of promoting -free access to electronic works by freely sharing Project Gutenberg™ -works in compliance with the terms of this agreement for keeping the -Project Gutenberg™ name associated with the work. You can easily -comply with the terms of this agreement by keeping this work in the -same format with its attached full Project Gutenberg™ License when -you share it without charge with others. - -1.D. The copyright laws of the place where you are located also govern -what you can do with this work. Copyright laws in most countries are -in a constant state of change. If you are outside the United States, -check the laws of your country in addition to the terms of this -agreement before downloading, copying, displaying, performing, -distributing or creating derivative works based on this work or any -other Project Gutenberg™ work. The Foundation makes no -representations concerning the copyright status of any work in any -country other than the United States. - -1.E. Unless you have removed all references to Project Gutenberg: - -1.E.1. The following sentence, with active links to, or other -immediate access to, the full Project Gutenberg™ License must appear -prominently whenever any copy of a Project Gutenberg™ work (any work -on which the phrase “Project Gutenberg” appears, or with which the -phrase “Project Gutenberg” is associated) is accessed, displayed, -performed, viewed, copied or distributed: - - This eBook is for the use of anyone anywhere in the United States and most - other parts of the world at no cost and with almost no restrictions - whatsoever. You may copy it, give it away or re-use it under the terms - of the Project Gutenberg License included with this eBook or online - at www.gutenberg.org. If you - are not located in the United States, you will have to check the laws - of the country where you are located before using this eBook. - -1.E.2. If an individual Project Gutenberg™ electronic work is -derived from texts not protected by U.S. copyright law (does not -contain a notice indicating that it is posted with permission of the -copyright holder), the work can be copied and distributed to anyone in -the United States without paying any fees or charges. If you are -redistributing or providing access to a work with the phrase “Project -Gutenberg” associated with or appearing on the work, you must comply -either with the requirements of paragraphs 1.E.1 through 1.E.7 or -obtain permission for the use of the work and the Project Gutenberg™ -trademark as set forth in paragraphs 1.E.8 or 1.E.9. - -1.E.3. If an individual Project Gutenberg™ electronic work is posted -with the permission of the copyright holder, your use and distribution -must comply with both paragraphs 1.E.1 through 1.E.7 and any -additional terms imposed by the copyright holder. Additional terms -will be linked to the Project Gutenberg™ License for all works -posted with the permission of the copyright holder found at the -beginning of this work. - -1.E.4. Do not unlink or detach or remove the full Project Gutenberg™ -License terms from this work, or any files containing a part of this -work or any other work associated with Project Gutenberg™. - -1.E.5. Do not copy, display, perform, distribute or redistribute this -electronic work, or any part of this electronic work, without -prominently displaying the sentence set forth in paragraph 1.E.1 with -active links or immediate access to the full terms of the Project -Gutenberg™ License. - -1.E.6. You may convert to and distribute this work in any binary, -compressed, marked up, nonproprietary or proprietary form, including -any word processing or hypertext form. However, if you provide access -to or distribute copies of a Project Gutenberg™ work in a format -other than “Plain Vanilla ASCII” or other format used in the official -version posted on the official Project Gutenberg™ website -(www.gutenberg.org), you must, at no additional cost, fee or expense -to the user, provide a copy, a means of exporting a copy, or a means -of obtaining a copy upon request, of the work in its original “Plain -Vanilla ASCII” or other form. Any alternate format must include the -full Project Gutenberg™ License as specified in paragraph 1.E.1. - -1.E.7. Do not charge a fee for access to, viewing, displaying, -performing, copying or distributing any Project Gutenberg™ works -unless you comply with paragraph 1.E.8 or 1.E.9. - -1.E.8. You may charge a reasonable fee for copies of or providing -access to or distributing Project Gutenberg™ electronic works -provided that: - - • You pay a royalty fee of 20% of the gross profits you derive from - the use of Project Gutenberg™ works calculated using the method - you already use to calculate your applicable taxes. The fee is owed - to the owner of the Project Gutenberg™ trademark, but he has - agreed to donate royalties under this paragraph to the Project - Gutenberg Literary Archive Foundation. Royalty payments must be paid - within 60 days following each date on which you prepare (or are - legally required to prepare) your periodic tax returns. Royalty - payments should be clearly marked as such and sent to the Project - Gutenberg Literary Archive Foundation at the address specified in - Section 4, “Information about donations to the Project Gutenberg - Literary Archive Foundation.” - - • You provide a full refund of any money paid by a user who notifies - you in writing (or by e-mail) within 30 days of receipt that s/he - does not agree to the terms of the full Project Gutenberg™ - License. You must require such a user to return or destroy all - copies of the works possessed in a physical medium and discontinue - all use of and all access to other copies of Project Gutenberg™ - works. - - • You provide, in accordance with paragraph 1.F.3, a full refund of - any money paid for a work or a replacement copy, if a defect in the - electronic work is discovered and reported to you within 90 days of - receipt of the work. - - • You comply with all other terms of this agreement for free - distribution of Project Gutenberg™ works. - - -1.E.9. If you wish to charge a fee or distribute a Project -Gutenberg™ electronic work or group of works on different terms than -are set forth in this agreement, you must obtain permission in writing -from the Project Gutenberg Literary Archive Foundation, the manager of -the Project Gutenberg™ trademark. Contact the Foundation as set -forth in Section 3 below. - -1.F. - -1.F.1. Project Gutenberg volunteers and employees expend considerable -effort to identify, do copyright research on, transcribe and proofread -works not protected by U.S. copyright law in creating the Project -Gutenberg™ collection. Despite these efforts, Project Gutenberg™ -electronic works, and the medium on which they may be stored, may -contain “Defects,” such as, but not limited to, incomplete, inaccurate -or corrupt data, transcription errors, a copyright or other -intellectual property infringement, a defective or damaged disk or -other medium, a computer virus, or computer codes that damage or -cannot be read by your equipment. - -1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the “Right -of Replacement or Refund” described in paragraph 1.F.3, the Project -Gutenberg Literary Archive Foundation, the owner of the Project -Gutenberg™ trademark, and any other party distributing a Project -Gutenberg™ electronic work under this agreement, disclaim all -liability to you for damages, costs and expenses, including legal -fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT -LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE -PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE FOUNDATION, THE -TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE -LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR -INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH -DAMAGE. - -1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a -defect in this electronic work within 90 days of receiving it, you can -receive a refund of the money (if any) you paid for it by sending a -written explanation to the person you received the work from. If you -received the work on a physical medium, you must return the medium -with your written explanation. The person or entity that provided you -with the defective work may elect to provide a replacement copy in -lieu of a refund. If you received the work electronically, the person -or entity providing it to you may choose to give you a second -opportunity to receive the work electronically in lieu of a refund. If -the second copy is also defective, you may demand a refund in writing -without further opportunities to fix the problem. - -1.F.4. Except for the limited right of replacement or refund set forth -in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO -OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PURPOSE. - -1.F.5. Some states do not allow disclaimers of certain implied -warranties or the exclusion or limitation of certain types of -damages. If any disclaimer or limitation set forth in this agreement -violates the law of the state applicable to this agreement, the -agreement shall be interpreted to make the maximum disclaimer or -limitation permitted by the applicable state law. The invalidity or -unenforceability of any provision of this agreement shall not void the -remaining provisions. - -1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the -trademark owner, any agent or employee of the Foundation, anyone -providing copies of Project Gutenberg™ electronic works in -accordance with this agreement, and any volunteers associated with the -production, promotion and distribution of Project Gutenberg™ -electronic works, harmless from all liability, costs and expenses, -including legal fees, that arise directly or indirectly from any of -the following which you do or cause to occur: (a) distribution of this -or any Project Gutenberg™ work, (b) alteration, modification, or -additions or deletions to any Project Gutenberg™ work, and (c) any -Defect you cause. - -Section 2. Information about the Mission of Project Gutenberg™ - -Project Gutenberg™ is synonymous with the free distribution of -electronic works in formats readable by the widest variety of -computers including obsolete, old, middle-aged and new computers. It -exists because of the efforts of hundreds of volunteers and donations -from people in all walks of life. - -Volunteers and financial support to provide volunteers with the -assistance they need are critical to reaching Project Gutenberg™’s -goals and ensuring that the Project Gutenberg™ collection will -remain freely available for generations to come. In 2001, the Project -Gutenberg Literary Archive Foundation was created to provide a secure -and permanent future for Project Gutenberg™ and future -generations. To learn more about the Project Gutenberg Literary -Archive Foundation and how your efforts and donations can help, see -Sections 3 and 4 and the Foundation information page at www.gutenberg.org. - -Section 3. Information about the Project Gutenberg Literary Archive Foundation - -The Project Gutenberg Literary Archive Foundation is a non-profit -501(c)(3) educational corporation organized under the laws of the -state of Mississippi and granted tax exempt status by the Internal -Revenue Service. The Foundation’s EIN or federal tax identification -number is 64-6221541. Contributions to the Project Gutenberg Literary -Archive Foundation are tax deductible to the full extent permitted by -U.S. federal laws and your state’s laws. - -The Foundation’s business office is located at 809 North 1500 West, -Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up -to date contact information can be found at the Foundation’s website -and official page at www.gutenberg.org/contact - -Section 4. Information about Donations to the Project Gutenberg -Literary Archive Foundation - -Project Gutenberg™ depends upon and cannot survive without widespread -public support and donations to carry out its mission of -increasing the number of public domain and licensed works that can be -freely distributed in machine-readable form accessible by the widest -array of equipment including outdated equipment. Many small donations -($1 to $5,000) are particularly important to maintaining tax exempt -status with the IRS. - -The Foundation is committed to complying with the laws regulating -charities and charitable donations in all 50 states of the United -States. Compliance requirements are not uniform and it takes a -considerable effort, much paperwork and many fees to meet and keep up -with these requirements. We do not solicit donations in locations -where we have not received written confirmation of compliance. To SEND -DONATIONS or determine the status of compliance for any particular state -visit www.gutenberg.org/donate. - -While we cannot and do not solicit contributions from states where we -have not met the solicitation requirements, we know of no prohibition -against accepting unsolicited donations from donors in such states who -approach us with offers to donate. - -International donations are gratefully accepted, but we cannot make -any statements concerning tax treatment of donations received from -outside the United States. U.S. laws alone swamp our small staff. - -Please check the Project Gutenberg web pages for current donation -methods and addresses. Donations are accepted in a number of other -ways including checks, online payments and credit card donations. To -donate, please visit: www.gutenberg.org/donate. - -Section 5. General Information About Project Gutenberg™ electronic works - -Professor Michael S. Hart was the originator of the Project -Gutenberg™ concept of a library of electronic works that could be -freely shared with anyone. For forty years, he produced and -distributed Project Gutenberg™ eBooks with only a loose network of -volunteer support. - -Project Gutenberg™ eBooks are often created from several printed -editions, all of which are confirmed as not protected by copyright in -the U.S. unless a copyright notice is included. Thus, we do not -necessarily keep eBooks in compliance with any particular paper -edition. - -Most people start at our website which has the main PG search -facility: www.gutenberg.org. - -This website includes information about Project Gutenberg™, -including how to make donations to the Project Gutenberg Literary -Archive Foundation, how to help produce our new eBooks, and how to -subscribe to our email newsletter to hear about new eBooks. - - diff --git a/libguf/test/data/utf8-test.txt b/libguf/test/data/utf8-test.txt deleted file mode 100755 index c5e99ce..0000000 --- a/libguf/test/data/utf8-test.txt +++ /dev/null @@ -1,67 +0,0 @@ -„Ich weiß nicht“, rief ich ohne Klang „ich weiß ja nicht. Wenn -niemand kommt, dann kommt eben niemand. Ich habe niemandem etwas -Böses getan, niemand hat mir etwas Böses getan, niemand aber will -mir helfen. Lauter niemand. Aber so ist es doch nicht. Nur daß mir -niemand hilft —, sonst wäre lauter niemand hübsch. Ich würde ganz -gern — warum denn nicht — einen Ausflug mit einer Gesellschaft von -lauter Niemand machen. Natürlich ins Gebirge, wohin denn sonst? Wie -sich diese Niemand aneinander drängen, diese vielen quer gestreckten -und eingehängten Arme, diese vielen Füße, durch winzige Schritte -getrennt! Versteht sich, daß alle in Frack sind. Wir gehen so lala, -der Wind fährt durch die Lücken, die wir und unsere Gliedmaßen offen -lassen. Die Hälse werden im Gebirge frei! Es ist ein Wunder, daß -wir nicht singen.“ - -Det var i den Tid, jeg gik omkring og sulted i Kristiania, denne forunderlige By, -som ingen forlader, før han har fået Mærker af den . . . . -Jeg ligger vågen på min Kvist og hører en Klokke nedenunder mig slå seks Slag; det var allerede ganske lyst, -og Folk begyndte at færdes op og ned i Trapperne. Nede ved Døren, hvor mit Rum var tapetseret med gamle Numre -af »Morgenbladet«, kunde jeg så tydelig se en Bekendtgørelse fra Fyrdirektøren, og lidt tilvenstre derfra et fedt, -bugnende Avertissement fra Bager Fabian Olsen om nybagt Brød. - -The quick brown fox jumps over the lazy dog. - -Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon. - -Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. - -Ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία. - -El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro. - -Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en -canoë au delà des îles, près du mälström où brûlent les novæ. - -D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh. - -Árvíztűrő tükörfúrógép. - -Pchnąć w tę łódź jeża lub ośm skrzyń fig. - -Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa. - -В чащах юга жил бы цитрус? Да, но фальшивый экземпляр! - -Pijamalı hasta, yağız şoföre çabucak güvendi. - -Albert osti fagotin ja töräytti puhkuvan melodian. - -דג סקרן שט בים מאוכזב ולפתע מצא חברה - -نص حكيم له سر قاطع وذو شأن عظيم مكتوب على ثوب أخضر ومغلف بجلد أزرق - -بر اثر چنین تلقین و شستشوی مغزی جامعی، سطح و پایهٔ ذهن و فهم و نظر بعضی اشخاص واژگونه و معکوس می‌شود - -키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다. - -いろはにほへとちりぬるを -わかよたれそつねならむ -うゐのおくやまけふこえて -あさきゆめみしゑひもせす - -イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム -ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン - -ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ -ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ -ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬ diff --git a/libguf/test/example.c b/libguf/test/example.c deleted file mode 100755 index 6fa37b0..0000000 --- a/libguf/test/example.c +++ /dev/null @@ -1,320 +0,0 @@ -#include -#include -#include -#include - -#include "guf_init.h" /* Must be included once (or compiled in a separate .c file and linked) */ - -#define GUF_ALLOC_LIBC_IMPL_STATIC -#include "guf_alloc_libc.h" - -#include "guf_cstr.h" -#include "guf_linalg.h" -#include "guf_utils.h" - -#define GUF_T float -#define GUF_SORT_IMPL_STATIC -#include "guf_sort.h" - -#define GUF_T int -#define GUF_SORT_IMPL_STATIC -#include "guf_sort.h" - -#define GUF_DBUF_NAME dbuf_int -#define GUF_T int -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL_STATIC -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_float -#define GUF_T float -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL_STATIC -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_heap -#define GUF_DBUF_NAME dbuf_heap_cstr -#define GUF_T_COPY guf_cstr_heap_copy -#define GUF_T_MOVE guf_cstr_heap_move -#define GUF_T_FREE guf_cstr_heap_free -#define GUF_T_EQ guf_cstr_heap_eq -#define GUF_DBUF_IMPL_STATIC -// #define GUF_CNT_WITH_ELEM_CTX -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_const -#define GUF_DBUF_NAME dbuf_const_cstr -#define GUF_T_EQ guf_cstr_const_eq -#define GUF_DBUF_IMPL_STATIC -#include "guf_dbuf.h" - -#define GUF_RAND_IMPL_STATIC -// #define GUF_RAND_32_BIT -#include "guf_rand.h" - -#include "impls/dict_impl.h" - -int main(void) -{ - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - guf_alloc_tracker_init(&allocator_ctx.tracker, 1, "example_allocator", NULL, NULL); - allocator_ctx.zero_init = false; - guf_libc_allocator_init(&allocator, &allocator_ctx); - - printf("libguf example: " GUF_PLATFORM_STRING "\n"); - guf_platform_assert_endianness(); - guf_platform_assert_native_word_bits(); - - guf_allocator zero_init_allocator; - guf_libc_alloc_ctx zero_init_allocator_ctx; - guf_alloc_tracker_init(&zero_init_allocator_ctx.tracker, 2, "example_zero_init_allocator", stdout, stderr); - zero_init_allocator_ctx.zero_init = true; - guf_libc_allocator_init(&zero_init_allocator, &zero_init_allocator_ctx); - - dict_cstr_int ht; - dict_cstr_int_init(&ht, &zero_init_allocator); - - dict_cstr_int_insert_val_arg(&ht, "Hello", 42, GUF_CPY_VALUE, GUF_CPY_VALUE); - dict_cstr_int_insert_val_arg(&ht, "World", 64, GUF_CPY_VALUE, GUF_CPY_VALUE); - - int kv_iter = 0; - GUF_CNT_FOREACH(&ht, dict_cstr_int, kv_it) { - printf("%d: %s -> %d\n", kv_iter++, kv_it.ptr->key, kv_it.ptr->val); - } - - guf_cstr_const key = "World"; - int *res = dict_cstr_int_at_val_arg(&ht, "World"); - if (res) { - printf("%s: %d\n", key, *res); - } else { - printf("key '%s' not found\n", key); - } - - GUF_ASSERT(dict_cstr_int_at_val_arg(&ht, "World")); - GUF_ASSERT(dict_cstr_int_at_val_arg(&ht, "Hello")); - GUF_ASSERT(dict_cstr_int_at_val_arg(&ht, "hello") == NULL); - GUF_ASSERT(dict_cstr_int_at_val_arg(&ht, "") == NULL); - - GUF_ASSERT(dict_cstr_int_contains_val_arg(&ht, "World")); - GUF_ASSERT(dict_cstr_int_contains_val_arg(&ht, "Hello")); - - const int ht_needle_val = 64; - const dict_cstr_int_iter ht_it = dict_cstr_int_find_val(&ht, dict_cstr_int_begin(&ht), dict_cstr_int_end(&ht), &ht_needle_val); - - if (!dict_cstr_int_iter_is_end(&ht, ht_it)) { - printf("found value %d (key %s)\n", ht_needle_val, ht_it.ptr->key); - } - - dict_cstr_int_free(&ht, NULL); - - - GUF_CNT_LIFETIME_BLOCK(dbuf_float, floats, { - floats = dbuf_float_new(&allocator); - - for (int i = 0; i <= 16; ++i) { - dbuf_float_push_val(&floats, i % 2 ? (float)i * -2.f : (float)i * 2.f); - } - - // float *tmp = test_allocator.alloc(floats.size * sizeof(float), &test_allocator_ctx); - // float *res = float_arr_merge_sort(floats.data, tmp, floats.size, GUF_SORT_ASCENDING, NULL); - // test_allocator.free(tmp, floats.size * sizeof(float), &test_allocator_ctx); - // GUF_ASSERT_RELEASE(res == floats.data); - - float_arr_qsort(floats.data, floats.size, GUF_SORT_ASCENDING, NULL); - GUF_ASSERT_RELEASE(float_arr_is_sorted(floats.data, floats.size, GUF_SORT_ASCENDING, NULL)); - - GUF_CNT_FOREACH(&floats, dbuf_float, it) { - printf("float: %f\n", (double)*it.ptr); - } - }) - - dbuf_heap_cstr strings = dbuf_heap_cstr_new(&allocator); - dbuf_heap_cstr_push_val_cpy(&strings, "Foo 1"); - dbuf_heap_cstr_push_val_cpy(&strings, "Bar 2"); - char *move_me = guf_cstr_dup("Baz 3"); - dbuf_heap_cstr_push(&strings, &move_me, GUF_CPY_MOVE); - GUF_ASSERT_RELEASE(move_me == NULL); - - dbuf_heap_cstr_push_val_cpy(&strings, "Boz 4"); - - char *findme = "Baz 3"; - dbuf_heap_cstr_iter beg = dbuf_heap_cstr_begin(&strings); - dbuf_heap_cstr_iter end = dbuf_heap_cstr_end(&strings); - dbuf_heap_cstr_iter fnd_it = dbuf_heap_cstr_find(&strings, beg, end, &findme); - if (!dbuf_heap_cstr_iter_is_end(&strings, fnd_it)) { - printf("%s found in range [%td, %td) at idx %td\n", findme, dbuf_heap_cstr_iter_to_idx(&strings, beg), dbuf_heap_cstr_iter_to_idx(&strings, end), dbuf_heap_cstr_iter_to_idx(&strings, fnd_it)); - } else { - printf("%s not found in range [%td, %td) at idx %td\n", findme, dbuf_heap_cstr_iter_to_idx(&strings, beg), dbuf_heap_cstr_iter_to_idx(&strings, end), dbuf_heap_cstr_iter_to_idx(&strings, fnd_it)); - } - - if (dbuf_heap_cstr_contains_val(&strings, "Baz 3")) { - printf("contains\n"); - } else { - printf("does not contain\n"); - } - - GUF_CNT_FOREACH(&strings, dbuf_heap_cstr, it) { - printf("%s\n", *it.ptr); - } - dbuf_heap_cstr_free(&strings, NULL); - - dbuf_const_cstr const_strings = dbuf_const_cstr_new(&allocator); - dbuf_const_cstr_push_val(&const_strings, "Const 1"); - dbuf_const_cstr_push_val(&const_strings, "Const 2"); - const char *foo = "Const 3"; - dbuf_const_cstr_push(&const_strings, &foo, GUF_CPY_VALUE); - - dbuf_const_cstr_iter found_it = dbuf_const_cstr_find(&const_strings, dbuf_const_cstr_begin(&const_strings), dbuf_const_cstr_end(&const_strings), &foo); - if (found_it.ptr != dbuf_const_cstr_end(&const_strings).ptr) { - *found_it.ptr = "Found!"; - } - - GUF_CNT_FOREACH(&const_strings, dbuf_const_cstr, it) { - printf("%s\n", *it.ptr); - } - dbuf_const_cstr_free(&const_strings, NULL); - - dbuf_int integers = dbuf_int_new(&allocator); - dbuf_int_push_val(&integers, 420); - dbuf_int_push_val(&integers, 520); - dbuf_int_push_val(&integers, 620); - dbuf_int_push_val(&integers, 720); - dbuf_int_push_val(&integers, 820); - - guf_err err; - dbuf_int_try_at(&integers, 16, &err); - if (err) { - printf("%s %s\n", guf_err_to_str(err), GUF_ERR_MSG_EMPTY()); - } - - int i = 0; - GUF_DBUF_FOREACH(integers, int, elem) { - printf("elem %d: %d\n", i, *elem); - ++i; - } - - GUF_CNT_FOREACH(&integers, dbuf_int, it) { - printf("it-elem: %d", *it.ptr); - if (dbuf_int_iter_next(&integers, it, 1).ptr != dbuf_int_end(&integers).ptr) { - printf(", it-next: %d", *dbuf_int_iter_next(&integers, it, 1).ptr); - } - if (dbuf_int_iter_next(&integers, it, -1).ptr != dbuf_int_end(&integers).ptr) { - printf(", it-prev: %d", *dbuf_int_iter_next(&integers, it, -1).ptr); - } - printf("\n"); - } - - for (dbuf_int_iter it = dbuf_int_begin(&integers); it.ptr != dbuf_int_end(&integers).ptr; it = dbuf_int_iter_next(&integers, it, 2)) { - printf("every other: %d\n", *it.ptr); - } - - for (dbuf_int_iter it = dbuf_int_rbegin(&integers); it.ptr != dbuf_int_rend(&integers).ptr; it = dbuf_int_iter_next(&integers, it, 1)) { - printf("reverse: %d\n", *it.ptr); - } - - for (dbuf_int_iter it = dbuf_int_rbegin(&integers); it.ptr != dbuf_int_rend(&integers).ptr; it = dbuf_int_iter_next(&integers, it, 2)) { - printf("every other reverse: %d (idx %td)\n", *it.ptr, dbuf_int_iter_to_idx(&integers, it)); - } - - dbuf_int_free(&integers, NULL); - printf("\n"); - guf_randstate rng; - guf_randstate_init(&rng, (guf_rand_seed_t)time(NULL)); - int heads = 0, tails = 0; - int throws = 10; - for (i = 0; i < throws; ++i) { - bool is_head = guf_rand_flip(&rng); - if (is_head) { - puts("head"); - ++heads; - } else { - puts("tail"); - ++tails; - } - } - printf("n: %d\nheads: %d\ntails: %d\n", throws, heads, tails); - - int result[256]; - memset(result, 0, sizeof result); - for (int n = 0; n < 32000; ++n) { - float r = roundf(guf_rand_normal_sample_one_f32(&rng, 100, 15)); - r = guf_clamp_f32(r, 0, 255); - result[(int)r] += 1; - } - for (size_t n = 60; n <= 140; ++n) { - printf("%zu:\t", n); - for (int j = 0; j < result[n] / 8; ++j) { - putc('#', stdout); - } - puts(""); - } - - - for (float angle = 0; angle <= 8.f * GUF_PI_F32; angle += 0.001f) { - guf_quaternion rotq = guf_quaternion_from_axis_angle(angle, guf_vec3_normalised((guf_vec3){-2324234.3f, 1.4f, -1.3f})); - guf_mat4x4 rotmat, rotmat_inv; - guf_mat4x4_init_from_quaternion(&rotmat, rotq); - GUF_ASSERT_RELEASE(guf_mat4x4_inverted(&rotmat, &rotmat_inv)) - - guf_mat4x4_set_trans(&rotmat, (guf_vec3){42.1234f, -512.2f, 3.1415926f}); - GUF_ASSERT_RELEASE(guf_mat4x4_inverted(&rotmat, &rotmat_inv)); - - GUF_ASSERT_RELEASE(guf_mat4x4_inverted(&rotmat_inv, &rotmat)); - GUF_ASSERT_RELEASE(guf_mat4x4_inverted(&rotmat, &rotmat_inv)); - } - - guf_quaternion q = guf_quaternion_from_axis_angle(GUF_PI_F32 / 8.f, guf_vec3_normalised((guf_vec3){0.3f, 10.2f, -25.f})); - - guf_mat4x4 mat; - guf_mat4x4_init_from_quaternion(&mat, q); - guf_mat4x4_set_trans(&mat, (guf_vec3){42.1234f, -512.2f, 3.1415926f}); - - mat.data[2][0] *= 100000.4f; - - const guf_mat4x4 mat_cpy = mat; - - printf("Matrix:\n"); - guf_mat4x4_print_with_precision(&mat, stdout, 8); - - guf_mat4x4 mat_inv; - bool invertible = guf_mat4x4_inverted(&mat, &mat_inv); - if (!invertible) { - printf("Not invertible\n"); - } else { - printf("Inverse:\n"); - guf_mat4x4_print_with_precision(&mat_inv, stdout, 8); - GUF_ASSERT_RELEASE(guf_mat4x4_inverted(&mat_inv, &mat)); - GUF_ASSERT_RELEASE(guf_mat4x4_nearly_equal(&mat, &mat_cpy, 1e-4f, 1e-5f)); - } - - mat = (guf_mat4x4) {.data = { - {1, 1.3f, 1, 1}, - {2, 2.6f, 2, 2}, - {0, 0, 2, 4}, - {0, 0, 0, 1} - }}; - printf("Matrix 2:\n"); - guf_mat4x4_print_with_precision(&mat, stdout, 8); - invertible = guf_mat4x4_inverted(&mat, &mat_inv); - if (!invertible) { - printf("Not invertible\n"); - } else { - printf("Inverse:\n"); - guf_mat4x4_print_with_precision(&mat_inv, stdout, 8); - } - - bool leak = false; - if (guf_alloc_tracker_found_leak(&allocator_ctx.tracker)) { - printf("Found memory leak:\n"); - guf_alloc_tracker_print(&allocator_ctx.tracker, stderr); - leak = true; - } - if (guf_alloc_tracker_found_leak(&zero_init_allocator_ctx.tracker)) { - printf("Found memory leak:\n"); - guf_alloc_tracker_print(&zero_init_allocator_ctx.tracker, stderr); - leak = true; - } - - return leak ? EXIT_FAILURE: EXIT_SUCCESS; -} diff --git a/libguf/test/impls/alloc_libc_impl.c b/libguf/test/impls/alloc_libc_impl.c deleted file mode 100755 index 813fd0e..0000000 --- a/libguf/test/impls/alloc_libc_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_ALLOC_LIBC_IMPL -#include "guf_alloc_libc.h" diff --git a/libguf/test/impls/alloc_tracker_impl.c b/libguf/test/impls/alloc_tracker_impl.c deleted file mode 100755 index 5f41f5a..0000000 --- a/libguf/test/impls/alloc_tracker_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_ALLOC_TRACKER_IMPL -#include "guf_alloc_tracker.h" diff --git a/libguf/test/impls/ckdint_impl.c b/libguf/test/impls/ckdint_impl.c deleted file mode 100755 index 856029d..0000000 --- a/libguf/test/impls/ckdint_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_MATH_CKDINT_IMPL -#include "guf_math_ckdint.h" diff --git a/libguf/test/impls/dbuf_impl.c b/libguf/test/impls/dbuf_impl.c deleted file mode 100755 index c0cf1b8..0000000 --- a/libguf/test/impls/dbuf_impl.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "dbuf_impl.h" - -#define GUF_DBUF_NAME dbuf_int -#define GUF_T int -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_i32 -#define GUF_T int32_t -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_char -#define GUF_T char -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_float -#define GUF_T float -#define GUF_T_IS_INTEGRAL_TYPE -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_heap -#define GUF_DBUF_NAME dbuf_heap_cstr -#define GUF_T_COPY guf_cstr_heap_copy -#define GUF_T_MOVE guf_cstr_heap_move -#define GUF_T_FREE guf_cstr_heap_free -#define GUF_T_EQ guf_cstr_heap_eq -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_const -#define GUF_DBUF_NAME dbuf_const_cstr -#define GUF_T_EQ guf_cstr_const_eq -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_T guf_str_view -#define GUF_DBUF_NAME dbuf_str_view -#define GUF_T_EQ guf_str_view_equal -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" - -#define GUF_T guf_str -#define GUF_DBUF_NAME dbuf_str -#define GUF_T_COPY guf_str_copy -#define GUF_T_MOVE guf_str_move -#define GUF_T_FREE guf_str_free -#define GUF_T_EQ guf_str_equal -#define GUF_DBUF_IMPL -#include "guf_dbuf.h" diff --git a/libguf/test/impls/dbuf_impl.h b/libguf/test/impls/dbuf_impl.h deleted file mode 100755 index 5c6d04a..0000000 --- a/libguf/test/impls/dbuf_impl.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef GUF_DBUF_IMPL_H -#define GUF_DBUF_IMPL_H - -#include "guf_cstr.h" -#include "guf_str.h" - -#define GUF_DBUF_NAME dbuf_int -#define GUF_T int -#define GUF_T_IS_INTEGRAL_TYPE -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_i32 -#define GUF_T int32_t -#define GUF_T_IS_INTEGRAL_TYPE -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_char -#define GUF_T char -#define GUF_T_IS_INTEGRAL_TYPE -#include "guf_dbuf.h" - -#define GUF_DBUF_NAME dbuf_float -#define GUF_T float -#define GUF_T_IS_INTEGRAL_TYPE -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_heap -#define GUF_DBUF_NAME dbuf_heap_cstr -#define GUF_T_COPY guf_cstr_heap_copy -#define GUF_T_MOVE guf_cstr_heap_move -#define GUF_T_FREE guf_cstr_heap_free -#define GUF_T_EQ guf_cstr_heap_eq -#include "guf_dbuf.h" - -#define GUF_T guf_cstr_const -#define GUF_DBUF_NAME dbuf_const_cstr -#define GUF_T_EQ guf_cstr_const_eq -#include "guf_dbuf.h" - -#define GUF_T guf_str_view -#define GUF_DBUF_NAME dbuf_str_view -#define GUF_T_EQ guf_str_view_equal -#include "guf_dbuf.h" - -#define GUF_T guf_str -#define GUF_DBUF_NAME dbuf_str -#define GUF_T_COPY guf_str_copy -#define GUF_T_MOVE guf_str_move -#define GUF_T_FREE guf_str_free -#define GUF_T_EQ guf_str_equal -#include "guf_dbuf.h" - -#endif diff --git a/libguf/test/impls/dict_impl.c b/libguf/test/impls/dict_impl.c deleted file mode 100755 index 3e773df..0000000 --- a/libguf/test/impls/dict_impl.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "dict_impl.h" - -#define GUF_DICT_KEY_T guf_cstr_const -#define GUF_DICT_KEY_T_EQ guf_cstr_const_eq -#define GUF_DICT_KEY_HASH guf_cstr_const_hash -#define GUF_DICT_VAL_T int -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_cstr_int -#define GUF_DICT_IMPL -#include "guf_dict.h" - -#define GUF_DICT_KEY_T guf_str_view -#define GUF_DICT_KEY_HASH guf_str_view_hash -#define GUF_DICT_KEY_T_EQ guf_str_view_equal -#define GUF_DICT_VAL_T int32_t -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_sv_i32 -#define GUF_DICT_IMPL -// #define GUF_DICT_64_BIT_IDX -// #define GUF_DICT_PROBE_LINEAR -// #define GUF_DICT_32_BIT_HASH -#include "guf_dict.h" - -#define GUF_DICT_KEY_T guf_str -#define GUF_DICT_KEY_HASH guf_str_hash -#define GUF_DICT_KEY_T_EQ guf_str_equal -#define GUF_DICT_KEY_T_CMP guf_str_cmp -#define GUF_DICT_KEY_T_COPY guf_str_copy -#define GUF_DICT_KEY_T_MOVE guf_str_move -#define GUF_DICT_KEY_T_FREE guf_str_free -#define GUF_DICT_VAL_T int32_t -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_str_i32 -#define GUF_DICT_IMPL -// #define GUF_DICT_64_BIT_IDX -// #define GUF_DICT_PROBE_LINEAR -// #define GUF_DICT_32_BIT_HASH -#include "guf_dict.h" - -#define GUF_DICT_KEY_T int32_t -#define GUF_DICT_KEY_HASH int32_hash -#define GUF_DICT_KEY_T_EQ int32_eq -#define GUF_DICT_VAL_T bool -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_i32_bool -#define GUF_DICT_IMPL -#include "guf_dict.h" diff --git a/libguf/test/impls/dict_impl.h b/libguf/test/impls/dict_impl.h deleted file mode 100755 index ba4cbad..0000000 --- a/libguf/test/impls/dict_impl.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef GUF_DICT_IMPL_H -#define GUF_DICT_IMPL_H - -#include "guf_common.h" -#include "guf_cstr.h" -#include "guf_str.h" - -#include "guf_hash.h" - -#define GUF_DICT_KEY_T guf_cstr_const -#define GUF_DICT_KEY_HASH guf_cstr_const_hash -#define GUF_DICT_KEY_T_EQ guf_cstr_const_eq -#define GUF_DICT_VAL_T int -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_cstr_int -#include "guf_dict.h" - -#define GUF_DICT_KEY_T guf_str_view -#define GUF_DICT_KEY_HASH guf_str_view_hash -#define GUF_DICT_KEY_T_EQ guf_str_view_equal -#define GUF_DICT_VAL_T int32_t -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_sv_i32 -// #define GUF_DICT_64_BIT_IDX -// #define GUF_DICT_PROBE_LINEAR -// #define GUF_DICT_32_BIT_HASH -#include "guf_dict.h" - -#define GUF_DICT_KEY_T guf_str -#define GUF_DICT_KEY_HASH guf_str_hash -#define GUF_DICT_KEY_T_EQ guf_str_equal -#define GUF_DICT_KEY_T_CMP guf_str_cmp -#define GUF_DICT_KEY_T_COPY guf_str_copy -#define GUF_DICT_KEY_T_MOVE guf_str_move -#define GUF_DICT_KEY_T_FREE guf_str_free -#define GUF_DICT_VAL_T int32_t -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_str_i32 -// #define GUF_DICT_64_BIT_IDX -// #define GUF_DICT_PROBE_LINEAR -// #define GUF_DICT_32_BIT_HASH -#include "guf_dict.h" - -static inline guf_hash_size_t int32_hash(const int32_t *a) -{ - return guf_hash(a, sizeof(int32_t), GUF_HASH_INIT); // TODO: byte order... -} -static inline bool int32_eq(const int32_t *a, const int32_t *b) -{ - return *a == *b; -} - -#define GUF_DICT_KEY_T int32_t -#define GUF_DICT_KEY_HASH int32_hash -#define GUF_DICT_KEY_T_EQ int32_eq -#define GUF_DICT_VAL_T bool -#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE -#define GUF_DICT_NAME dict_i32_bool -#include "guf_dict.h" - -#endif diff --git a/libguf/test/impls/init_impl.c b/libguf/test/impls/init_impl.c deleted file mode 100755 index 7261d21..0000000 --- a/libguf/test/impls/init_impl.c +++ /dev/null @@ -1 +0,0 @@ -#include "guf_init.h" diff --git a/libguf/test/impls/linalg_impl.c b/libguf/test/impls/linalg_impl.c deleted file mode 100755 index 8debd22..0000000 --- a/libguf/test/impls/linalg_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_LINALG_IMPL -#include "guf_linalg.h" diff --git a/libguf/test/impls/rand_impl.c b/libguf/test/impls/rand_impl.c deleted file mode 100755 index 5258f3d..0000000 --- a/libguf/test/impls/rand_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_RAND_IMPL -#include "guf_rand.h" diff --git a/libguf/test/impls/sort_impl.c b/libguf/test/impls/sort_impl.c deleted file mode 100755 index 778a00a..0000000 --- a/libguf/test/impls/sort_impl.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "sort_impl.h" - -#define GUF_T float -#define GUF_SORT_IMPL -#include "guf_sort.h" - -#define GUF_T int32_t -#define GUF_SORT_IMPL -#include "guf_sort.h" - -#define GUF_T int8_t -#define GUF_SORT_IMPL -#include "guf_sort.h" - -#define GUF_T guf_cstr_heap -#define GUF_SORT_IMPL -#include "guf_sort.h" diff --git a/libguf/test/impls/sort_impl.h b/libguf/test/impls/sort_impl.h deleted file mode 100755 index 6c4b7c9..0000000 --- a/libguf/test/impls/sort_impl.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef GUF_SORT_IMPL_H -#define GUF_SORT_IMPL_H - -#include "guf_cstr.h" - -#define GUF_T float -#include "guf_sort.h" - -#define GUF_T int32_t -#include "guf_sort.h" - -#define GUF_T int8_t -#include "guf_sort.h" - -#define GUF_T guf_cstr_heap -#include "guf_sort.h" - -#endif diff --git a/libguf/test/impls/str_impl.c b/libguf/test/impls/str_impl.c deleted file mode 100755 index 8114902..0000000 --- a/libguf/test/impls/str_impl.c +++ /dev/null @@ -1,2 +0,0 @@ -#define GUF_STR_IMPL -#include "guf_str.h" diff --git a/libguf/test/test.cpp b/libguf/test/test.cpp deleted file mode 100755 index 415a8af..0000000 --- a/libguf/test/test.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include - -#include "test_dbuf.hpp" -#include "test_dict.hpp" -#include "test_utf8.hpp" -#include "test_str.hpp" -#include "test_ckdint.hpp" - -extern "C" -{ - #include "guf_assert.h" - #include "guf_math.h" -} - -static std::vector> g_tests {}; - -static void init_tests() -{ - g_tests.push_back(std::make_unique("DbufIntTest")); - g_tests.push_back(std::make_unique("DbufCstringTest")); - g_tests.push_back(std::make_unique("DbufStrTest")); - - g_tests.push_back(std::make_unique("DictSvToIntTest")); - g_tests.push_back(std::make_unique("UTF8Test")); - g_tests.push_back(std::make_unique("StrTest")); - g_tests.push_back(std::make_unique("CkdIntTest")); -} - -int main() -{ - init_tests(); - - std::cout << "Running " << g_tests.size() << " tests...\n"; - - // std::cout << "max cap 1:" << dict_sv_i32_max_capacity() << "\n"; - // std::cout << "max cap 2:" << dict_cstr_int_max_capacity() << "\n"; - - size_t num_passed = 0; - for (auto &test : g_tests) { - Test *tst = test.get(); - GUF_ASSERT_RELEASE(tst); - tst->before_run(); - tst->run(); - tst->after_run(); - std::cout << "- " << *tst << "\n"; - if (tst->passed) { - ++num_passed; - } - } - - const bool passed_all = (num_passed == g_tests.size()); - GUF_ASSERT_RELEASE(num_passed <= g_tests.size()); - - if (passed_all) { - std::cout << "-> SUCCESS: Passed all (" << num_passed << "/" << g_tests.size() << ") tests.\n"; - } else { - std::cout << "-> FAILURE: Failed " << (g_tests.size() - num_passed) << "/" << g_tests.size() << " tests.\n"; - } - - return passed_all ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/libguf/test/test.hpp b/libguf/test/test.hpp deleted file mode 100755 index 58d65bf..0000000 --- a/libguf/test/test.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef GUF_TEST_HPP -#define GUF_TEST_HPP - -#include -#include -#include -#include -#include -#include -extern "C" { - #include "guf_common.h" - #include "guf_assert.h" -} - -#define TEST_CHECK(COND) (check((COND), GUF_STRINGIFY(COND), __LINE__, __FILE__)) - -struct Test -{ -private: - std::chrono::steady_clock::time_point time_start, time_end; - -protected: - std::stack check_name_stack; - std::string full_check_name = ""; - - void push_check_name(const std::string& check_name) - { - check_name_stack.push(check_name); - full_check_name = full_check_name + "::" + check_name; - } - - void pop_check_name() - { - const size_t sep_idx = full_check_name.rfind("::"); - GUF_ASSERT_RELEASE(sep_idx != std::string::npos); - full_check_name = full_check_name.substr(0, sep_idx); - check_name_stack.pop(); - } - - bool check(bool cond, std::string_view msg, size_t line, std::string_view fname) - { - if (!cond) { - std::cerr << name << full_check_name << ": "; - std::cerr << "FAILED CHECK (" << msg << ") on line " << line << " in file " << fname << "\n"; \ - ++num_failed_checks; - } else { - ++num_passed_checks; - } - return cond; - } - -public: - const std::string name {}; - std::chrono::duration runtime_ms {0}; - bool passed {false}, done {false}; - size_t num_failed_checks {0}, num_passed_checks {0}; - - Test(const std::string& nm) : name{nm} {} - virtual ~Test() = default; - - size_t total_checks() const - { - return num_passed_checks + num_failed_checks; - } - - virtual void run() = 0; - - void before_run() - { - time_start = std::chrono::steady_clock::now(); - } - - void after_run() - { - done = true; - passed = (num_failed_checks == 0); - - time_end = std::chrono::steady_clock::now(); - runtime_ms = std::chrono::duration_cast(time_end - time_start); - } - - friend std::ostream& operator<<(std::ostream &os, const Test& tst) - { - std::ios_base::fmtflags os_flags = os.flags(); - std::streamsize os_precision = os.precision(); - - os << tst.name << ": " << (tst.passed ? "PASS" : "FAIL"); - os << std::fixed << std::setprecision(2); - os << " (" << tst.num_passed_checks << "/" << tst.total_checks() << ") in " << tst.runtime_ms.count() << " ms"; - - os.precision(os_precision); - os.flags(os_flags); - return os; - } -}; - -template<> -struct std::hash> { - std::size_t operator()(const std::unique_ptr& test) const - { - if (test.get() == nullptr) { - return 0; - } - return std::hash()(test.get()->name); - } -}; - -#endif diff --git a/libguf/test/test_ckdint.cpp b/libguf/test/test_ckdint.cpp deleted file mode 100755 index 84b45b6..0000000 --- a/libguf/test/test_ckdint.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include "test_ckdint.hpp" - -extern "C" -{ - #include "guf_math_ckdint.h" -} - -/* - CkdIntTest: -*/ - -void CkdIntTest::run() -{ - push_check_name("test_ckd"); - test_ckd(); - pop_check_name(); - - push_check_name("test_ckd_uint"); - test_ckd_uint(); - pop_check_name(); -} - -void CkdIntTest::test_ckd() -{ - for (int32_t a = INT8_MIN; a <= INT8_MAX; ++a) { - for (int32_t b = INT8_MIN; b <= INT8_MAX; ++b) { - const int32_t add_res = a + b; - const guf_math_ckd_result ckd_add = guf_ckd_add_i8((int8_t)a, (int8_t)b); - TEST_CHECK(ckd_add == guf_ckd_add_i8((int8_t)b, (int8_t)a)); - TEST_CHECK(ckd_add == guf_ckd_add_least_i8((int_least8_t)a, (int_least8_t)b)); - if (add_res > INT8_MAX) { - TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_POS); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_add_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == INT8_MAX); - TEST_CHECK(guf_saturating_add_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_add_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(static_cast(wrapped) == INT8_MIN + (add_res % (INT8_MAX + 1))); - TEST_CHECK(guf_wrapping_add_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(wrapped == wrapped2); - } - else if (add_res < INT8_MIN) { - TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_NEG); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_add_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == INT8_MIN); - TEST_CHECK(guf_saturating_add_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_add_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(static_cast(wrapped) == INT8_MAX - (-add_res % (-INT8_MIN + 1))); - TEST_CHECK(guf_wrapping_add_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(wrapped == wrapped2); - } - else { - TEST_CHECK(ckd_add == GUF_MATH_CKD_SUCCESS); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_add_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == add_res); - TEST_CHECK(guf_saturating_add_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_add_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == add_res); - TEST_CHECK(guf_wrapping_add_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(wrapped == wrapped2); - } - - const int32_t sub_res = a - b; - const guf_math_ckd_result ckd_sub = guf_ckd_sub_i8((int8_t)a, (int8_t)b); - TEST_CHECK(ckd_sub == guf_ckd_sub_least_i8((int_least8_t)a, (int_least8_t)b)); - if (sub_res > INT8_MAX) { - TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_POS); - int8_t saturated; - TEST_CHECK(guf_saturating_sub_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == INT8_MAX); - int8_t wrapped; - TEST_CHECK(guf_wrapping_sub_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(static_cast(wrapped) == INT8_MIN + (sub_res % (INT8_MAX + 1))); - } else if (sub_res < INT8_MIN) { - TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_NEG); - int8_t saturated; - TEST_CHECK(guf_saturating_sub_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == INT8_MIN); - int8_t wrapped; - TEST_CHECK(guf_wrapping_sub_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(static_cast(wrapped) == INT8_MAX - (-sub_res % (-INT8_MIN + 1))); - } else { - TEST_CHECK(ckd_sub == GUF_MATH_CKD_SUCCESS); - int8_t saturated; - TEST_CHECK(guf_saturating_sub_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == sub_res); - int8_t wrapped; - TEST_CHECK(guf_wrapping_sub_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == sub_res); - } - - const int32_t mul_res = a * b; - const guf_math_ckd_result ckd_mul = guf_ckd_mul_i8((int8_t)a, (int8_t)b); - TEST_CHECK(ckd_mul == guf_ckd_mul_least_i8((int_least8_t)a, (int_least8_t)b)); - TEST_CHECK(ckd_mul == guf_ckd_mul_i8((int8_t)b, (int8_t)a)); - if (mul_res > INT8_MAX) { - TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_POS); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_mul_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == INT8_MAX); - - TEST_CHECK(guf_saturating_mul_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_mul_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(guf_wrapping_mul_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(wrapped == wrapped2); - // TODO: check wrapped - } else if (mul_res < INT8_MIN) { - TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_NEG); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_mul_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == INT8_MIN); - - TEST_CHECK(guf_saturating_mul_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_mul_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(guf_wrapping_mul_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(wrapped == wrapped2); - // TODO: check wrapped - } else { - TEST_CHECK(ckd_mul == GUF_MATH_CKD_SUCCESS); - int8_t saturated, saturated2; - TEST_CHECK(guf_saturating_mul_i8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == mul_res); - - TEST_CHECK(guf_saturating_mul_i8(static_cast(b), static_cast(a), &saturated2) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(saturated == saturated2); - - int8_t wrapped, wrapped2; - TEST_CHECK(guf_wrapping_mul_i8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == mul_res); - TEST_CHECK(guf_wrapping_mul_i8(static_cast(b), static_cast(a), &wrapped2) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(wrapped == wrapped2); - } - } - } - - int8_t mul_i8_res = -1; - TEST_CHECK(guf_wrapping_mul_i8(42, 5, &mul_i8_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i8_res == -46); - mul_i8_res = -1; - TEST_CHECK(guf_wrapping_mul_i8(5, 42, &mul_i8_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i8_res == -46); - - int16_t mul_i16_res = -1245; - TEST_CHECK(guf_wrapping_mul_i16(32767, 2, &mul_i16_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i16_res == -2); - mul_i16_res = -1245; - TEST_CHECK(guf_wrapping_mul_i16(-32767, 2, &mul_i16_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(mul_i16_res == 2); - /* - // https://play.rust-lang.org/?version=stable&mode=debug&edition=2024 - - use std::num::Wrapping; - - fn main() { - let a = Wrapping(-314159265_i32); - let b = Wrapping(4096_i32); - println!("{}", a * b); - } - */ - - int32_t mul_i32_res = -12345; - TEST_CHECK(guf_wrapping_mul_i32(INT32_MAX, 2, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32_res == -2); - mul_i32_res = -12345; - TEST_CHECK(guf_wrapping_mul_i32(2, INT32_MAX, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32_res == -2); - - mul_i32_res = -12345; - TEST_CHECK(guf_wrapping_mul_i32(INT32_MAX, -2, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(mul_i32_res == 2); - mul_i32_res = -12345; - TEST_CHECK(guf_wrapping_mul_i32(-2, INT32_MAX, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(mul_i32_res == 2); - - TEST_CHECK(guf_wrapping_mul_i32(42002718, 314159265, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32_res == -972735522); - mul_i32_res = -12345; - TEST_CHECK(guf_wrapping_mul_i32(314159265, 42002718, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32_res == -972735522); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(42002718, 314159265, &mul_i32_res); - TEST_CHECK(mul_i32_res == -972735522); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(-42002718, 314159265, &mul_i32_res); - TEST_CHECK(mul_i32_res == 972735522); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(-88888888, 99999999, &mul_i32_res); - TEST_CHECK(mul_i32_res == 1374494264); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(INT32_MIN, -1, &mul_i32_res); - TEST_CHECK(mul_i32_res == INT32_MIN); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(-2147483648, 2147483640, &mul_i32_res); - TEST_CHECK(mul_i32_res == 0); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(-2048, -314159265, &mul_i32_res); - TEST_CHECK(mul_i32_res == -846919680); - - mul_i32_res = 12345; - guf_wrapping_mul_i32(4096, -314159265, &mul_i32_res); - TEST_CHECK(mul_i32_res == 1693839360); - - - int_least32_t mul_i32least_res = -12345; - TEST_CHECK(guf_wrapping_mul_least_i32(INT32_MAX, 2, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32least_res == -2); - mul_i32least_res = -12345; - TEST_CHECK(guf_wrapping_mul_least_i32(2, INT32_MAX, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32least_res == -2); - - mul_i32least_res = -12345; - TEST_CHECK(guf_wrapping_mul_least_i32(INT32_MAX, -2, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(mul_i32least_res == 2); - mul_i32least_res = -12345; - TEST_CHECK(guf_wrapping_mul_least_i32(-2, INT32_MAX, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(mul_i32least_res == 2); - - TEST_CHECK(guf_wrapping_mul_least_i32(42002718, 314159265, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32least_res == -972735522); - mul_i32least_res = -12345; - TEST_CHECK(guf_wrapping_mul_least_i32(314159265, 42002718, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(mul_i32least_res == -972735522); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(42002718, 314159265, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == -972735522); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(-42002718, 314159265, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == 972735522); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(-88888888, 99999999, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == 1374494264); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(INT32_MIN, -1, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == INT32_MIN); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(-2147483648, 2147483640, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == 0); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(-2048, -314159265, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == -846919680); - - mul_i32least_res = 12345; - guf_wrapping_mul_least_i32(4096, -314159265, &mul_i32least_res); - TEST_CHECK(mul_i32least_res == 1693839360); - - - - ptrdiff_t ptrdiff_res = -1234; - TEST_CHECK(guf_saturating_add_ptrdiff_t(PTRDIFF_MAX, 1, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(ptrdiff_res == PTRDIFF_MAX); - ptrdiff_res = -1234; - TEST_CHECK(guf_saturating_add_ptrdiff_t(PTRDIFF_MIN, -1, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(ptrdiff_res == PTRDIFF_MIN); - - ptrdiff_res = -1234; - TEST_CHECK(guf_saturating_mul_ptrdiff_t(PTRDIFF_MAX, 2, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(ptrdiff_res == PTRDIFF_MAX); - ptrdiff_res = -1234; - TEST_CHECK(guf_saturating_mul_ptrdiff_t(PTRDIFF_MIN, 2, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(ptrdiff_res == PTRDIFF_MIN); -} - -void CkdIntTest::test_ckd_uint() -{ - for (int32_t a = 0; a <= UINT8_MAX; ++a) { - for (int32_t b = 0; b <= UINT8_MAX; ++b) { - const int32_t add_res = a + b; - const guf_math_ckd_result ckd_add = guf_ckd_add_u8((uint8_t)a, (uint8_t)b); - GUF_ASSERT(ckd_add == guf_ckd_add_least_u8((uint_least8_t)a, (uint_least8_t)b)); - if (add_res > UINT8_MAX) { - TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_POS); - uint8_t saturated; - TEST_CHECK(guf_saturating_add_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == UINT8_MAX); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_add_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(static_cast(wrapped) == 0 + (add_res % (UINT8_MAX + 1))); - } - else { - TEST_CHECK(ckd_add == GUF_MATH_CKD_SUCCESS); - uint8_t saturated; - TEST_CHECK(guf_saturating_add_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == add_res); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_add_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == add_res); - } - - const int32_t sub_res = a - b; - const guf_math_ckd_result ckd_sub = guf_ckd_sub_u8((uint8_t)a, (uint8_t)b); - GUF_ASSERT(ckd_sub == guf_ckd_sub_least_u8((uint_least8_t)a, (uint_least8_t)b)); - if (sub_res < 0) { - TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_NEG); - uint8_t saturated; - TEST_CHECK(guf_saturating_sub_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(saturated == 0); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_sub_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG); - TEST_CHECK(wrapped == static_cast(static_cast(a) - static_cast(b))); - } else { - TEST_CHECK(ckd_sub == GUF_MATH_CKD_SUCCESS); - uint8_t saturated; - TEST_CHECK(guf_saturating_sub_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == sub_res); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_sub_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == sub_res); - } - - const int32_t mul_res = a * b; - const guf_math_ckd_result ckd_mul = guf_ckd_mul_u8((uint8_t)a, (uint8_t)b); - GUF_ASSERT(ckd_mul == guf_ckd_mul_least_u8((uint_least8_t)a, (uint_least8_t)b)); - if (mul_res > UINT8_MAX) { - TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_POS); - uint8_t saturated; - TEST_CHECK(guf_saturating_mul_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(saturated == UINT8_MAX); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_mul_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS); - TEST_CHECK(wrapped == static_cast(static_cast(a) * static_cast(b))); - } else { - TEST_CHECK(ckd_mul == GUF_MATH_CKD_SUCCESS); - uint8_t saturated; - TEST_CHECK(guf_saturating_mul_u8(static_cast(a), static_cast(b), &saturated) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(saturated) == mul_res); - uint8_t wrapped; - TEST_CHECK(guf_wrapping_mul_u8(static_cast(a), static_cast(b), &wrapped) == GUF_MATH_CKD_SUCCESS); - TEST_CHECK(static_cast(wrapped) == mul_res); - } - } - } -} diff --git a/libguf/test/test_ckdint.hpp b/libguf/test/test_ckdint.hpp deleted file mode 100755 index 986689d..0000000 --- a/libguf/test/test_ckdint.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "test.hpp" - -struct CkdIntTest : public Test -{ - CkdIntTest(const std::string& nm) : Test(nm) {}; - void run() override; - -private: - void test_ckd(); - void test_ckd_uint(); -}; diff --git a/libguf/test/test_dbuf.cpp b/libguf/test/test_dbuf.cpp deleted file mode 100755 index 9ac1870..0000000 --- a/libguf/test/test_dbuf.cpp +++ /dev/null @@ -1,685 +0,0 @@ -#include "test_dbuf.hpp" - -extern "C" -{ - #include "guf_alloc_libc.h" - #include "impls/dbuf_impl.h" -} - -/* - DbufIntTest -*/ - -void DbufIntTest::run() -{ - if (done) { - return; - } - - // allocator_ctx.tracker.log = fopen("alloc_log.txt", "w"); - // allocator_ctx.tracker.err_log = fopen("alloc_err_log.txt", "w"); - - dbuf_int dbuf {}; - dbuf_int_init(&dbuf, 0, &allocator); - - push_check_name("test_push"); - - test_push(&dbuf, 256); - test_push(&dbuf, 128); - test_push(&dbuf, 17); - TEST_CHECK(dbuf.size == (256 + 128 + 17)); - - dbuf_int_free(&dbuf, NULL); - TEST_CHECK(dbuf.size == 0 && dbuf.capacity == 0 && dbuf.data == NULL); - - dbuf_int_init(&dbuf, 24, &allocator); - TEST_CHECK(dbuf.size == 0 && dbuf.capacity == 24 && dbuf.data); - - test_push(&dbuf, 365); - test_push(&dbuf, 4); - test_push(&dbuf, 25); - test_push(&dbuf, 64); - TEST_CHECK(dbuf.size == (365 + 4 + 25 + 64)); - - dbuf_int_free(&dbuf, NULL); - TEST_CHECK(dbuf.size == 0 && dbuf.capacity == 0 && dbuf.data == NULL); - - pop_check_name(); - - push_check_name("insert_remove"); - - for (int n = 0; n <= 128; ++n) { - test_insert_remove(n); - } - test_insert_remove(400); - test_insert_remove(401); - test_insert_remove(512); - test_insert_remove(513); - test_insert_remove(601); - test_insert_remove(2048); - test_insert_remove(2049); - - pop_check_name(); - - TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker)); - // guf_alloc_tracker_print(&allocator_ctx.tracker, stdout); - // puts(""); - // fclose(allocator_ctx.tracker.log); - // fclose(allocator_ctx.tracker.err_log); -} - -std::vector DbufIntTest::dbuf_to_vec(dbuf_int *dbuf) -{ - std::vector vec; - GUF_CNT_FOREACH(dbuf, dbuf_int, it) { - vec.push_back(*it.ptr); - } - return vec; -} - -void DbufIntTest::test_push(dbuf_int *dbuf, int n) -{ - std::vector vec = dbuf_to_vec(dbuf); - - TEST_CHECK(std::ssize(vec) == dbuf->size); - - for (int i = 0; i < n; ++i) { - dbuf_int_push_val(dbuf, i); - vec.push_back(i); - TEST_CHECK(*dbuf_int_back(dbuf) == vec.back()); - } - - ptrdiff_t i = 0; - GUF_CNT_FOREACH(dbuf, dbuf_int, it) { - TEST_CHECK(*it.ptr == vec.at(i++)); - } - TEST_CHECK(i == dbuf->size); - - i = dbuf->size - 1; - GUF_CNT_FOREACH_REVERSE(dbuf, dbuf_int, rit) { - TEST_CHECK(*rit.ptr == vec.at(i--)); - } - TEST_CHECK(i == -1); - -} - -void DbufIntTest::test_insert_remove(int n) -{ - dbuf_int dbuf = {}; - dbuf_int_init(&dbuf, 0, &allocator); - std::vector vec = dbuf_to_vec(&dbuf); - - guf_err err = GUF_ERR_NONE; - dbuf_int_try_erase(&dbuf, 0, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_int_try_erase(&dbuf, 12, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_int_try_front(&dbuf, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_int_try_back(&dbuf, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_int_try_at(&dbuf, 0, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - for (int i = 0; i < n; ++i) { - dbuf_int_insert_val(&dbuf, i, i); - dbuf_int_insert_val(&dbuf, i * 2, 0); - dbuf_int_insert_val(&dbuf, i * 4, dbuf.size); - - vec.insert(vec.begin() + i, i); - vec.insert(vec.begin(), i * 2); - vec.insert(vec.end(), i * 4); - } - TEST_CHECK(std::ssize(vec) == dbuf.size); - - // Iterate - dbuf_int_iter it_dbuf = dbuf_int_begin(&dbuf); - std::vector::const_iterator it_vec = vec.begin(); - while (!dbuf_int_iter_is_end(&dbuf, it_dbuf) && it_vec != vec.end()) { - TEST_CHECK(*it_dbuf.ptr == *it_vec); - it_dbuf = dbuf_int_iter_next(&dbuf, it_dbuf, 1); - std::advance(it_vec, 1); - } - TEST_CHECK(dbuf_int_iter_is_end(&dbuf, it_dbuf) && it_vec == vec.end()); - - // Step iterate. - it_dbuf = dbuf_int_begin(&dbuf); - it_vec = vec.begin(); - while (!dbuf_int_iter_is_end(&dbuf, it_dbuf) && it_vec != vec.end()) { - TEST_CHECK(*it_dbuf.ptr == *it_vec); - it_dbuf = dbuf_int_iter_next(&dbuf, it_dbuf, 7); - - if (dbuf_int_iter_is_end(&dbuf, it_dbuf)) { - it_vec = vec.end(); - } else { - std::advance(it_vec, 7); - } - } - TEST_CHECK(dbuf_int_iter_is_end(&dbuf, it_dbuf) && it_vec == vec.end()); - - // Reverse iterate. - dbuf_int_iter rit_dbuf = dbuf_int_rbegin(&dbuf); - std::vector::const_reverse_iterator rit_vec = vec.crbegin(); - while (!dbuf_int_iter_is_end(&dbuf, rit_dbuf) && rit_vec != vec.crend()) { - TEST_CHECK(*rit_dbuf.ptr == *rit_vec); - rit_dbuf = dbuf_int_iter_next(&dbuf, rit_dbuf, 1); - std::advance(rit_vec, 1); - } - TEST_CHECK(dbuf_int_iter_is_end(&dbuf, rit_dbuf) && rit_vec == vec.rend()); - - // Reverse iterate step. - rit_dbuf = dbuf_int_rbegin(&dbuf); - rit_vec = vec.crbegin(); - while (!dbuf_int_iter_is_end(&dbuf, rit_dbuf) && rit_vec != vec.crend()) { - TEST_CHECK(*rit_dbuf.ptr == *rit_vec); - rit_dbuf = dbuf_int_iter_next(&dbuf, rit_dbuf, 4); - if (dbuf_int_iter_is_end(&dbuf, rit_dbuf)) { - rit_vec = vec.rend(); - } else { - std::advance(rit_vec, 4); - } - } - TEST_CHECK(dbuf_int_iter_is_end(&dbuf, rit_dbuf) && rit_vec == vec.rend()); - - TEST_CHECK(dbuf.size == std::ssize(vec)); - - for (ptrdiff_t i = 0; i < dbuf.size; i += 8) { - dbuf_int_erase(&dbuf, i); - dbuf_int_erase(&dbuf, 0); - dbuf_int_pop(&dbuf); - - vec.erase(vec.begin() + i); - vec.erase(vec.begin() + 0); - vec.pop_back(); - } - - TEST_CHECK(dbuf.size == std::ssize(vec)); - - for (ptrdiff_t i = 0; i < dbuf.size; i += 8) { - TEST_CHECK(*dbuf_int_at(&dbuf, i) == vec.at(i)); - } - - const ptrdiff_t size = dbuf.size; - for (ptrdiff_t i = 0; i < size; ++i) { - int a = dbuf_int_pop_move(&dbuf); - int b = vec.back(); - TEST_CHECK(a == b); - vec.pop_back(); - } - TEST_CHECK(dbuf.size == 0 && vec.size() == 0); - - dbuf_int_free(&dbuf, NULL); - TEST_CHECK(dbuf.size == 0 && dbuf.capacity == 0 && !dbuf.data); -} - - - - -/* - DbufCstringTest -*/ - -void DbufCstringTest::run() -{ - if (done) { - return; - } - - // allocator_ctx.tracker.log = fopen("alloc_log.txt", "w"); - // allocator_ctx.tracker.err_log = fopen("alloc_err_log.txt", "w"); - - push_check_name("push_insert_erase"); - - for (int i = 1; i <= 32; ++i) { - test_push_insert_erase(i); - test_push_insert_erase(i, i - 1); - test_push_insert_erase(i, i + 1); - test_push_insert_erase(i, i); - test_push_insert_erase(i, i / 2); - } - test_push_insert_erase(2048); - test_push_insert_erase(2048, 11); - - dbuf_heap_cstr str_dbuf = {}; - dbuf_heap_cstr_init(&str_dbuf, 0, &allocator); - std::vector str_vec {}; - - for (int i = 0; i < 512; ++i) { - char buf[128]; - memset(buf, '\0', GUF_ARR_SIZE(buf)); - snprintf(buf, GUF_ARR_SIZE(buf), "This is a pretty guf string (number %d)", i); - guf_cstr_heap str = buf; - dbuf_heap_cstr_push(&str_dbuf, &str, GUF_CPY_DEEP); - str_vec.push_back(std::string{buf}); - } - for (int i = 0; i < str_dbuf.size + 16; ++i) { - test_iter(str_vec, &str_dbuf, i); - } - - dbuf_heap_cstr_free(&str_dbuf, NULL); - TEST_CHECK(str_dbuf.size == 0 && str_dbuf.capacity == 0 && !str_dbuf.data); - - pop_check_name(); - - push_check_name("find"); - test_find(); - test_find(3); - test_find(42); - test_find(129); - pop_check_name(); - - TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker)); - // guf_alloc_tracker_print(&allocator_ctx.tracker, stdout); - // puts(""); - // fclose(allocator_ctx.tracker.log); - // fclose(allocator_ctx.tracker.err_log); -} - -void DbufCstringTest::test_iter(std::vector& str_vec, dbuf_heap_cstr *str_dbuf, int step) -{ - GUF_ASSERT_RELEASE(str_dbuf); - if (step <= 0) { - step = 1; - } - - ptrdiff_t i = 0; - GUF_CNT_FOREACH(str_dbuf, dbuf_heap_cstr, it) { - char *str = *it.ptr; - TEST_CHECK(str_vec.at(i) == str); - ++i; - } - TEST_CHECK(i == str_dbuf->size); - - i = str_dbuf->size - 1; - GUF_CNT_FOREACH_REVERSE(str_dbuf, dbuf_heap_cstr, rit) { - char *str = *rit.ptr; - TEST_CHECK(str_vec.at(i) == str); - --i; - } - TEST_CHECK(i == -1); - - dbuf_heap_cstr_iter it_dbuf = dbuf_heap_cstr_begin(str_dbuf); - std::vector::iterator it_vec = str_vec.begin(); - while (!dbuf_heap_cstr_iter_is_end(str_dbuf, it_dbuf)) { - TEST_CHECK(it_vec != str_vec.end()); - TEST_CHECK(*it_vec == *it_dbuf.ptr); - it_dbuf = dbuf_heap_cstr_iter_next(str_dbuf, it_dbuf, step); - if (!dbuf_heap_cstr_iter_is_end(str_dbuf, it_dbuf)) { - std::advance(it_vec, step); - } else { - it_vec = str_vec.end(); - } - } - TEST_CHECK(dbuf_heap_cstr_iter_is_end(str_dbuf, it_dbuf) && it_vec == str_vec.end()); - - dbuf_heap_cstr_iter rit_dbuf = dbuf_heap_cstr_rbegin(str_dbuf); - std::vector::reverse_iterator rit_vec = str_vec.rbegin(); - while (!dbuf_heap_cstr_iter_is_end(str_dbuf, rit_dbuf)) { - TEST_CHECK(rit_vec != str_vec.rend()); - TEST_CHECK(*rit_vec == *rit_dbuf.ptr); - rit_dbuf = dbuf_heap_cstr_iter_next(str_dbuf, rit_dbuf, step); - if (!dbuf_heap_cstr_iter_is_end(str_dbuf, rit_dbuf)) { - std::advance(rit_vec, step); - } else { - rit_vec = str_vec.rend(); - } - } - TEST_CHECK(dbuf_heap_cstr_iter_is_end(str_dbuf, rit_dbuf) && rit_vec == str_vec.rend()); - - for (i = 0; i < str_dbuf->size; ++i) { - char *str = *dbuf_heap_cstr_at(str_dbuf, i); - TEST_CHECK(str_vec.at(i) == str); - } -} - -void DbufCstringTest::test_push_insert_erase(int n, ptrdiff_t start_cap) -{ - std::vector str_vec; - dbuf_heap_cstr str_dbuf {}; - dbuf_heap_cstr_init(&str_dbuf, start_cap, &allocator); - - for (int i = 0; i < n; ++i) { - constexpr int BUF_SZ = 128; - char buf[BUF_SZ]; - memset(buf, '\0', BUF_SZ); - snprintf(buf, BUF_SZ, "This is string number %d", i); - guf_cstr_heap str = buf; - - dbuf_heap_cstr_push(&str_dbuf, &str, GUF_CPY_DEEP); - dbuf_heap_cstr_push_val_cpy(&str_dbuf, str); - char *heap_buf = strdup("Move me plz"); - dbuf_heap_cstr_push(&str_dbuf, &heap_buf, GUF_CPY_MOVE); - TEST_CHECK(heap_buf == NULL); - - TEST_CHECK(strncmp(*dbuf_heap_cstr_back(&str_dbuf), "Move me plz", BUF_SZ) == 0); - TEST_CHECK(strncmp(*dbuf_heap_cstr_at(&str_dbuf, str_dbuf.size - 2), buf, BUF_SZ) == 0); - TEST_CHECK(strncmp(*dbuf_heap_cstr_at(&str_dbuf, str_dbuf.size - 3), buf, BUF_SZ) == 0); - - str_vec.push_back(std::string{buf}); - str_vec.push_back(std::string{buf}); - str_vec.emplace_back("Move me plz"); - } - - TEST_CHECK(str_dbuf.size == std::ssize(str_vec)); - TEST_CHECK(str_dbuf.size == 3 * n); - - for (int i = 1; i <= 8; ++i) { - test_iter(str_vec, &str_dbuf, i); - } - test_iter(str_vec, &str_dbuf, (int)str_dbuf.size); - test_iter(str_vec, &str_dbuf, (int)str_dbuf.size - 1); - test_iter(str_vec, &str_dbuf, (int)str_dbuf.size + 1); - - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - TEST_CHECK(str_vec.at(i) == *dbuf_heap_cstr_at(&str_dbuf, i)); - } - - // Insert front. - for (ptrdiff_t i = 0; i < 16; ++i) { - char str[] = "front"; - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, 0); - str_vec.insert(str_vec.begin(), std::string{str}); - } - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - TEST_CHECK(str_vec.at(i) == *dbuf_heap_cstr_at(&str_dbuf, i)); - } - // Insert back. - for (ptrdiff_t i = 0; i < 16; ++i) { - char str[] = "front"; - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, str_dbuf.size); - str_vec.insert(str_vec.end(), std::string{str}); - } - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - TEST_CHECK(str_vec.at(i) == *dbuf_heap_cstr_at(&str_dbuf, i)); - } - - // Insert at i. - char str[] = "guf"; - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, str_dbuf.size / 2); - str_vec.insert(str_vec.begin() + str_vec.size() / 2, str); - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, str_dbuf.size / 4); - str_vec.insert(str_vec.begin() + str_vec.size() / 4, str); - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, 1); - str_vec.insert(str_vec.begin() + 1, str); - dbuf_heap_cstr_insert_val_cpy(&str_dbuf, str, str_dbuf.size - 1); - str_vec.insert(str_vec.begin() + (str_vec.size() - 1), str); - - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - TEST_CHECK(str_vec.at(i) == *dbuf_heap_cstr_at(&str_dbuf, i)); - } - - guf_err err = GUF_ERR_NONE; - dbuf_heap_cstr_try_insert_val_cpy(&str_dbuf, str, str_dbuf.size + 1, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_heap_cstr_try_insert_val_cpy(&str_dbuf, str, -1, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - err = GUF_ERR_NONE; - dbuf_heap_cstr_try_insert_val_cpy(&str_dbuf, str, str_dbuf.size + 2, &err); - TEST_CHECK(err == GUF_ERR_IDX_RANGE); - - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - TEST_CHECK(str_vec.at(i) == *dbuf_heap_cstr_at(&str_dbuf, i)); - } - - if (str_dbuf.size) { - dbuf_heap_cstr_erase(&str_dbuf, str_dbuf.size - 1); - str_vec.erase(str_vec.end() - 1); - } - - ptrdiff_t to_rem = 8; - while (str_dbuf.size && to_rem--) { - dbuf_heap_cstr_erase(&str_dbuf, 0); - str_vec.erase(str_vec.begin()); - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - if (str_dbuf.size) { - dbuf_heap_cstr_pop(&str_dbuf); - str_vec.pop_back(); - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - } - if (str_dbuf.size) { - dbuf_heap_cstr_erase(&str_dbuf, str_dbuf.size / 2); - str_vec.erase(str_vec.begin() + (str_vec.size() / 2)); - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - } - } - - dbuf_heap_cstr_free(&str_dbuf, NULL); - TEST_CHECK(str_dbuf.size == 0 && str_dbuf.capacity == 0 && !str_dbuf.data); -} - -void DbufCstringTest::test_find(int n) -{ - if (n < 2) { - n = 2; - } - std::vector str_vec {}; - - dbuf_heap_cstr str_dbuf = {}; - dbuf_heap_cstr_init(&str_dbuf, 0, &allocator); - - for (int i = 0; i < n; ++i) { - constexpr int BUF_SZ = 128; - char buf[BUF_SZ]; - memset(buf, '\0', BUF_SZ); - snprintf(buf, BUF_SZ, "String number %d", i); - - dbuf_heap_cstr_push_val_cpy(&str_dbuf, buf); - str_vec.push_back(buf); - } - char *move_me = strdup("Moved string"); - dbuf_heap_cstr_push(&str_dbuf, &move_me, GUF_CPY_MOVE); - GUF_ASSERT_RELEASE(move_me == NULL); - str_vec.emplace_back("Moved string"); - - TEST_CHECK(std::ssize(str_vec) == str_dbuf.size); - - for (ptrdiff_t i = 0; i < str_dbuf.size; ++i) { - char *needle = *dbuf_heap_cstr_at(&str_dbuf, i); - TEST_CHECK(str_vec.at(i) == needle); - - TEST_CHECK(dbuf_heap_cstr_contains_val(&str_dbuf, needle)); - - dbuf_heap_cstr_iter fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), dbuf_heap_cstr_end(&str_dbuf), needle); - TEST_CHECK(!dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin(), str_vec.cend(), needle) != str_vec.end()); - - dbuf_heap_cstr_iter begin = dbuf_heap_cstr_iter_next(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), i); - dbuf_heap_cstr_iter end = dbuf_heap_cstr_end(&str_dbuf); - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, begin, end, needle); - TEST_CHECK(!dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin() + i, str_vec.cend(), needle) != str_vec.end()); - - begin = dbuf_heap_cstr_iter_next(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), i + 1); - end = dbuf_heap_cstr_end(&str_dbuf); - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, begin, end, needle); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin() + i + 1, str_vec.cend(), needle) == str_vec.end()); - - // Reverse. - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_rbegin(&str_dbuf), dbuf_heap_cstr_rend(&str_dbuf), needle); - TEST_CHECK(!dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.crbegin(), str_vec.crend(), needle) != str_vec.rend()); - } - - char needle[] = "Definitely not inside"; - dbuf_heap_cstr_iter fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), dbuf_heap_cstr_end(&str_dbuf), needle); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin(), str_vec.cend(), needle) == str_vec.end()); - - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_rbegin(&str_dbuf), dbuf_heap_cstr_rend(&str_dbuf), needle); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.crbegin(), str_vec.crend(), needle) == str_vec.rend()); - - char *needle2 = *dbuf_heap_cstr_at(&str_dbuf, 0); - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_iter_next(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), 1), dbuf_heap_cstr_end(&str_dbuf), needle2); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin() + 1, str_vec.cend(), needle2) == str_vec.end()); - - needle2 = *dbuf_heap_cstr_back(&str_dbuf); - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_iter_next(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), 1), dbuf_heap_cstr_iter_next(&str_dbuf, dbuf_heap_cstr_end(&str_dbuf), -1), needle2); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.begin(), str_vec.end() - 1, needle2) == (str_vec.end() - 1)); - - needle2 = *dbuf_heap_cstr_at(&str_dbuf, 0); - fnd_it = dbuf_heap_cstr_find_val(&str_dbuf, dbuf_heap_cstr_begin(&str_dbuf), dbuf_heap_cstr_begin(&str_dbuf), needle2); - TEST_CHECK(dbuf_heap_cstr_iter_is_end(&str_dbuf, fnd_it)); - TEST_CHECK(std::find(str_vec.cbegin(), str_vec.cbegin(), needle2) == str_vec.cbegin()); - - dbuf_heap_cstr_free(&str_dbuf, NULL); -} - - - -/* - DbufStrTest: -*/ - -void DbufStrTest::run() -{ - test_push_insert_erase(16); - test_push_insert_erase(16, 1); - test_push_insert_erase(16, 15); - test_push_insert_erase(16, 16); - test_push_insert_erase(16, 97); - test_push_insert_erase(16, 256); - - test_push_insert_erase(500); - test_push_insert_erase(500, 1); - test_push_insert_erase(500, 499); - test_push_insert_erase(500, 500); - test_push_insert_erase(500, 97); - test_push_insert_erase(500, 256); - -} - - -void DbufStrTest::test_push_insert_erase(size_t n, ptrdiff_t start_cap) -{ - dbuf_str strings = start_cap < 0 ? dbuf_str_new(&allocator) : dbuf_str_new_with_capacity(start_cap, &allocator); - std::vector strings_cpp {}; - - guf_libc_alloc_ctx str_allocator_ctx = { - .tracker = guf_alloc_tracker_new(42, "test_push_insert_erase: local str allocator", NULL, NULL), - .zero_init = false - }; - guf_allocator str_allocator = guf_libc_allocator_new(&str_allocator_ctx); - - for (size_t i = 0; i < n; ++i) { - std::string str; - for (size_t c = 0; c < 512 + GUF_STR_SSO_BUF_CAP; ++c) { - str += (char)(c % 10 + '0'); - } - const guf_str_view sv_long = guf_str_view{.str = str.data(), .len = (ptrdiff_t)str.size()}; - const guf_str_view sv_short = guf_str_view{.str = str.data(), .len = (ptrdiff_t)GUF_STR_SSO_BUF_CAP - 1}; - - guf_str long_str = GUF_STR_UNINITIALISED_CPP, short_str = GUF_STR_UNINITIALISED_CPP; - guf_str_init(&long_str, sv_long, &str_allocator); - guf_str_init(&short_str, sv_short, &str_allocator); - - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 1 + (i*3)); - - // Move - guf_err err; - dbuf_str_try_push(&strings, &long_str, GUF_CPY_MOVE, &err); - TEST_CHECK(err == GUF_ERR_NONE); - dbuf_str_try_push(&strings, &short_str, GUF_CPY_MOVE, &err); - TEST_CHECK(err == GUF_ERR_NONE); - - strings_cpp.push_back(str.substr(0, str.size())); - strings_cpp.push_back(str.substr(0, GUF_STR_SSO_BUF_CAP - 1)); - - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 1 + (i*3)); - - TEST_CHECK(guf_str_is_uninit(&long_str)); - TEST_CHECK(guf_str_is_uninit(&short_str)); - - // Deep-copy - guf_str_init(&long_str, sv_long, &str_allocator); - guf_str_init(&short_str, sv_short, &str_allocator); - - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 2 + (i*3)); - - dbuf_str_try_push(&strings, &long_str, GUF_CPY_DEEP, &err); - TEST_CHECK(err == GUF_ERR_NONE); - dbuf_str_try_push(&strings, &short_str, GUF_CPY_DEEP, &err); - TEST_CHECK(err == GUF_ERR_NONE); - - strings_cpp.push_back(str.substr(0, str.size())); - strings_cpp.push_back(str.substr(0, GUF_STR_SSO_BUF_CAP - 1)); - - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 3 + (i*3)); - - TEST_CHECK(guf_str_is_valid(&long_str) && guf_str_is_valid(&short_str)); - TEST_CHECK(guf_str_view_equal_val_arg(guf_str_view_from_str(&long_str), sv_long)); - TEST_CHECK(guf_str_view_equal_val_arg(guf_str_view_from_str(&short_str), sv_short)); - - guf_str_free(&long_str, NULL); - guf_str_free(&short_str, NULL); - - TEST_CHECK(str_allocator_ctx.tracker.free_count == 1 + (i*1)); - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 3 + (i*3)); - } - - TEST_CHECK(str_allocator_ctx.tracker.free_count == n); - TEST_CHECK(str_allocator_ctx.tracker.alloc_count == 3 * n); - - TEST_CHECK(strings.size == 4 * (ptrdiff_t)n); - TEST_CHECK(strings.size == std::ssize(strings_cpp)); - - std::string str; - for (size_t c = 0; c < 512 + GUF_STR_SSO_BUF_CAP; ++c) { - str += (char)(c % 10 + '0'); - } - const guf_str_view sv_long = guf_str_view{.str = str.data(), .len = (ptrdiff_t)str.size()}; - const guf_str_view sv_short = guf_str_view{.str = str.data(), .len = (ptrdiff_t)GUF_STR_SSO_BUF_CAP - 1}; - size_t i = 0; - GUF_CNT_FOREACH(&strings, dbuf_str, it) { - if (TEST_CHECK(it.ptr)) { - const guf_str *s = it.ptr; - TEST_CHECK(guf_str_view_equal_val_arg(guf_str_view_from_str(s), i % 2 == 0 ? sv_long : sv_short)); - const guf_str_view sv_cpp = guf_str_view {.str = strings_cpp.at(i).data(), .len = (ptrdiff_t)strings_cpp.at(i).size()}; - TEST_CHECK(guf_str_view_equal_val_arg(guf_str_view_from_str(s), sv_cpp)); - } - ++i; - } - - GUF_CNT_FOREACH(&strings, dbuf_str, it) { - if (TEST_CHECK(it.ptr)) { - guf_str *s = it.ptr; - TEST_CHECK(guf_str_append(s, GUF_CSTR_LIT_TO_VIEW_CPP(""))); - } - } - std::vector delims = {guf_str_view{.str = "", .len = 5}}; - i = 0; - GUF_CNT_FOREACH(&strings, dbuf_str, it) { - if (TEST_CHECK(it.ptr)) { - const guf_str *s = it.ptr; - guf_str_tok_state tk_state = guf_str_tok_state_new(guf_str_view_from_str(s), delims.data(), std::ssize(delims), GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - size_t tok_n = 0; - while (guf_str_tok_next(&tk_state, true)) { - TEST_CHECK(guf_str_view_equal_val_arg(tk_state.cur_tok , i % 2 == 0 ? sv_long : sv_short)); - TEST_CHECK(guf_str_view_equal_val_arg(tk_state.cur_delim, guf_str_view{.str = "", .len = 5})); - ++tok_n; - } - TEST_CHECK(tok_n == 1); - } - ++i; - } - - dbuf_str_free(&strings, NULL); - TEST_CHECK(!guf_alloc_tracker_found_leak(&str_allocator_ctx.tracker)); -} diff --git a/libguf/test/test_dbuf.hpp b/libguf/test/test_dbuf.hpp deleted file mode 100755 index 3cef1fd..0000000 --- a/libguf/test/test_dbuf.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include -#include "test.hpp" - -extern "C" -{ - #include "guf_alloc_libc.h" - #include "impls/dbuf_impl.h" -} - -struct DbufIntTest : public Test -{ - DbufIntTest(const std::string& nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 1, "DbufIntTest_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - } - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - std::vector dbuf_to_vec(dbuf_int *dbuf); - void test_push(dbuf_int *dbuf, int n); - void test_insert_remove(int n); -}; - - -struct DbufCstringTest : public Test -{ - DbufCstringTest(std::string nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 2, "DbufCstringTest_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - } - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - void test_iter(std::vector& str_vec, dbuf_heap_cstr *str_dbuf, int step = 1); - void test_push_insert_erase(int n, ptrdiff_t start_cap = 0); - void test_find(int n = 32); -}; - - -struct DbufStrTest : public Test -{ - DbufStrTest(std::string nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 3, "DbufStrTest_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - } - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - void test_push_insert_erase(size_t n, ptrdiff_t start_cap = 0); -}; diff --git a/libguf/test/test_dict.cpp b/libguf/test/test_dict.cpp deleted file mode 100755 index 91d14ab..0000000 --- a/libguf/test/test_dict.cpp +++ /dev/null @@ -1,431 +0,0 @@ -#include "test_dict.hpp" - -#include -#include -extern "C" -{ - #include "guf_alloc_libc.h" - #include "guf_str.h" - #include "impls/dict_impl.h" - #include "impls/dbuf_impl.h" -} - -/* - DictSvToIntTest: -*/ - -void DictSvToIntTest::run() -{ - if (done) { - return; - } - - push_check_name("insert_lookup(\"utf8-test.txt\")"); - if (TEST_CHECK(load_file(TEST_DATA_DIR "/utf8-test.txt"))) { - insert_lookup(); - for (ptrdiff_t i = 0; i <= 64; ++i) { - insert_lookup(i); - } - insert_lookup(512); - insert_lookup(1997); - insert_lookup(1999); - } - free_file(); - pop_check_name(); - - push_check_name("insert_lookup(\"bartleby.txt\")"); - if (TEST_CHECK(load_file(TEST_DATA_DIR "/bartleby.txt"))) { - insert_lookup(); - insert_lookup(201); - } - free_file(); - pop_check_name(); - - //guf_alloc_tracker_print(&allocator_ctx.tracker, NULL); - TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker)); -} - -void DictSvToIntTest::insert_lookup(std::optional inital_dict_cap) -{ - std::unordered_map word_cnt_map {}; - dict_sv_i32 word_cnt_dict {}; - dict_str_i32 word_cnt_dict_str {}; - - if (inital_dict_cap) { - dict_sv_i32_init_with_capacity(&word_cnt_dict, &allocator, inital_dict_cap.value()); - dict_str_i32_init_with_capacity(&word_cnt_dict_str, &allocator, inital_dict_cap.value()); - } else { - dict_sv_i32_init(&word_cnt_dict, &allocator); - dict_str_i32_init(&word_cnt_dict_str, &allocator); - } - - dbuf_str_view delims = dbuf_str_view_new(&allocator); - for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) { - guf_str_view d = {.str = GUF_UTF8_WHITESPACE[i], .len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i])}; - dbuf_str_view_push_val(&delims, d); - } - for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_COMMON_PUNCT); ++i) { - guf_str_view d = {.str = GUF_UTF8_COMMON_PUNCT[i], .len = (ptrdiff_t)strlen(GUF_UTF8_COMMON_PUNCT[i])}; - dbuf_str_view_push_val(&delims, d); - } - - guf_str_tok_state tok_state = guf_str_tok_state_new(guf_str_view{.str = text_buf.data, .len = text_buf.size}, delims.data, delims.size, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - while (guf_str_tok_next(&tok_state, true)) { - guf_str_view tok = tok_state.cur_tok; - // if (tok.len <= 0) { - // continue; - // } - std::string_view sv(tok.str , tok.len); - //std::cout << sv << std::string_view(tok_state.cur_delim.str, tok_state.cur_delim.len); - TEST_CHECK(dict_sv_i32_contains(&word_cnt_dict, &tok) == word_cnt_map.contains(sv)); - if (!dict_sv_i32_contains(&word_cnt_dict, &tok)) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, tok, 1, GUF_CPY_VALUE, GUF_CPY_VALUE); - word_cnt_map.insert({sv, 1}); - if (TEST_CHECK(!dict_str_i32_contains_val_arg(&word_cnt_dict_str, guf_str_new_readonly(tok)))) { - dict_str_i32_insert_val_arg(&word_cnt_dict_str, guf_str_new(tok, &allocator), 1, GUF_CPY_MOVE, GUF_CPY_VALUE); - } - } else { - int32_t *cnt = dict_sv_i32_at_val_arg(&word_cnt_dict, tok); - if (TEST_CHECK(cnt)) { - *cnt += 1; - } - int32_t *cnt_2 = dict_str_i32_at_val_arg(&word_cnt_dict_str, guf_str_new_readonly(tok)); - if (TEST_CHECK(cnt_2)) { - *cnt_2 += 1; - } - // else { - // std::cout << "tok: " << std::string_view{tok.str, (size_t)tok.len} << "\n"; - // } - word_cnt_map.at(sv) += 1; - } - // printf("tok_len: %td ", tok.len); - // printf("'%.*s'\n", (int)tok.len, tok.str); - TEST_CHECK(dict_sv_i32_debug_valid_size(&word_cnt_dict)); - TEST_CHECK(dict_str_i32_debug_valid_size(&word_cnt_dict_str)); - - } - dbuf_str_view_free(&delims, NULL); - - TEST_CHECK(dict_sv_i32_size(&word_cnt_dict) == std::ssize(word_cnt_map)); - TEST_CHECK(dict_sv_i32_debug_valid_size(&word_cnt_dict)); - - TEST_CHECK(dict_str_i32_size(&word_cnt_dict_str) == std::ssize(word_cnt_map)); - TEST_CHECK(dict_str_i32_debug_valid_size(&word_cnt_dict_str)); - - for (const auto & [word, cnt] : word_cnt_map ) { - guf_str_view sv = {.str = word.data(), .len = (ptrdiff_t)word.size()}; - int32_t *res = dict_sv_i32_at(&word_cnt_dict, &sv); - int32_t *res2 = dict_str_i32_at_val_arg(&word_cnt_dict_str, guf_str_new_readonly(sv)); - TEST_CHECK(res && *res == cnt); - TEST_CHECK(res2 && *res2 == cnt); - } - - ptrdiff_t i = 0; - GUF_CNT_FOREACH(&word_cnt_dict, dict_sv_i32, kv_it) { - const dict_sv_i32_kv *kv = kv_it.ptr; - if (TEST_CHECK(kv)) { - const int32_t cnt = kv->val; - const std::string_view sv(kv->key.str, kv->key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - TEST_CHECK(word_cnt_map.at(sv) == cnt); - } - } - ++i; - } - TEST_CHECK(i == dict_sv_i32_size(&word_cnt_dict)); - TEST_CHECK(i == std::ssize(word_cnt_map)); - TEST_CHECK(dict_sv_i32_debug_valid_size(&word_cnt_dict)); - - i = 0; - GUF_CNT_FOREACH(&word_cnt_dict_str, dict_str_i32, kv_it) { - const dict_str_i32_kv *kv = kv_it.ptr; - if (TEST_CHECK(kv)) { - const int32_t cnt = kv->val; - const std::string_view sv(guf_str_const_cstr(&kv->key), guf_str_len(&kv->key)); - // std::cout << sv << "\n"; - - if (TEST_CHECK(word_cnt_map.contains(sv))) { - TEST_CHECK(word_cnt_map.at(sv) == cnt); - } - } - ++i; - } - TEST_CHECK(i == dict_str_i32_size(&word_cnt_dict_str)); - TEST_CHECK(i == std::ssize(word_cnt_map)); - TEST_CHECK(dict_str_i32_debug_valid_size(&word_cnt_dict_str)); - - // std::cout << "load fac: " << dict_sv_i32_load_factor(&word_cnt_dict) << ", cap: " << word_cnt_dict.kv_indices_cap << " elem cap: " << word_cnt_dict.kv_elems.capacity << "\n"; - // std::cout << "size: " << dict_sv_i32_size(&word_cnt_dict) << ", max probelen: " << word_cnt_dict.max_probelen << "\n"; - // std::cout << "mem usage: " << dict_sv_i32_memory_usage(&word_cnt_dict) << "\n"; - - // Erase tests: - const double load_fac_before_erase = dict_sv_i32_load_factor(&word_cnt_dict); - const ptrdiff_t size_before_erase = dict_sv_i32_size(&word_cnt_dict); - ptrdiff_t num_del = 0; - while (dict_sv_i32_size(&word_cnt_dict) > size_before_erase / 2) { - dict_sv_i32_kv *kv = NULL; - if (num_del % 2) { - dict_sv_i32_iter it = dict_sv_i32_begin(&word_cnt_dict); - GUF_ASSERT_RELEASE(!dict_sv_i32_iter_is_end(&word_cnt_dict, it)); - kv = it.ptr; - } else { - dict_sv_i32_iter rit = dict_sv_i32_rbegin(&word_cnt_dict); - GUF_ASSERT_RELEASE(!dict_sv_i32_iter_is_end(&word_cnt_dict, rit)); - kv = rit.ptr; - } - GUF_ASSERT_RELEASE(kv); - - const guf_str_view key = kv->key; - - const bool del_success = dict_sv_i32_erase(&word_cnt_dict, &key); - TEST_CHECK(del_success); - TEST_CHECK(!dict_sv_i32_contains(&word_cnt_dict, &key)); - - std::string_view sv(key.str, (size_t)key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - word_cnt_map.erase(sv); - } - TEST_CHECK(!word_cnt_map.contains(sv)); - - if (del_success) { - ++num_del; - } - } - TEST_CHECK(dict_sv_i32_size(&word_cnt_dict) >= 0); - TEST_CHECK(size_before_erase - num_del == dict_sv_i32_size(&word_cnt_dict)); - TEST_CHECK(std::ssize(word_cnt_map) == dict_sv_i32_size(&word_cnt_dict)); - - if (dict_sv_i32_size(&word_cnt_dict) != 0) { - TEST_CHECK(load_fac_before_erase == dict_sv_i32_load_factor(&word_cnt_dict)); - } else { - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == 0); - } - - if (dict_sv_i32_size(&word_cnt_dict) >= 4) { - dict_sv_i32_kv_dbuf_iter it = dict_sv_i32_begin(&word_cnt_dict); - it = dict_sv_i32_iter_next(&word_cnt_dict, it, 1); - GUF_ASSERT_RELEASE(!dict_sv_i32_iter_is_end(&word_cnt_dict, it)); - - guf_str_view key = it.ptr->key; - - bool del_success = dict_sv_i32_erase(&word_cnt_dict, &key); - TEST_CHECK(del_success); - TEST_CHECK(!dict_sv_i32_contains(&word_cnt_dict, &key)); - - std::string_view sv(key.str, (size_t)key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - word_cnt_map.erase(sv); - } - - it = dict_sv_i32_rbegin(&word_cnt_dict); - it = dict_sv_i32_iter_next(&word_cnt_dict, it, 1); - GUF_ASSERT_RELEASE(!dict_sv_i32_iter_is_end(&word_cnt_dict, it)); - key = it.ptr->key; - - del_success = dict_sv_i32_erase(&word_cnt_dict, &key); - TEST_CHECK(del_success); - TEST_CHECK(!dict_sv_i32_contains(&word_cnt_dict, &key)); - - sv = std::string_view(key.str, (size_t)key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - word_cnt_map.erase(sv); - } - } - TEST_CHECK(std::ssize(word_cnt_map) == dict_sv_i32_size(&word_cnt_dict)); - - i = 0; - GUF_CNT_FOREACH(&word_cnt_dict, dict_sv_i32, kv_it) { - const dict_sv_i32_kv *kv = kv_it.ptr; - if (TEST_CHECK(kv)) { - const int32_t cnt = kv->val; - const std::string_view sv(kv->key.str, (size_t)kv->key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - TEST_CHECK(word_cnt_map.at(sv) == cnt); - } - ++i; - } - } - TEST_CHECK(i == word_cnt_dict.kv_elems.size); - TEST_CHECK(i == std::ssize(word_cnt_map)); - - while (dict_sv_i32_size(&word_cnt_dict) > 0) { - const dict_sv_i32_iter beg = dict_sv_i32_begin(&word_cnt_dict); - if (TEST_CHECK(!dict_sv_i32_iter_is_end(&word_cnt_dict, beg))) { - const guf_str_view key = beg.ptr->key; - if (TEST_CHECK(dict_sv_i32_contains(&word_cnt_dict, &key))) { - const bool del_success = dict_sv_i32_erase(&word_cnt_dict, &key); - TEST_CHECK(del_success); - TEST_CHECK(!dict_sv_i32_contains(&word_cnt_dict, &key)); - } - const std::string_view sv(key.str, (size_t)key.len); - if (TEST_CHECK(word_cnt_map.contains(sv))) { - word_cnt_map.erase(sv); - } - } - } - TEST_CHECK(dict_sv_i32_size(&word_cnt_dict) == 0 && word_cnt_map.size() == 0); - TEST_CHECK(word_cnt_dict.num_tombstones == 0); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == 0); - - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Hej"), (size_t)64, GUF_CPY_VALUE, GUF_CPY_VALUE); - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("verden!"), (size_t)128, GUF_CPY_VALUE, GUF_CPY_VALUE); - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Flødeskum"), (size_t)256, GUF_CPY_VALUE, GUF_CPY_VALUE); - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("med"), (size_t)512, GUF_CPY_VALUE, GUF_CPY_VALUE); - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Faxe Kondi."), (size_t)1024, GUF_CPY_VALUE, GUF_CPY_VALUE); - - TEST_CHECK(dict_sv_i32_size(&word_cnt_dict) == 5); - - int32_t *val = dict_sv_i32_at_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Hej")); - TEST_CHECK(val && *val == 64); - val = dict_sv_i32_at_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Flødeskum")); - TEST_CHECK(val && *val == 256); - val = dict_sv_i32_at_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Faxe Kondi.")); - TEST_CHECK(val && *val == 1024); - val = dict_sv_i32_at_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("verden!")); - TEST_CHECK(val && *val == 128); - val = dict_sv_i32_at_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("med")); - TEST_CHECK(val && *val == 512); - - TEST_CHECK(word_cnt_dict.kv_elems.size == 5); - - TEST_CHECK(word_cnt_dict.kv_elems.data[0].val == 64 && std::strcmp(word_cnt_dict.kv_elems.data[0].key.str, "Hej") == 0); - TEST_CHECK(word_cnt_dict.kv_elems.data[1].val == 128 && std::strcmp(word_cnt_dict.kv_elems.data[1].key.str, "verden!") == 0); - TEST_CHECK(word_cnt_dict.kv_elems.data[2].val == 256 && std::strcmp(word_cnt_dict.kv_elems.data[2].key.str, "Flødeskum") == 0); - TEST_CHECK(word_cnt_dict.kv_elems.data[3].val == 512 && std::strcmp(word_cnt_dict.kv_elems.data[3].key.str, "med") == 0); - TEST_CHECK(word_cnt_dict.kv_elems.data[4].val == 1024 && std::strcmp(word_cnt_dict.kv_elems.data[4].key.str, "Faxe Kondi.") == 0); - - const double load_fac_beg = dict_sv_i32_load_factor(&word_cnt_dict); - const ptrdiff_t cap_begin = word_cnt_dict.kv_indices_cap; - ptrdiff_t del = 0; - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Hej"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - for (ptrdiff_t n = 0; n < cap_begin + 128; ++n) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Hej"), 64, GUF_CPY_VALUE, GUF_CPY_VALUE); - TEST_CHECK(word_cnt_dict.num_tombstones == --del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Hej"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - } - TEST_CHECK(word_cnt_dict.kv_indices_cap == cap_begin); - - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Faxe Kondi."))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - for (ptrdiff_t n = 0; n < 256; ++n) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Faxe Kondi."), 128, GUF_CPY_VALUE, GUF_CPY_VALUE); - TEST_CHECK(word_cnt_dict.num_tombstones == --del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Faxe Kondi."))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - } - TEST_CHECK(word_cnt_dict.kv_indices_cap == cap_begin); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("med"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - for (ptrdiff_t n = 0; n < 512 + cap_begin; ++n) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("med"), 256, GUF_CPY_VALUE, GUF_CPY_VALUE); - TEST_CHECK(word_cnt_dict.num_tombstones == --del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("med"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - } - TEST_CHECK(word_cnt_dict.kv_indices_cap == cap_begin); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Flødeskum"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - for (ptrdiff_t n = 0; n < 71; ++n) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Flødeskum"), 512, GUF_CPY_VALUE, GUF_CPY_VALUE); - TEST_CHECK(word_cnt_dict.num_tombstones == --del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("Flødeskum"))); - TEST_CHECK(word_cnt_dict.num_tombstones == ++del); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == load_fac_beg); - } - TEST_CHECK(word_cnt_dict.kv_indices_cap == cap_begin); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("verden!"))); - TEST_CHECK(word_cnt_dict.num_tombstones == 0); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == 0); - for (ptrdiff_t n = 0; n < 201; ++n) { - dict_sv_i32_insert_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("verden!"), 128, GUF_CPY_VALUE, GUF_CPY_VALUE); - TEST_CHECK(word_cnt_dict.num_tombstones == 0); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) > 0); - - TEST_CHECK(dict_sv_i32_erase_val_arg(&word_cnt_dict, GUF_CSTR_TO_VIEW_CPP("verden!"))); - TEST_CHECK(word_cnt_dict.num_tombstones == 0); - TEST_CHECK(dict_sv_i32_load_factor(&word_cnt_dict) == 0); - } - TEST_CHECK(word_cnt_dict.kv_indices_cap == cap_begin); - - TEST_CHECK(word_cnt_dict.kv_elems.size == 0); - TEST_CHECK(dict_sv_i32_size(&word_cnt_dict) == 0); - - - std::string str; - for (size_t c = 0; c < GUF_STR_SSO_BUF_CAP * 4; ++c) { - str += c % 2 ? "AAA" : "aaa"; - } - - guf_str str_cpy = guf_str_new(guf_str_view{.str = str.data(), .len = (ptrdiff_t)str.size()}, &allocator); - dict_str_i32_insert_val_arg(&word_cnt_dict_str, str_cpy, 42, GUF_CPY_DEEP, GUF_CPY_VALUE); - int32_t *foo = dict_str_i32_at_val_arg(&word_cnt_dict_str, guf_str_new_readonly(guf_str_view_from_str(&str_cpy))); - if (TEST_CHECK(foo)) { - TEST_CHECK(*foo == 42); - } - guf_str_append(&str_cpy, GUF_CSTR_LIT_TO_VIEW_CPP("Foobar")); - int32_t *foo2 = dict_str_i32_at_val_arg(&word_cnt_dict_str, guf_str_new_readonly(guf_str_view{.str = str.data(), .len = (ptrdiff_t)str.size()})); - if (TEST_CHECK(foo2)) { - TEST_CHECK(*foo2 == 42); - } - - guf_str_free(&str_cpy, NULL); - - dict_sv_i32_free(&word_cnt_dict, NULL); - dict_str_i32_free(&word_cnt_dict_str, NULL); - - bool dbuf_null = !word_cnt_dict.kv_elems.data && !word_cnt_dict.kv_elems.allocator && !word_cnt_dict.kv_elems.capacity && !word_cnt_dict.kv_elems.size; - TEST_CHECK(dbuf_null && !word_cnt_dict.kv_indices && !word_cnt_dict.kv_indices_cap && !word_cnt_dict.max_probelen && !word_cnt_dict.num_tombstones); -} - -bool DictSvToIntTest::load_file(const char *fname) -{ - FILE *in_file {nullptr}; - if (!in_file) { - in_file = fopen(fname, "r"); - } - - GUF_ASSERT_RELEASE(in_file); - - dbuf_char_init(&text_buf, 128, &allocator); - - int c = EOF; - while ((c = fgetc(in_file)) != EOF) { - dbuf_char_push_val(&text_buf, (char)c); - text_vec.push_back((char)c); - } - fclose(in_file); - - // dbuf_char_insert_val(&text_buf, '\xC0', 1); - // text_vec.insert(text_vec.cbegin() + 1, '\xC0'); - - return TEST_CHECK(std::ssize(text_vec) == text_buf.size); -} - -void DictSvToIntTest::free_file() -{ - dbuf_char_free(&text_buf, NULL); - text_buf = {}; - text_vec.clear(); -} diff --git a/libguf/test/test_dict.hpp b/libguf/test/test_dict.hpp deleted file mode 100755 index da51229..0000000 --- a/libguf/test/test_dict.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include -#include -#include "test.hpp" - -extern "C" -{ - #include "impls/dbuf_impl.h" - #include "guf_alloc_libc.h" -} - -struct DictSvToIntTest : public Test -{ - DictSvToIntTest(const std::string& nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 3, "DictSvToIntTest_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - }; - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - dbuf_char text_buf {}; - std::vector text_vec {}; - - bool load_file(const char *fname); - void free_file(); - - void insert_lookup(std::optional inital_dict_cap = {}); -}; diff --git a/libguf/test/test_str.cpp b/libguf/test/test_str.cpp deleted file mode 100755 index 9f816da..0000000 --- a/libguf/test/test_str.cpp +++ /dev/null @@ -1,379 +0,0 @@ -#include "test_str.hpp" -extern "C" -{ - #include "guf_alloc_libc.h" -} - -/* - StrTest: -*/ - -void StrTest::run() -{ - if (done) { - return; - } - - const std::vector words = { - "", - "\0", - "Hello", - "Othell\0o", - "f\0\0", - "\0", - "0", - "a", - "ab", - "🌈 waow a rainboge!", - "orange cat(1) :3", - "xes yag", - "Hello, world! This is a pretty darn long string I'd say...", - "I want to eat crayons. I crave crayons because they are tasty, and everybody telling me crayons are not edible must be either lying or dumb. I like trains. 42 is a number. 3.14159265... is not a rational number, and it is called pi. I ate some pie (it was a crayon pie).", - std::string(32, 'a'), - std::string(64, 'b'), - std::string(1024, 'a'), - std::string(2048, 'a'), - std::string(4096, 'a'), - std::string(5001, 'a'), - std::string(7121, 'a'), - std::string(2000, 'a'), - std::string(GUF_STR_SSO_BUF_CAP, 'a'), - std::string(GUF_STR_SSO_BUF_CAP - 1, 'a'), - std::string(GUF_STR_SSO_BUF_CAP + 1, 'a'), - std::string(GUF_STR_SSO_BUF_CAP - 2, 'a'), - std::string(GUF_STR_SSO_BUF_CAP + 2, 'a'), - std::string(GUF_STR_SSO_BUF_CAP - 3, 'a'), - std::string(GUF_STR_SSO_BUF_CAP + 3, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 2, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 3, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 4, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 5, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 6, 'a'), - std::string(GUF_STR_SSO_BUF_CAP * 7, 'a'), - }; - - - push_check_name("init_empy"); - test_init_empty(); - pop_check_name(); - - push_check_name("append_char"); - for (const auto& word : words) { - test_init_free(word); - test_append_char(word); - test_append_char(word, true); - } - pop_check_name(); - - push_check_name("append_str"); - for (size_t i = 0; i < words.size(); ++i) { - const auto& w1 = words.at(i); - append_str(w1, w1); - append_str(w1, w1); - for (size_t j = i + 1; j < words.size(); ++j) { - const auto& w2 = words.at(j); - append_str(w1, w2); - append_str(w2, w1); - } - } - pop_check_name(); - - push_check_name("test_popsplit"); - std::vector split = test_popsplit("1997-04-01", "-"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "1997" && split.at(1) == "04" && split.at(2) == "01"); - } - split = test_popsplit("1997-04-01-", "-"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "1997" && split.at(1) == "04" && split.at(2) == "01"); - } - - split = test_popsplit("2025/05/08", "/"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "2025" && split.at(1) == "05" && split.at(2) == "08"); - } - split = test_popsplit("2025/05/08/", "/"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "2025" && split.at(1) == "05" && split.at(2) == "08"); - } - split = test_popsplit("2025/05/08//", "/"); - if (TEST_CHECK(split.size() == 4)) { - TEST_CHECK(split.at(0) == "2025" && split.at(1) == "05" && split.at(2) == "08" && split.at(3) == ""); - } - - split = test_popsplit("/2025/05/08", "/"); - if (TEST_CHECK(split.size() == 4)) { - TEST_CHECK(split.at(0) == "" && split.at(1) == "2025" && split.at(2) == "05" && split.at(3) == "08"); - } - split = test_popsplit("//2025/05/08", "/"); - if (TEST_CHECK(split.size() == 5)) { - TEST_CHECK(split.at(0) == "" && split.at(1) == "" && split.at(2) == "2025" && split.at(3) == "05" && split.at(4) == "08"); - } - - split = test_popsplit("I eat formidable crayons, oof, for real", "foo"); - if (TEST_CHECK(split.size() == 1)) { - TEST_CHECK(split.at(0) == "I eat formidable crayons, oof, for real"); - } - - split = test_popsplit("Hej <<", "<<"); - if (TEST_CHECK(split.size() == 1)) { - TEST_CHECK(split.at(0) == "Hej "); - } - split = test_popsplit("Hej << verden", "<<"); - if (TEST_CHECK(split.size() == 2)) { - TEST_CHECK(split.at(0) == "Hej " && split.at(1) == " verden"); - } - split = test_popsplit("<< Hej << verden", "<<"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "" && split.at(1) == " Hej " && split.at(2) == " verden"); - } - split = test_popsplit("<< Hej << verden <<< foo<>", "<<"); - if (TEST_CHECK(split.size() == 4)) { - TEST_CHECK(split.at(0) == "" && split.at(1) == " Hej " && split.at(2) == " verden " && split.at(3) == "< foo<>"); - } - - split = test_popsplit("I eat tofu", ""); - if (TEST_CHECK(split.size() == 1)) { - TEST_CHECK(split.at(0) == "I eat tofu"); - } - - split = test_popsplit("At 3 a.m. during FULL-moon FULL-STOP Next to the public-library's -STOP sign FULL-STOP", "FULL-STOP"); - if (TEST_CHECK(split.size() == 2)) { - TEST_CHECK(split.at(0) == "At 3 a.m. during FULL-moon " && split.at(1) == " Next to the public-library's -STOP sign "); - } - split = test_popsplit("At 3 a.m. during FULL-moon FULL-STOP Next to the public-library's -STOP sign FULL-STOPI like trains, FULL-STO", "FULL-STOP"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "At 3 a.m. during FULL-moon " && split.at(1) == " Next to the public-library's -STOP sign " && split.at(2) == "I like trains, FULL-STO"); - } - split = test_popsplit("At 3 a.m. during FULL-moon FULL-STOP Next to the public-library's -STOP sign FULL-STOPI like trains, FULL-STO Poo", "FULL-STOP"); - if (TEST_CHECK(split.size() == 3)) { - TEST_CHECK(split.at(0) == "At 3 a.m. during FULL-moon " && split.at(1) == " Next to the public-library's -STOP sign " && split.at(2) == "I like trains, FULL-STO Poo"); - } - pop_check_name(); - - push_check_name("get_toks"); - std::vector tok_words = {"hello", "world", "cat", "vertex", "normal", "pizza", "running", "mouse", "playing", "adjacent"}; - std::vector delims = {",", " ", "\n", "\t", "\r"}; - - for (int is_trailing = 0; is_trailing < 2; ++is_trailing) { - for (ptrdiff_t num_words = 1; num_words < std::ssize(tok_words); ++num_words) { - std::string str = ""; - for (ptrdiff_t j = 0; j < num_words; ++j) { - str += tok_words.at(j); - if (j < num_words - 1 || is_trailing) { - str += ", "; - } - } - std::vector toks = get_toks(std::string_view{str}, delims, false, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - if (TEST_CHECK(std::ssize(toks) == num_words)) { - for (ptrdiff_t i = 0; i < num_words; ++i) { - TEST_CHECK(toks.at(i) == tok_words.at(i)); - } - } - } - } - - std::string_view tok_str = "age: 28, occupation: NULL, crayons_eaten: 256 "; - delims = {"", "", ":", ",", " ", "\t", "", "" && tok_result.at(0) == "" && tok_result.at(1) == "age" && tok_result.at(2) == ":" && tok_result.at(3) == " " && tok_result.at(4) == "28"); - - tok_result = get_toks(tok_str, delims, false, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - TEST_CHECK(tok_result.size() == 6); - TEST_CHECK(tok_result.at(0) == "age" && tok_result.at(1) == "28" && tok_result.at(2) == "occupation" && tok_result.at(3) == "NULL" && - tok_result.at(4) == "crayons_eaten" && tok_result.at(5) == "256"); - pop_check_name(); - - // guf_alloc_tracker_print(&allocator_ctx.tracker, NULL); - TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker)); -} - - -void StrTest::test_init_free(std::string str) -{ - guf_str s0; - guf_str_init(&s0, GUF_CSTR_TO_VIEW_CPP(str.c_str()), &allocator); - guf_str s1 = guf_str_new(GUF_CSTR_TO_VIEW_CPP(str.c_str()), &allocator); - guf_str s2; - guf_str_init_from_cstr(&s2, str.c_str(), &allocator); - - TEST_CHECK(guf_str_equal(&s0, &s1)); - TEST_CHECK(guf_str_equal(&s0, &s2)); - TEST_CHECK(guf_str_equal(&s1, &s2)); - - TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s0)); - TEST_CHECK(str == guf_str_const_cstr(&s0)); - TEST_CHECK(str == guf_str_cstr(&s0)); - - TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s1)); - TEST_CHECK(str == guf_str_const_cstr(&s1)); - TEST_CHECK(str == guf_str_cstr(&s1)); - - TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s2)); - TEST_CHECK(str == guf_str_const_cstr(&s2)); - TEST_CHECK(str == guf_str_cstr(&s2)); - - guf_str_free(&s0, NULL); - guf_str_free(&s1, NULL); - guf_str_free(&s2, NULL); - TEST_CHECK(guf_str_is_uninit(&s0)); - TEST_CHECK(guf_str_is_uninit(&s1)); - TEST_CHECK(guf_str_is_uninit(&s2)); -} - -void StrTest::test_init_empty() -{ - std::string str = ""; - guf_str s = GUF_STR_UNINITIALISED_CPP; - guf_str_init_empty(&s, &allocator); - TEST_CHECK(guf_str_len(&s) == 0); - TEST_CHECK(str == guf_str_const_cstr(&s)); - - guf_str_append_char(&s, 'a', 1024); - str.append(1024, 'a'); - TEST_CHECK(guf_str_len(&s) == (ptrdiff_t)str.size()); - TEST_CHECK(guf_str_const_cstr(&s) == str); - - guf_str_append_char(&s, 'b', 24); - str.append(24, 'b'); - TEST_CHECK(guf_str_len(&s) == (ptrdiff_t)str.size()); - TEST_CHECK(guf_str_const_cstr(&s) == str); - - guf_str_append_char(&s, 'c', 255); - str.append(255, 'c'); - TEST_CHECK(guf_str_len(&s) == (ptrdiff_t)str.size()); - TEST_CHECK(guf_str_const_cstr(&s) == str); - - *guf_str_at(&s, 0) = '<'; - str.at(0) = '<'; - TEST_CHECK(guf_str_len(&s) == (ptrdiff_t)str.size()); - TEST_CHECK(guf_str_const_cstr(&s) == str); - - *guf_str_at(&s, guf_str_len(&s) - 1) = '>'; - str.at(str.size() - 1) = '>'; - TEST_CHECK(guf_str_len(&s) == (ptrdiff_t)str.size()); - TEST_CHECK(guf_str_const_cstr(&s) == str); - - guf_err err = GUF_ERR_NONE; - TEST_CHECK(NULL == guf_str_try_at(&s, guf_str_len(&s), &err)); - TEST_CHECK(err != GUF_ERR_NONE && err == GUF_ERR_IDX_RANGE); - err = GUF_ERR_NONE; - TEST_CHECK(NULL == guf_str_try_at(&s, -1, &err)); - TEST_CHECK(err != GUF_ERR_NONE && err == GUF_ERR_IDX_RANGE); - - guf_str_free(&s, NULL); - TEST_CHECK(guf_str_is_uninit(&s)); -} - -void StrTest::test_append_char(std::string str, bool include_null) -{ - guf_str s0 = guf_str_new(guf_str_view{.str = str.c_str(), .len = (ptrdiff_t)str.size()}, &allocator); - - TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s0)); - TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - - for (int i = include_null ? 0 : 1; i < 128; ++i) { - char ch = (char)i; - guf_str_append_one_char(&s0, ch); - str.append(1, ch); - TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str.size()); - TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - } - - for (int i = include_null ? 0 : 1; i < 128; ++i) { - char ch = (char)i; - guf_str_append_char(&s0, ch, i); - str.append(i, ch); - TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str.size()); - TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - guf_str_append_char(&s0, ch, i * 16); - str.append(i * 16, ch); - TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str.size()); - TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - } - - guf_str_free(&s0, NULL); - TEST_CHECK(guf_str_is_uninit(&s0)); -} - -void StrTest::append_str(const std::string& a, const std::string& b) -{ - std::string str0 = a; - guf_str s0 = guf_str_new(guf_str_view{.str = str0.c_str(), .len = (ptrdiff_t)str0.size()}, &allocator); - TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str0.size()); - TEST_CHECK((str0 == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - TEST_CHECK((str0 == std::string_view{guf_str_cstr(&s0), (size_t)guf_str_len(&s0)})); - - for (int i = 0; i <= 64; ++i) { - str0.append(b); - guf_str_append(&s0, guf_str_view{.str = b.c_str(), .len = (ptrdiff_t)b.size()}); - TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str0.size()); - TEST_CHECK((str0 == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); - TEST_CHECK((str0 == std::string_view{guf_str_cstr(&s0), (size_t)guf_str_len(&s0)})); - } - - guf_str_free(&s0, NULL); - TEST_CHECK(guf_str_is_uninit(&s0)); -} - -std::vector StrTest::test_popsplit(std::string_view str, std::string_view delim) -{ - std::vector result = {}; - - if (delim.size() > 0) { // NOTE: str.find with an empty delimiter returns 0, not std::string::npos - std::string_view src_cpp = str; - for (size_t idx = src_cpp.find(delim, 0); src_cpp.size() > 0; idx = src_cpp.find(delim, 0)) { - result.push_back(src_cpp.substr(0, idx)); - if (idx == std::string::npos) { - break; - } - src_cpp = src_cpp.substr(idx + delim.size()); - } - } else { - result.push_back(str); - } - - - const guf_str_view delim_sv = guf_str_view{.str = delim.data(), .len = (ptrdiff_t)delim.size()}; - guf_str_view src = guf_str_view{.str = str.data(), .len = (ptrdiff_t)str.size()}; - size_t n = 0; - do { - const guf_str_view popped = guf_str_view_pop_split(&src, delim_sv); - TEST_CHECK(n < result.size()); - TEST_CHECK(std::string_view(popped.str, (size_t)popped.len) == result.at(n)); - const guf_str_view res = {.str = result.at(n).data(), .len = (ptrdiff_t)result.at(n).size()}; - TEST_CHECK(guf_str_view_equal(&popped, &res)); - TEST_CHECK(guf_str_view_equal_val_arg(popped, res)); - // std::cout << "guf: " << std::string_view{popped.str, (size_t)popped.len} << "\n"; - // std::cout << "cpp: " << std::string_view{res.str, (size_t)res.len} << "\n"; - ++n; - } while (src.len > 0); - TEST_CHECK(n == result.size()); - - return result; -} - -std::vector StrTest::get_toks(std::string_view sv_in, const std::vector& delims_in, bool preserve_delims, guf_str_tok_delim_opt opt) -{ - const guf_str_view sv = guf_str_view{.str = sv_in.data(), .len = (ptrdiff_t)sv_in.size()}; - std::vector delims; - for (const auto delim : delims_in) { - delims.push_back(guf_str_view{.str = delim.data(), .len = (ptrdiff_t)delim.size()}); - } - guf_str_tok_state tok_state = guf_str_tok_state_new(sv, delims.data(), std::ssize(delims), opt); - - std::vector toks_out; - while (guf_str_tok_next(&tok_state, preserve_delims)) { - if (tok_state.cur_tok.len > 0) { - toks_out.push_back( std::string_view{tok_state.cur_tok.str, (size_t)tok_state.cur_tok.len}); - } - if (preserve_delims && tok_state.cur_delim.len > 0) { - toks_out.push_back( std::string_view{tok_state.cur_delim.str, (size_t)tok_state.cur_delim.len}); - } - } - TEST_CHECK(tok_state.done); - const ptrdiff_t num_toks = preserve_delims ? tok_state.num_delims_read + tok_state.num_toks_read : tok_state.num_toks_read; - TEST_CHECK(num_toks == std::ssize(toks_out)); - return toks_out; -} diff --git a/libguf/test/test_str.hpp b/libguf/test/test_str.hpp deleted file mode 100755 index 6153700..0000000 --- a/libguf/test/test_str.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include "test.hpp" -extern "C" -{ - #include "guf_str.h" - #include "guf_alloc_libc.h" -} - -struct StrTest : public Test -{ - StrTest(const std::string& nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 4, "StrTest_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - }; - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - void test_init_free(std::string str); - void test_init_empty(); - void test_append_char(std::string str, bool include_null = false); - void append_str(const std::string& a, const std::string& b); - std::vector test_popsplit(std::string_view str, std::string_view delim); - std::vector get_toks(std::string_view sv_in, const std::vector& delims_in, bool preserve_delims = false, guf_str_tok_delim_opt opt = GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); -}; diff --git a/libguf/test/test_utf8.cpp b/libguf/test/test_utf8.cpp deleted file mode 100755 index 3294070..0000000 --- a/libguf/test/test_utf8.cpp +++ /dev/null @@ -1,387 +0,0 @@ -#include "test_utf8.hpp" -extern "C" -{ - #include "guf_alloc_libc.h" - #include "guf_str.h" - #include "impls/dict_impl.h" -} - -/* - UTF8Test: -*/ - -void UTF8Test::run() -{ - if (done) { - return; - } - - push_check_name("read_utf8_chars"); - ptrdiff_t valid = 0, invalid = 0; - read_utf8_chars(TEST_DATA_DIR "/" "utf8-test.txt", &valid, &invalid); - TEST_CHECK(valid == 2635 && invalid == 0); - read_utf8_chars(TEST_DATA_DIR "/" "bartleby.txt", &valid, &invalid); - TEST_CHECK(valid > 16000 && invalid == 0); - pop_check_name(); - - push_check_name("count_words"); - dbuf_str_view delims = dbuf_str_view_new(&allocator); - for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) { - guf_str_view d = {.str = GUF_UTF8_WHITESPACE[i], .len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i])}; - dbuf_str_view_push_val(&delims, d); - } - for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_COMMON_PUNCT); ++i) { - guf_str_view d = {.str = GUF_UTF8_COMMON_PUNCT[i], .len = (ptrdiff_t)strlen(GUF_UTF8_COMMON_PUNCT[i])}; - dbuf_str_view_push_val(&delims, d); - } - int words = count_words(TEST_DATA_DIR "/" "utf8-test.txt", &delims); - TEST_CHECK(words == 422); - int words_with_delims = count_words_with_delims(TEST_DATA_DIR "/" "utf8-test.txt", &delims); - TEST_CHECK(words_with_delims == 950); - - int words2 = count_words(TEST_DATA_DIR "/" "bartleby.txt", &delims); - TEST_CHECK(words2 > 2048); - - dbuf_str_view_free(&delims, NULL); - pop_check_name(); - - push_check_name("encode_decode"); - encode_decode(); - encode_decode_file(TEST_DATA_DIR "/" "utf8-test.txt"); - encode_decode_file(TEST_DATA_DIR "/" "bartleby.txt"); - pop_check_name(); - - //guf_alloc_tracker_print(&allocator_ctx.tracker, NULL); - TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker)); -} - - -bool UTF8Test::load_text(const char *fname) -{ - FILE *in_file {nullptr}; - if (!in_file) { - in_file = fopen(fname, "r"); - } - - if (!in_file) { - return false; - } - - dbuf_char_init(&text_buf, 128, &allocator); - - int c = EOF; - while ((c = fgetc(in_file)) != EOF) { - dbuf_char_push_val(&text_buf, (char)c); - text_vec.push_back((char)c); - } - fclose(in_file); - - return TEST_CHECK(std::ssize(text_vec) == text_buf.size); -} - -void UTF8Test::free_text() -{ - dbuf_char_free(&text_buf, NULL); - text_vec.clear(); -} - - -void UTF8Test::read_utf8_chars(const char *fname, ptrdiff_t *n_valid, ptrdiff_t *n_invalid) -{ - GUF_ASSERT_RELEASE(load_text(fname)); - - ptrdiff_t valid_chars = 0, invalid_chars = 0, bytes = 0; - guf_str_view input_str = {.str = text_buf.data, .len = text_buf.size}; - guf_utf8_char ch = {}; - for (guf_utf8_stat stat = guf_utf8_char_next(&ch, &input_str); stat != GUF_UTF8_READ_DONE; stat = guf_utf8_char_next(&ch, &input_str)) { - if (stat == GUF_UTF8_READ_VALID) { - ++valid_chars; - // printf("%s", ch.bytes); - } else { - ++invalid_chars; - // printf("::INVALID_UTF8_CHAR::"); - } - bytes += guf_utf8_char_num_bytes(&ch); - } - TEST_CHECK(input_str.len == 0 && input_str.str == NULL); - TEST_CHECK(bytes == text_buf.size); - - // printf("\nread %td bytes\n", bytes); - // printf("read %td valid and %td invalid utf-8 characters\n", valid_chars, invalid_chars); - - free_text(); - - if (n_valid) - *n_valid = valid_chars; - if (n_invalid) - *n_invalid = invalid_chars; -} - -int UTF8Test::count_words(const char *fname, const dbuf_str_view *delims) -{ - GUF_ASSERT_RELEASE(load_text(fname)); - - int num_words = 0; - - guf_str_tok_state tok_state = guf_str_tok_state_new(guf_str_view{.str = text_buf.data, .len = text_buf.size}, delims->data, delims->size, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - while (guf_str_tok_next(&tok_state, false)) { - TEST_CHECK(tok_state.cur_tok.len > 0); - ++num_words; - } - - free_text(); - return num_words; -} - -int UTF8Test::count_words_with_delims(const char *fname, const dbuf_str_view *delims) -{ - GUF_ASSERT_RELEASE(load_text(fname)); - - int num_words = 0, num_delims = 0; - guf_str_tok_state tok_state = guf_str_tok_state_new(guf_str_view{.str = text_buf.data, .len = text_buf.size}, delims->data, delims->size, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST); - while (guf_str_tok_next(&tok_state, true)) { - if (tok_state.cur_tok.len) { - ++num_words; - // printf("'%.*s'\n", (int)tok_state.cur_tok.len, tok_state.cur_tok.str); - } - if (tok_state.cur_delim.len) { - ++num_delims; - // if (tok_state.cur_delim.str[0] == '\n') - // printf("'\\n'\n"); - // else - // printf("'%.*s'\n", (int)tok_state.cur_delim.len, tok_state.cur_delim.str); - } - } - free_text(); - return num_words + num_delims; -} - -void UTF8Test::encode_decode_file(const char *fname) -{ - GUF_ASSERT_RELEASE(load_text(fname)); - - dbuf_i32 cp_buf = dbuf_i32_new(&allocator); - - ptrdiff_t valid_chars = 0, invalid_chars = 0; - guf_str_view input_str = {.str = text_buf.data, .len = text_buf.size}; - guf_utf8_char ch = {}; - for (guf_utf8_stat stat = guf_utf8_char_next(&ch, &input_str); stat != GUF_UTF8_READ_DONE; stat = guf_utf8_char_next(&ch, &input_str)) { - if (stat == GUF_UTF8_READ_VALID) { - ++valid_chars; - const int32_t codepoint = guf_utf8_decode(&ch); - TEST_CHECK(codepoint >= 0); - dbuf_i32_push_val(&cp_buf, codepoint); - } else { - ++invalid_chars; - const int32_t codepoint = guf_utf8_decode(&ch); - TEST_CHECK(codepoint < 0); - dbuf_i32_push_val(&cp_buf, -1); - } - } - TEST_CHECK(cp_buf.size == valid_chars + invalid_chars); - - guf_str_view in_str = {.str = text_buf.data, .len = text_buf.size}; - GUF_CNT_FOREACH(&cp_buf, dbuf_i32, it) { - GUF_ASSERT_RELEASE(it.ptr); - const int32_t codepoint = *it.ptr; - guf_utf8_char utf8_ch = {}; - const guf_utf8_stat stat = guf_utf8_char_next(&utf8_ch, &in_str); - if (codepoint >= 0) { - TEST_CHECK(stat == GUF_UTF8_READ_VALID); - guf_utf8_char encoded_ch = {}; - TEST_CHECK(guf_utf8_encode(&encoded_ch, codepoint)); - TEST_CHECK(guf_utf8_equal(&encoded_ch, &utf8_ch)); - } - } - guf_utf8_char utf8_ch = {}; - const guf_utf8_stat stat = guf_utf8_char_next(&utf8_ch, &in_str); - TEST_CHECK(stat == GUF_UTF8_READ_DONE); - - dbuf_i32_free(&cp_buf, NULL); - - free_text(); -} - -void UTF8Test::encode_decode() -{ - guf_utf8_char utf8 = {0}; - - // 1 byte characters. - for (uint8_t ascii = 0; ascii <= 0x7F; ++ascii) { - TEST_CHECK(guf_utf8_encode(&utf8, ascii)); - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 1); - TEST_CHECK(utf8.bytes[0] == ascii); - TEST_CHECK(utf8.bytes[1] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == ascii); - } - - // 2 byte characters: - TEST_CHECK(guf_utf8_encode(&utf8, 0x00E6)); // "æ" (Latin Small Letter Ae) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xA6'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00E6); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00E5)); // "å" (Latin Small Letter A with Ring Above) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xA5'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00E5); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00F8)); // "ø" (Latin Small Letter O with Stroke) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xB8'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00F8); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00E4)); // "ä" (Latin Small Letter A with Diaeresis) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xA4'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00E4); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00F6)); // "ö" (Latin Small Letter O with Diaeresis) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xB6'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00F6); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00D6)); // "Ö" (Latin Capital Letter O with Diaeresis) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\x96'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00D6); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00FC)); // "ü" (Latin Small Letter U with Diaeresis) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC3' && utf8.bytes[1] == '\xBC'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00FC); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x00B5)); // "µ" (Micro Sign) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xC2' && utf8.bytes[1] == '\xB5'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x00B5); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x030A)); // "◌̊" (Combining Ring Above) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 2); - TEST_CHECK(utf8.bytes[0] == '\xCC' && utf8.bytes[1] == '\x8A'); - TEST_CHECK(utf8.bytes[2] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x030A); - - // 3 byte characters: - TEST_CHECK(guf_utf8_encode(&utf8, 0x7121)); // "無" (Nothingness; CJK Unified Ideograph-7121) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(!guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(utf8.bytes[0] == '\xE7' && utf8.bytes[1] == '\x84' && utf8.bytes[2] == '\xA1'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x7121); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x201E)); // "„" (Double Low-9 Quotation Mark) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(!guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(utf8.bytes[0] == '\xE2' && utf8.bytes[1] == '\x80' && utf8.bytes[2] == '\x9E'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x201E); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x20AC)); // "€" (Euro Sign) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(!guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(utf8.bytes[0] == '\xE2' && utf8.bytes[1] == '\x82' && utf8.bytes[2] == '\xAC'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x20AC); - - TEST_CHECK(guf_utf8_encode(&utf8, 0xFC51)); // "ﱑ" (Arabic Ligature Heh with Jeem Isolated Form) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(!guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(utf8.bytes[0] == '\xEF' && utf8.bytes[1] == '\xB1' && utf8.bytes[2] == '\x91'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0xFC51); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x1AA3)); // "᪣" (Tai Tham Sign Keow) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(!guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(utf8.bytes[0] == '\xE1' && utf8.bytes[1] == '\xAA' && utf8.bytes[2] == '\xA3'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x1AA3); - - TEST_CHECK(guf_utf8_encode(&utf8, GUF_UTF8_REPLACEMENT_CHAR_CODEPOINT)); // "�" (Replacement Character) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 3); - TEST_CHECK(utf8.bytes[0] == '\xEF' && utf8.bytes[1] == '\xBF' && utf8.bytes[2] == '\xBD'); - TEST_CHECK(utf8.bytes[3] == '\0'); - TEST_CHECK(guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(guf_utf8_decode(&utf8) == GUF_UTF8_REPLACEMENT_CHAR_CODEPOINT); - - // 4 byte characters: - TEST_CHECK(guf_utf8_encode(&utf8, 0x1F308)); // "🌈" (Rainbow) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 4); - TEST_CHECK(utf8.bytes[0] == '\xF0' && utf8.bytes[1] == '\x9F' && utf8.bytes[2] == '\x8C' && utf8.bytes[3] == '\x88'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x1F308); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x130B8)); // "𓂸" (Egyptian Hieroglyph D052) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 4); - TEST_CHECK(utf8.bytes[0] == '\xF0' && utf8.bytes[1] == '\x93' && utf8.bytes[2] == '\x82' && utf8.bytes[3] == '\xB8'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x130B8); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x1F97A)); // "🥺" (Face with Pleading Eyes) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 4); - TEST_CHECK(utf8.bytes[0] == '\xF0' && utf8.bytes[1] == '\x9F' && utf8.bytes[2] == '\xA5' && utf8.bytes[3] == '\xBA'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x1F97A); - - TEST_CHECK(guf_utf8_encode(&utf8, 0x1F980)); // "🦀" (Crab) - TEST_CHECK(guf_utf8_char_num_bytes(&utf8) == 4); - TEST_CHECK(utf8.bytes[0] == '\xF0' && utf8.bytes[1] == '\x9F' && utf8.bytes[2] == '\xA6' && utf8.bytes[3] == '\x80'); - TEST_CHECK(guf_utf8_decode(&utf8) == 0x1F980); - - // Invalid characters: - utf8 = {.bytes = {'\xC0', '\x80', 0, 0}}; - TEST_CHECK(guf_utf8_decode(&utf8) < 0); - - utf8 = {.bytes = {'\xC0', 0, 0, 0}}; - TEST_CHECK(guf_utf8_decode(&utf8) < 0); - - utf8 = {.bytes = {'\x80', 0, 0, 0}}; - TEST_CHECK(guf_utf8_decode(&utf8) < 0); - - // "The definition of UTF-8 prohibits encoding character numbers between U+D800 and U+DFFF" (surrogate pairs). - TEST_CHECK(!guf_utf8_encode(&utf8, 0xD800)); - TEST_CHECK(guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(guf_utf8_decode(&utf8) == GUF_UTF8_REPLACEMENT_CHAR_CODEPOINT); - - TEST_CHECK(!guf_utf8_encode(&utf8, 0xDFFF)); - TEST_CHECK(guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(guf_utf8_decode(&utf8) == GUF_UTF8_REPLACEMENT_CHAR_CODEPOINT); - - TEST_CHECK(!guf_utf8_encode(&utf8, 0xDA00)); - TEST_CHECK(guf_utf8_equal(&utf8, &GUF_UTF8_REPLACEMENT_CHAR)); - TEST_CHECK(guf_utf8_decode(&utf8) == GUF_UTF8_REPLACEMENT_CHAR_CODEPOINT); - - char buf[] = {'\x2F', '\xC0', '\xAE', '\x2E', '\x2F'}; - guf_str_view input_str = {.str = buf, .len = GUF_ARR_SIZE(buf)}; - guf_utf8_char ch = {}; - int valid_chars = 0, invalid_chars = 0; - for (guf_utf8_stat stat = guf_utf8_char_next(&ch, &input_str); stat != GUF_UTF8_READ_DONE; stat = guf_utf8_char_next(&ch, &input_str)) { - if (stat == GUF_UTF8_READ_VALID) { - ++valid_chars; - } else { - ++invalid_chars; - } - } - TEST_CHECK(invalid_chars == 2 && valid_chars == 3); - - char buf2[] = {'\xE0', '\x80', 'a', 'b', 'c'}; // 1 invalid 3-byte-character, 2 valid 1-byte-characters - input_str = {.str = buf2, .len = GUF_ARR_SIZE(buf2)}; - ch = {}; - valid_chars = invalid_chars = 0; - for (guf_utf8_stat stat = guf_utf8_char_next(&ch, &input_str); stat != GUF_UTF8_READ_DONE; stat = guf_utf8_char_next(&ch, &input_str)) { - if (stat == GUF_UTF8_READ_VALID) { - // printf("%s", ch.bytes); - ++valid_chars; - } else { - // printf("%s", GUF_UTF8_REPLACEMENT_CHAR.bytes); - ++invalid_chars; - } - } - TEST_CHECK(invalid_chars == 1 && valid_chars == 2); -} diff --git a/libguf/test/test_utf8.hpp b/libguf/test/test_utf8.hpp deleted file mode 100755 index e6e6846..0000000 --- a/libguf/test/test_utf8.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include -#include "test.hpp" -extern "C" -{ - #include "impls/dbuf_impl.h" - #include "guf_alloc_libc.h" -} - -struct UTF8Test : public Test -{ - UTF8Test(const std::string& nm) : Test(nm) - { - allocator_ctx.zero_init = false; - guf_alloc_tracker_init(&allocator_ctx.tracker, 5, "UTF8Test_allocator", NULL, NULL); - guf_libc_allocator_init(&allocator, &allocator_ctx); - }; - - void run() override; - -private: - guf_allocator allocator; - guf_libc_alloc_ctx allocator_ctx; - - dbuf_char text_buf {}; - std::vector text_vec; - - bool load_text(const char *fname); - void free_text(); - - void read_utf8_chars(const char *fname, ptrdiff_t *n_valid, ptrdiff_t *n_invalid); - int count_words(const char *fname, const dbuf_str_view *delims); - int count_words_with_delims(const char *fname, const dbuf_str_view *delims); - void encode_decode_file(const char *fname); - void encode_decode(); -};