{"id":2930,"date":"2025-06-27T15:04:34","date_gmt":"2025-06-27T13:04:34","guid":{"rendered":"https:\/\/moijari.com\/?p=2930"},"modified":"2025-07-28T12:35:22","modified_gmt":"2025-07-28T10:35:22","slug":"sudokues-everywhere-summer-sudokues-new-hardest-steps-13-sudoku-found-revisiting-db8-db8-list-on-harder-sudokues-by-digits-and-by-steps-db8-source-trying-to-find-pi-using-pseudoressu-pseudo-rand","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=2930","title":{"rendered":"Sudokues everywhere: summer sudokues, new hardest steps 13 sudoku found, revisiting db8: db8 list on harder sudokues by digits and by steps, db8 source, db8 string pattern matching, trying to find pi using pseudoressu pseudo random bit generator"},"content":{"rendered":"\n<p>Suomessa lahjoituksen voi tehd\u00e4, mutta sit\u00e4 ei voi pyyt\u00e4\u00e4. Jos haluat lahjoittaa kuitenkin projektille, laita lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Jos lahjoitat sata euroa tai enemm\u00e4n ja haluat vastalahjan, voit saada vastalahjana sudokun tai t\u00e4m\u00e4nhetkisen sorsan. Vastalahjasudokua tai sorsaa varten kirjoita s\u00e4hk\u00f6postiviesti osoitteeseen moijaricom@gmail.com ja laita viestiin aiemmat pankkitapahtuman viestiss\u00e4 mainitut nimesi ja asuinpaikkakuntasi ja postiosoitteesi vastalahjan l\u00e4hetyst\u00e4 varten. Laita s\u00e4hk\u00f6postiviestin otsakkeeksi &#8220;vastalahjasudoku&#8221; tai &#8220;vastalahjasorsa&#8221;. L\u00e4het\u00e4n yhden sudokun jokaisesta sata euroa ylitt\u00e4v\u00e4st\u00e4 lahjoituksesta. Sorsa tulee tietenkin vain yhteen kertaan.<\/p>\n\n\n\n<p>My\u00f6s pienet lahjoitukset (euro tai kaksi) ovat tervetulleita. Itseasiassa optimi oisi kolme euroa kerran kuussa, kymmenell\u00e4 lahjoituksella saisin maksettua jo palvellimen kuukausimaksun. Toiset kymmenen lahjoitusta ostaisi koodausvissyt.. <\/p>\n\n\n\n<p>Kiitokset lahjoituksestasi.<\/p>\n\n\n\n<p>Edellinen artikkelini (<a href=\"https:\/\/moijari.com\/?p=1874\">https:\/\/moijari.com\/?p=1874<\/a>) oli mielest\u00e4ni paras t\u00e4h\u00e4n asti. Siin\u00e4 viimeisteltiin ressu satunnaisbittigeneraattori, tutkittiin sen satunnaisuutta, tehtiin sille liit\u00e4nn\u00e4isrutiineja: pseudoressu_bytes, ressutwist_bytes, stream_bytes, urandom_bytes. siin\u00e4 korjattiin pari bugia ressusta (+2-bugi ja bad for randomness bugi), ja mets\u00e4stettiin bugia exfat:ista. artikkelissa oli sudoku loppukevennys ja ensimm\u00e4inen versio db8:sta. Lis\u00e4ksi siin\u00e4 tehtiin komentorivi ohjelma newressu kaiken satunnaisuuden arvontaan.<\/p>\n\n\n\n<p>L\u00f6ysin uuden vaikean steps 13 sudokun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |           | 9       8 |         1 |\nB |           |     2     |     4   3 |\nC |           |     1     |     6   5 |\n  +-----------+-----------+-----------+\nD |         9 |     3   6 | 7         |\nE |           |           |           |\nF |         5 |           |     1   2 |\n  +-----------+-----------+-----------+\nG | 9   4   1 |     5     |     2     |\nH |     2   8 |           |           |\nI | 6         |           |     9     |\n  +-----------+-----------+-----------+\n  s:1 gu:93 st:13 ro:2 clues:25<\/code><\/pre>\n\n\n\n<p>Sitten sudokusarja kes\u00e4ksi: kopi pastaa n\u00e4m\u00e4 tekstink\u00e4sittelyyn (esimerkiksi libre office) ja esikatsele ja muuta fonttikokoa ja sarakkeita haluamallasi tavalla ja tulosta. Voit my\u00f6s joutua lis\u00e4\u00e4m\u00e4\u00e4n tyhji\u00e4 rivej\u00e4 sudokujen v\u00e4liin.<\/p>\n\n\n\n<p>Lis\u00e4\u00e4 sudokuja l\u00f6ytyy edelllisest\u00e4 artikkelista (<a href=\"https:\/\/moijari.com\/?p=1874\">https:\/\/moijari.com\/?p=1874<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     7     |     1     |     5   6 |\nB |     2   9 | 4   8     | 1   3   7 |\nC |         1 | 9         | 2       4 |\n  +-----------+-----------+-----------+\nD | 7         |           | 8   6     |\nE |     6   8 | 7   9     | 4   2   3 |\nF | 4   1   3 | 6   2     | 5   7   9 |\n  +-----------+-----------+-----------+\nG |         5 | 8   4     |     1   2 |\nH |           |     7     |           |\nI |           | 5   3   2 | 6   9   8 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:45\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7   9   2 | 4       3 |         5 |\nB | 4   5   6 | 9   8     |     3     |\nC | 8       1 | 2         | 9   6     |\n  +-----------+-----------+-----------+\nD |         3 |           |           |\nE | 5         |     9     |     2   7 |\nF | 2   1   7 |         8 |     4   9 |\n  +-----------+-----------+-----------+\nG | 1   8     | 6   2   9 | 4   7   3 |\nH |           |           | 2   5   6 |\nI | 6       4 | 5         | 1       8 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:44\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4   6 |           |     2     |\nB | 8   2   7 |           |         3 |\nC | 1       3 | 6         | 9       4 |\n  +-----------+-----------+-----------+\nD | 2   3   1 |     5   7 | 4       6 |\nE | 4   7   8 | 1   6     | 3   5   2 |\nF | 5       9 |           |     8   1 |\n  +-----------+-----------+-----------+\nG | 6   1     |     8     |           |\nH |           | 7         | 2       8 |\nI | 7         | 5   3   4 | 1       9 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:43\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 6   3   7 | 5   2   4 |         8 |\nB |     5   8 |     1   3 |         7 |\nC |         2 | 7         |     3     |\n  +-----------+-----------+-----------+\nD |     8     | 9       1 |     5   2 |\nE |     1     | 2         |         6 |\nF |         5 | 8   7   6 | 1       9 |\n  +-----------+-----------+-----------+\nG |         3 | 1   8   2 |           |\nH |           | 3   5   7 |     6   1 |\nI |     7     | 4   6   9 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:42\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3         |     4     | 6         |\nB | 5   1   2 | 8   6     | 3         |\nC | 7   6     |     3     | 1       5 |\n  +-----------+-----------+-----------+\nD |           |     9   2 | 4         |\nE |         5 |     7   1 |     9   3 |\nF |           |         4 |     1   6 |\n  +-----------+-----------+-----------+\nG |     7     | 4   2   6 |     3     |\nH | 4         | 9   1     | 7   2     |\nI |     2   3 | 7   5   8 |     6     |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:41\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     6     | 5   1   3 | 2   8   7 |\nB |     1     |     7   9 |         3 |\nC | 5   7     | 6         | 9   1   4 |\n  +-----------+-----------+-----------+\nD |     8   5 | 1         | 4         |\nE | 7   3     |           |           |\nF | 2       4 |     3     |         1 |\n  +-----------+-----------+-----------+\nG |         6 | 3         | 7       8 |\nH | 3   4   7 | 2       8 | 1   5     |\nI |           |         6 | 3         |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:40\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 2   1     | 3   8     |\nB | 3   2   6 |     8   9 | 4         |\nC | 8         |           |     2   6 |\n  +-----------+-----------+-----------+\nD | 7   4   8 |     5   3 |           |\nE | 2   3     |     9   7 | 1       8 |\nF |           |     4   2 | 7         |\n  +-----------+-----------+-----------+\nG | 5   8     | 4   7     | 6         |\nH | 1       2 |     6     | 8   3     |\nI |     9     |         8 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:39\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4   6     | 3       9 | 1         |\nB |         2 |           |         6 |\nC |         8 |         2 | 4   3   9 |\n  +-----------+-----------+-----------+\nD |     1     | 8   9   5 | 2   7   4 |\nE |     4     | 2       3 | 9         |\nF |           |         7 |     6   5 |\n  +-----------+-----------+-----------+\nG |     7     |           |     4   2 |\nH |     3     |     2   6 |     1     |\nI |     2   6 |         4 | 8   9     |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:38\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     5   9 |           |     4   2 |\nB | 7   3   1 |         2 | 9       8 |\nC |     6   4 |     8   7 |           |\n  +-----------+-----------+-----------+\nD | 6         |         9 |     8     |\nE | 5   2     |         1 |         9 |\nF |           | 7   6   5 |     3   4 |\n  +-----------+-----------+-----------+\nG |           |           | 5   9     |\nH | 4   7     |     9   6 |         3 |\nI | 9   1     | 3   7     |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:37\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         7 | 1   3     |           |\nB | 3         | 5       9 | 2   8   1 |\nC |     1   5 | 2         |     3   6 |\n  +-----------+-----------+-----------+\nD | 2         |         4 | 9       7 |\nE |     6   9 |     1     | 3         |\nF | 7         | 9         | 8       4 |\n  +-----------+-----------+-----------+\nG | 6         |     9   3 |         8 |\nH | 1   8     | 7       2 |     9   3 |\nI |           |           |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:36\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     9   1 | 3         |           |\nB |     3     | 1         |         2 |\nC |           | 7       4 |           |\n  +-----------+-----------+-----------+\nD | 6   4   5 | 2       7 |     8   9 |\nE |           |           | 7   4   5 |\nF | 9       7 |           |           |\n  +-----------+-----------+-----------+\nG | 3   6   2 |         1 | 9   5     |\nH |           | 8       3 |           |\nI | 8   7   4 |     5   6 | 2       3 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:4 clues:35\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4   9   8 |     1     | 7   3     |\nB | 7         |         9 |         6 |\nC |         1 | 7         | 9         |\n  +-----------+-----------+-----------+\nD |     5     |     9     |     1     |\nE |     2     | 5         |           |\nF |           | 6       1 | 8   5     |\n  +-----------+-----------+-----------+\nG |     1   2 |         4 | 5   7     |\nH |           |     2   7 | 6         |\nI | 9       4 |     6   5 |         1 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:2 clues:34\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1     |           |           |\nB |           | 4   9     |         3 |\nC | 3         | 8         |     4   2 |\n  +-----------+-----------+-----------+\nD |           | 5       6 |     1     |\nE |           | 9   3     | 7       6 |\nF |     5     |     2     | 4   3     |\n  +-----------+-----------+-----------+\nG |     2   3 |     4   8 |     9     |\nH |     4   5 | 3   7   2 |     6   1 |\nI |         6 |           |         4 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:33\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 4         |           |\nB | 3       2 |           | 7   4     |\nC | 4   6     |           |     3   8 |\n  +-----------+-----------+-----------+\nD |           |     2   4 |     8     |\nE |     8     | 1   5     |         9 |\nF |           |         9 |           |\n  +-----------+-----------+-----------+\nG | 8   1   3 |     7   2 | 6       4 |\nH | 6       9 |         1 |     7     |\nI |     5     |     4   8 | 1         |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:32\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         6 |           |           |\nB |           | 2       7 | 5   8     |\nC | 1         | 9         | 6       3 |\n  +-----------+-----------+-----------+\nD | 4         |     7   2 |           |\nE | 6         |           |     1     |\nF | 7   8   2 |     5   6 | 3         |\n  +-----------+-----------+-----------+\nG |         3 | 7       9 | 1       8 |\nH |     7     |     4     |           |\nI |     6     |         5 |     4   2 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:31\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3         | 4       9 |           |\nB |     7     |     5     |     2     |\nC |           |     8   2 |           |\n  +-----------+-----------+-----------+\nD |     8     | 9         |           |\nE | 4   2   1 |           |         9 |\nF |     9     | 3         | 1   6     |\n  +-----------+-----------+-----------+\nG | 8   1   6 |     9   5 | 4         |\nH |     3   7 |     6     |     8     |\nI |           |     3     |         1 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:3 clues:30\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8   1     |         7 |     5   9 |\nB | 9   4   2 |           |         7 |\nC |           | 8         |           |\n  +-----------+-----------+-----------+\nD | 5   3     |         6 | 9         |\nE |           |     7   3 | 6         |\nF |           | 2   5     |     4     |\n  +-----------+-----------+-----------+\nG |     9     |           | 5   3   1 |\nH |           |         4 | 2         |\nI |     2   5 |         9 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:4 clues:29\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     3     |           |         4 |\nB | 4   1     |         9 |           |\nC |           | 8   3     |           |\n  +-----------+-----------+-----------+\nD |     2     | 7   6   5 |     4     |\nE |           |           | 6         |\nF | 9         |           | 7   8     |\n  +-----------+-----------+-----------+\nG |     8   6 | 5   1     |     9     |\nH | 1   4     |     7   6 | 3         |\nI | 3         |         2 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:6 clues:28\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     3     |           |\nB |           |           | 9   6   5 |\nC |     4     |         5 |           |\n  +-----------+-----------+-----------+\nD | 5         | 1         | 2       7 |\nE |           |     7   4 |           |\nF |         9 |           |     1     |\n  +-----------+-----------+-----------+\nG | 9         |           |           |\nH |     6   1 | 7         |     3     |\nI | 3   7   2 | 9   8     | 6   5   4 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:4 clues:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         9 | 1         |         2 |\nB |     7     | 3         |     9   6 |\nC |           | 6   7     | 4   8     |\n  +-----------+-----------+-----------+\nD |     9   2 |         3 |           |\nE |           |     5     |           |\nF |     1     |           | 7       4 |\n  +-----------+-----------+-----------+\nG | 8         | 7         |         5 |\nH |         6 | 8       1 |           |\nI |           |     9     |     4     |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:5 clues:26\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         1 | 2       4 | 8   5     |\nB | 3       2 |           |           |\nC |     6     |         3 | 2       7 |\n  +-----------+-----------+-----------+\nD | 2         |     4     |           |\nE | 9   8     |         5 | 3         |\nF |     5     |     9     |           |\n  +-----------+-----------+-----------+\nG |           |         6 |           |\nH |     3     |           | 7         |\nI | 5         |         7 |     6     |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:5 clues:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         |         3 | 2       8 |\nB | 8         |         6 |     5     |\nC |           |         1 |           |\n  +-----------+-----------+-----------+\nD | 4         |           |     7     |\nE |           |           |     2     |\nF |     6   9 |     8     |         1 |\n  +-----------+-----------+-----------+\nG |           |         4 |           |\nH | 6   9     |           |         7 |\nI |     3     | 6       7 |     4   9 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:5 clues:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 6   3     |     7     |\nB |           |           |     6   5 |\nC |     2     |     8   9 |           |\n  +-----------+-----------+-----------+\nD |     4   1 | 8   5     |           |\nE |     6     |           | 7         |\nF |           |           |     8     |\n  +-----------+-----------+-----------+\nG |           |           | 5       1 |\nH | 3         |     1     |           |\nI |         8 | 5         |     2   9 |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:7 clues:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 6       8 |         5 |\nB |           |           |           |\nC | 2         |     1     | 7         |\n  +-----------+-----------+-----------+\nD |           |         5 | 4         |\nE |         3 |         9 |     6     |\nF | 4         |     8     |           |\n  +-----------+-----------+-----------+\nG |     9     |     7     | 8   4   1 |\nH |     6     |         4 |     9     |\nI |         8 |           |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:5 clues:22\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 1   5     |           |\nB |         7 |           |     5     |\nC | 2         |           |           |\n  +-----------+-----------+-----------+\nD |         6 |         7 |           |\nE | 8         |           | 3         |\nF |           |         3 | 9       2 |\n  +-----------+-----------+-----------+\nG |           | 3         |         5 |\nH | 9         |     7     |     1   3 |\nI |     8   4 |     2     |           |\n  +-----------+-----------+-----------+\n  s:0 gu:0 st:0 ro:5 clues:21<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 esittely edellisen raportin mielest\u00e4ni t\u00e4rkeimm\u00e4st\u00e4 asiasta db8:sta, lista t\u00e4h\u00e4n asti ll\u00f6ydetyist\u00e4 sudokujen vaikeusasteista (steps luku): aiemmissa steps 12 sudokuissa oli 26 tai 24 vihjett\u00e4..<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.04 \u00a9\nskk&gt;digits,steps\nquery:digits,steps\nquery2:'digits', 'steps'\n201 rows.\n0 'digits' = \"19\", 'steps' = \"0\"\n1 'digits' = \"20\", 'steps' = \"0\"\n2 'digits' = \"21\", 'steps' = \"0\"\n3 'digits' = \"21\", 'steps' = \"2\"\n4 'digits' = \"21\", 'steps' = \"3\"\n5 'digits' = \"21\", 'steps' = \"4\"\n6 'digits' = \"22\", 'steps' = \"0\"\n7 'digits' = \"22\", 'steps' = \"1\"\n8 'digits' = \"22\", 'steps' = \"2\"\n9 'digits' = \"22\", 'steps' = \"3\"\n10 'digits' = \"22\", 'steps' = \"4\"\n11 'digits' = \"22\", 'steps' = \"5\"\n12 'digits' = \"22\", 'steps' = \"6\"\n13 'digits' = \"22\", 'steps' = \"8\"\n14 'digits' = \"23\", 'steps' = \"0\"\n15 'digits' = \"23\", 'steps' = \"1\"\n16 'digits' = \"23\", 'steps' = \"2\"\n17 'digits' = \"23\", 'steps' = \"3\"\n18 'digits' = \"23\", 'steps' = \"4\"\n19 'digits' = \"23\", 'steps' = \"5\"\n20 'digits' = \"23\", 'steps' = \"6\"\n21 'digits' = \"23\", 'steps' = \"7\"\n22 'digits' = \"23\", 'steps' = \"8\"\n23 'digits' = \"23\", 'steps' = \"9\"\n24 'digits' = \"23\", 'steps' = \"10\"\n25 'digits' = \"23\", 'steps' = \"11\"\n26 'digits' = \"24\", 'steps' = \"0\"\n27 'digits' = \"24\", 'steps' = \"1\"\n28 'digits' = \"24\", 'steps' = \"2\"\n29 'digits' = \"24\", 'steps' = \"3\"\n30 'digits' = \"24\", 'steps' = \"4\"\n31 'digits' = \"24\", 'steps' = \"5\"\n32 'digits' = \"24\", 'steps' = \"6\"\n33 'digits' = \"24\", 'steps' = \"7\"\n34 'digits' = \"24\", 'steps' = \"8\"\n35 'digits' = \"24\", 'steps' = \"9\"\n36 'digits' = \"24\", 'steps' = \"10\"\n37 'digits' = \"24\", 'steps' = \"11\"\n38 'digits' = \"24\", 'steps' = \"12\"\n39 'digits' = \"25\", 'steps' = \"0\"\n40 'digits' = \"25\", 'steps' = \"1\"\n41 'digits' = \"25\", 'steps' = \"2\"\n42 'digits' = \"25\", 'steps' = \"3\"\n43 'digits' = \"25\", 'steps' = \"4\"\n44 'digits' = \"25\", 'steps' = \"5\"\n45 'digits' = \"25\", 'steps' = \"6\"\n46 'digits' = \"25\", 'steps' = \"7\"\n47 'digits' = \"25\", 'steps' = \"8\"\n48 'digits' = \"25\", 'steps' = \"9\"\n49 'digits' = \"25\", 'steps' = \"10\"\n50 'digits' = \"25\", 'steps' = \"11\"\n51 'digits' = \"25\", 'steps' = \"13\"\n52 'digits' = \"26\", 'steps' = \"0\"\n53 'digits' = \"26\", 'steps' = \"1\"\n54 'digits' = \"26\", 'steps' = \"2\"\n55 'digits' = \"26\", 'steps' = \"3\"\n56 'digits' = \"26\", 'steps' = \"4\"\n57 'digits' = \"26\", 'steps' = \"5\"\n58 'digits' = \"26\", 'steps' = \"6\"\n59 'digits' = \"26\", 'steps' = \"7\"\n60 'digits' = \"26\", 'steps' = \"8\"\n61 'digits' = \"26\", 'steps' = \"9\"\n62 'digits' = \"26\", 'steps' = \"10\"\n63 'digits' = \"26\", 'steps' = \"11\"\n64 'digits' = \"26\", 'steps' = \"12\"\n65 'digits' = \"27\", 'steps' = \"0\"\n66 'digits' = \"27\", 'steps' = \"1\"\n67 'digits' = \"27\", 'steps' = \"2\"\n68 'digits' = \"27\", 'steps' = \"3\"\n69 'digits' = \"27\", 'steps' = \"4\"\n70 'digits' = \"27\", 'steps' = \"5\"\n71 'digits' = \"27\", 'steps' = \"6\"\n72 'digits' = \"27\", 'steps' = \"7\"\n73 'digits' = \"27\", 'steps' = \"8\"\n74 'digits' = \"27\", 'steps' = \"9\"\n75 'digits' = \"27\", 'steps' = \"10\"\n76 'digits' = \"27\", 'steps' = \"11\"\n77 'digits' = \"28\", 'steps' = \"0\"\n78 'digits' = \"28\", 'steps' = \"1\"\n79 'digits' = \"28\", 'steps' = \"2\"\n80 'digits' = \"28\", 'steps' = \"3\"\n81 'digits' = \"28\", 'steps' = \"4\"\n82 'digits' = \"28\", 'steps' = \"5\"\n83 'digits' = \"28\", 'steps' = \"6\"\n84 'digits' = \"28\", 'steps' = \"7\"\n85 'digits' = \"28\", 'steps' = \"8\"\n86 'digits' = \"28\", 'steps' = \"9\"\n87 'digits' = \"28\", 'steps' = \"10\"\n88 'digits' = \"29\", 'steps' = \"0\"\n89 'digits' = \"29\", 'steps' = \"1\"\n90 'digits' = \"29\", 'steps' = \"2\"\n91 'digits' = \"29\", 'steps' = \"3\"\n92 'digits' = \"29\", 'steps' = \"4\"\n93 'digits' = \"29\", 'steps' = \"5\"\n94 'digits' = \"29\", 'steps' = \"6\"\n95 'digits' = \"29\", 'steps' = \"7\"\n96 'digits' = \"29\", 'steps' = \"8\"\n97 'digits' = \"29\", 'steps' = \"9\"\n98 'digits' = \"29\", 'steps' = \"10\"\n99 'digits' = \"30\", 'steps' = \"0\"\n100 'digits' = \"30\", 'steps' = \"1\"\n101 'digits' = \"30\", 'steps' = \"2\"\n102 'digits' = \"30\", 'steps' = \"3\"\n103 'digits' = \"30\", 'steps' = \"4\"\n104 'digits' = \"30\", 'steps' = \"5\"\n105 'digits' = \"30\", 'steps' = \"6\"\n106 'digits' = \"30\", 'steps' = \"7\"\n107 'digits' = \"30\", 'steps' = \"8\"\n108 'digits' = \"30\", 'steps' = \"9\"\n109 'digits' = \"30\", 'steps' = \"10\"\n110 'digits' = \"31\", 'steps' = \"0\"\n111 'digits' = \"31\", 'steps' = \"1\"\n112 'digits' = \"31\", 'steps' = \"2\"\n113 'digits' = \"31\", 'steps' = \"3\"\n114 'digits' = \"31\", 'steps' = \"4\"\n115 'digits' = \"31\", 'steps' = \"5\"\n116 'digits' = \"31\", 'steps' = \"6\"\n117 'digits' = \"31\", 'steps' = \"7\"\n118 'digits' = \"31\", 'steps' = \"8\"\n119 'digits' = \"32\", 'steps' = \"0\"\n120 'digits' = \"32\", 'steps' = \"1\"\n121 'digits' = \"32\", 'steps' = \"2\"\n122 'digits' = \"32\", 'steps' = \"3\"\n123 'digits' = \"32\", 'steps' = \"4\"\n124 'digits' = \"32\", 'steps' = \"5\"\n125 'digits' = \"32\", 'steps' = \"6\"\n126 'digits' = \"32\", 'steps' = \"7\"\n127 'digits' = \"32\", 'steps' = \"8\"\n128 'digits' = \"33\", 'steps' = \"0\"\n129 'digits' = \"33\", 'steps' = \"1\"\n130 'digits' = \"33\", 'steps' = \"2\"\n131 'digits' = \"33\", 'steps' = \"3\"\n132 'digits' = \"33\", 'steps' = \"4\"\n133 'digits' = \"33\", 'steps' = \"5\"\n134 'digits' = \"33\", 'steps' = \"6\"\n135 'digits' = \"34\", 'steps' = \"0\"\n136 'digits' = \"34\", 'steps' = \"1\"\n137 'digits' = \"34\", 'steps' = \"2\"\n138 'digits' = \"34\", 'steps' = \"3\"\n139 'digits' = \"34\", 'steps' = \"4\"\n140 'digits' = \"34\", 'steps' = \"5\"\n141 'digits' = \"34\", 'steps' = \"6\"\n142 'digits' = \"35\", 'steps' = \"0\"\n143 'digits' = \"35\", 'steps' = \"1\"\n144 'digits' = \"35\", 'steps' = \"2\"\n145 'digits' = \"35\", 'steps' = \"3\"\n146 'digits' = \"35\", 'steps' = \"4\"\n147 'digits' = \"35\", 'steps' = \"5\"\n148 'digits' = \"36\", 'steps' = \"0\"\n149 'digits' = \"36\", 'steps' = \"1\"\n150 'digits' = \"36\", 'steps' = \"2\"\n151 'digits' = \"36\", 'steps' = \"3\"\n152 'digits' = \"36\", 'steps' = \"4\"\n153 'digits' = \"36\", 'steps' = \"5\"\n154 'digits' = \"36\", 'steps' = \"6\"\n155 'digits' = \"37\", 'steps' = \"0\"\n156 'digits' = \"37\", 'steps' = \"1\"\n157 'digits' = \"37\", 'steps' = \"2\"\n158 'digits' = \"37\", 'steps' = \"3\"\n159 'digits' = \"37\", 'steps' = \"5\"\n160 'digits' = \"38\", 'steps' = \"0\"\n161 'digits' = \"38\", 'steps' = \"1\"\n162 'digits' = \"38\", 'steps' = \"2\"\n163 'digits' = \"38\", 'steps' = \"3\"\n164 'digits' = \"38\", 'steps' = \"4\"\n165 'digits' = \"39\", 'steps' = \"0\"\n166 'digits' = \"39\", 'steps' = \"1\"\n167 'digits' = \"39\", 'steps' = \"2\"\n168 'digits' = \"39\", 'steps' = \"3\"\n169 'digits' = \"39\", 'steps' = \"4\"\n170 'digits' = \"40\", 'steps' = \"0\"\n171 'digits' = \"40\", 'steps' = \"1\"\n172 'digits' = \"40\", 'steps' = \"2\"\n173 'digits' = \"40\", 'steps' = \"3\"\n174 'digits' = \"41\", 'steps' = \"0\"\n175 'digits' = \"41\", 'steps' = \"1\"\n176 'digits' = \"41\", 'steps' = \"2\"\n177 'digits' = \"41\", 'steps' = \"3\"\n178 'digits' = \"42\", 'steps' = \"0\"\n179 'digits' = \"42\", 'steps' = \"1\"\n180 'digits' = \"42\", 'steps' = \"2\"\n181 'digits' = \"43\", 'steps' = \"0\"\n182 'digits' = \"43\", 'steps' = \"1\"\n183 'digits' = \"44\", 'steps' = \"0\"\n184 'digits' = \"44\", 'steps' = \"1\"\n185 'digits' = \"44\", 'steps' = \"2\"\n186 'digits' = \"45\", 'steps' = \"0\"\n187 'digits' = \"46\", 'steps' = \"0\"\n188 'digits' = \"46\", 'steps' = \"1\"\n189 'digits' = \"47\", 'steps' = \"0\"\n190 'digits' = \"47\", 'steps' = \"1\"\n191 'digits' = \"48\", 'steps' = \"0\"\n192 'digits' = \"49\", 'steps' = \"0\"\n193 'digits' = \"50\", 'steps' = \"0\"\n194 'digits' = \"51\", 'steps' = \"0\"\n195 'digits' = \"52\", 'steps' = \"0\"\n196 'digits' = \"53\", 'steps' = \"0\"\n197 'digits' = \"54\", 'steps' = \"0\"\n198 'digits' = \"55\", 'steps' = \"0\"\n199 'digits' = \"56\", 'steps' = \"0\"\n200 'digits' = \"57\", 'steps' = \"0\"\nskk&gt;exit\n$<\/code><\/pre>\n\n\n\n<p>Sama lista askelittain (steps) vihjeitt\u00e4in (digits)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.04 \u00a9\nskk&gt;steps,digits\nquery:steps,digits\nquery2:'steps', 'digits'\n201 rows.\n0 'steps' = \"0\", 'digits' = \"19\"\n1 'steps' = \"0\", 'digits' = \"20\"\n2 'steps' = \"0\", 'digits' = \"21\"\n3 'steps' = \"0\", 'digits' = \"22\"\n4 'steps' = \"0\", 'digits' = \"23\"\n5 'steps' = \"0\", 'digits' = \"24\"\n6 'steps' = \"0\", 'digits' = \"25\"\n7 'steps' = \"0\", 'digits' = \"26\"\n8 'steps' = \"0\", 'digits' = \"27\"\n9 'steps' = \"0\", 'digits' = \"28\"\n10 'steps' = \"0\", 'digits' = \"29\"\n11 'steps' = \"0\", 'digits' = \"30\"\n12 'steps' = \"0\", 'digits' = \"31\"\n13 'steps' = \"0\", 'digits' = \"32\"\n14 'steps' = \"0\", 'digits' = \"33\"\n15 'steps' = \"0\", 'digits' = \"34\"\n16 'steps' = \"0\", 'digits' = \"35\"\n17 'steps' = \"0\", 'digits' = \"36\"\n18 'steps' = \"0\", 'digits' = \"37\"\n19 'steps' = \"0\", 'digits' = \"38\"\n20 'steps' = \"0\", 'digits' = \"39\"\n21 'steps' = \"0\", 'digits' = \"40\"\n22 'steps' = \"0\", 'digits' = \"41\"\n23 'steps' = \"0\", 'digits' = \"42\"\n24 'steps' = \"0\", 'digits' = \"43\"\n25 'steps' = \"0\", 'digits' = \"44\"\n26 'steps' = \"0\", 'digits' = \"45\"\n27 'steps' = \"0\", 'digits' = \"46\"\n28 'steps' = \"0\", 'digits' = \"47\"\n29 'steps' = \"0\", 'digits' = \"48\"\n30 'steps' = \"0\", 'digits' = \"49\"\n31 'steps' = \"0\", 'digits' = \"50\"\n32 'steps' = \"0\", 'digits' = \"51\"\n33 'steps' = \"0\", 'digits' = \"52\"\n34 'steps' = \"0\", 'digits' = \"53\"\n35 'steps' = \"0\", 'digits' = \"54\"\n36 'steps' = \"0\", 'digits' = \"55\"\n37 'steps' = \"0\", 'digits' = \"56\"\n38 'steps' = \"0\", 'digits' = \"57\"\n39 'steps' = \"1\", 'digits' = \"22\"\n40 'steps' = \"1\", 'digits' = \"23\"\n41 'steps' = \"1\", 'digits' = \"24\"\n42 'steps' = \"1\", 'digits' = \"25\"\n43 'steps' = \"1\", 'digits' = \"26\"\n44 'steps' = \"1\", 'digits' = \"27\"\n45 'steps' = \"1\", 'digits' = \"28\"\n46 'steps' = \"1\", 'digits' = \"29\"\n47 'steps' = \"1\", 'digits' = \"30\"\n48 'steps' = \"1\", 'digits' = \"31\"\n49 'steps' = \"1\", 'digits' = \"32\"\n50 'steps' = \"1\", 'digits' = \"33\"\n51 'steps' = \"1\", 'digits' = \"34\"\n52 'steps' = \"1\", 'digits' = \"35\"\n53 'steps' = \"1\", 'digits' = \"36\"\n54 'steps' = \"1\", 'digits' = \"37\"\n55 'steps' = \"1\", 'digits' = \"38\"\n56 'steps' = \"1\", 'digits' = \"39\"\n57 'steps' = \"1\", 'digits' = \"40\"\n58 'steps' = \"1\", 'digits' = \"41\"\n59 'steps' = \"1\", 'digits' = \"42\"\n60 'steps' = \"1\", 'digits' = \"43\"\n61 'steps' = \"1\", 'digits' = \"44\"\n62 'steps' = \"1\", 'digits' = \"46\"\n63 'steps' = \"1\", 'digits' = \"47\"\n64 'steps' = \"2\", 'digits' = \"21\"\n65 'steps' = \"2\", 'digits' = \"22\"\n66 'steps' = \"2\", 'digits' = \"23\"\n67 'steps' = \"2\", 'digits' = \"24\"\n68 'steps' = \"2\", 'digits' = \"25\"\n69 'steps' = \"2\", 'digits' = \"26\"\n70 'steps' = \"2\", 'digits' = \"27\"\n71 'steps' = \"2\", 'digits' = \"28\"\n72 'steps' = \"2\", 'digits' = \"29\"\n73 'steps' = \"2\", 'digits' = \"30\"\n74 'steps' = \"2\", 'digits' = \"31\"\n75 'steps' = \"2\", 'digits' = \"32\"\n76 'steps' = \"2\", 'digits' = \"33\"\n77 'steps' = \"2\", 'digits' = \"34\"\n78 'steps' = \"2\", 'digits' = \"35\"\n79 'steps' = \"2\", 'digits' = \"36\"\n80 'steps' = \"2\", 'digits' = \"37\"\n81 'steps' = \"2\", 'digits' = \"38\"\n82 'steps' = \"2\", 'digits' = \"39\"\n83 'steps' = \"2\", 'digits' = \"40\"\n84 'steps' = \"2\", 'digits' = \"41\"\n85 'steps' = \"2\", 'digits' = \"42\"\n86 'steps' = \"2\", 'digits' = \"44\"\n87 'steps' = \"3\", 'digits' = \"21\"\n88 'steps' = \"3\", 'digits' = \"22\"\n89 'steps' = \"3\", 'digits' = \"23\"\n90 'steps' = \"3\", 'digits' = \"24\"\n91 'steps' = \"3\", 'digits' = \"25\"\n92 'steps' = \"3\", 'digits' = \"26\"\n93 'steps' = \"3\", 'digits' = \"27\"\n94 'steps' = \"3\", 'digits' = \"28\"\n95 'steps' = \"3\", 'digits' = \"29\"\n96 'steps' = \"3\", 'digits' = \"30\"\n97 'steps' = \"3\", 'digits' = \"31\"\n98 'steps' = \"3\", 'digits' = \"32\"\n99 'steps' = \"3\", 'digits' = \"33\"\n100 'steps' = \"3\", 'digits' = \"34\"\n101 'steps' = \"3\", 'digits' = \"35\"\n102 'steps' = \"3\", 'digits' = \"36\"\n103 'steps' = \"3\", 'digits' = \"37\"\n104 'steps' = \"3\", 'digits' = \"38\"\n105 'steps' = \"3\", 'digits' = \"39\"\n106 'steps' = \"3\", 'digits' = \"40\"\n107 'steps' = \"3\", 'digits' = \"41\"\n108 'steps' = \"4\", 'digits' = \"21\"\n109 'steps' = \"4\", 'digits' = \"22\"\n110 'steps' = \"4\", 'digits' = \"23\"\n111 'steps' = \"4\", 'digits' = \"24\"\n112 'steps' = \"4\", 'digits' = \"25\"\n113 'steps' = \"4\", 'digits' = \"26\"\n114 'steps' = \"4\", 'digits' = \"27\"\n115 'steps' = \"4\", 'digits' = \"28\"\n116 'steps' = \"4\", 'digits' = \"29\"\n117 'steps' = \"4\", 'digits' = \"30\"\n118 'steps' = \"4\", 'digits' = \"31\"\n119 'steps' = \"4\", 'digits' = \"32\"\n120 'steps' = \"4\", 'digits' = \"33\"\n121 'steps' = \"4\", 'digits' = \"34\"\n122 'steps' = \"4\", 'digits' = \"35\"\n123 'steps' = \"4\", 'digits' = \"36\"\n124 'steps' = \"4\", 'digits' = \"38\"\n125 'steps' = \"4\", 'digits' = \"39\"\n126 'steps' = \"5\", 'digits' = \"22\"\n127 'steps' = \"5\", 'digits' = \"23\"\n128 'steps' = \"5\", 'digits' = \"24\"\n129 'steps' = \"5\", 'digits' = \"25\"\n130 'steps' = \"5\", 'digits' = \"26\"\n131 'steps' = \"5\", 'digits' = \"27\"\n132 'steps' = \"5\", 'digits' = \"28\"\n133 'steps' = \"5\", 'digits' = \"29\"\n134 'steps' = \"5\", 'digits' = \"30\"\n135 'steps' = \"5\", 'digits' = \"31\"\n136 'steps' = \"5\", 'digits' = \"32\"\n137 'steps' = \"5\", 'digits' = \"33\"\n138 'steps' = \"5\", 'digits' = \"34\"\n139 'steps' = \"5\", 'digits' = \"35\"\n140 'steps' = \"5\", 'digits' = \"36\"\n141 'steps' = \"5\", 'digits' = \"37\"\n142 'steps' = \"6\", 'digits' = \"22\"\n143 'steps' = \"6\", 'digits' = \"23\"\n144 'steps' = \"6\", 'digits' = \"24\"\n145 'steps' = \"6\", 'digits' = \"25\"\n146 'steps' = \"6\", 'digits' = \"26\"\n147 'steps' = \"6\", 'digits' = \"27\"\n148 'steps' = \"6\", 'digits' = \"28\"\n149 'steps' = \"6\", 'digits' = \"29\"\n150 'steps' = \"6\", 'digits' = \"30\"\n151 'steps' = \"6\", 'digits' = \"31\"\n152 'steps' = \"6\", 'digits' = \"32\"\n153 'steps' = \"6\", 'digits' = \"33\"\n154 'steps' = \"6\", 'digits' = \"34\"\n155 'steps' = \"6\", 'digits' = \"36\"\n156 'steps' = \"7\", 'digits' = \"23\"\n157 'steps' = \"7\", 'digits' = \"24\"\n158 'steps' = \"7\", 'digits' = \"25\"\n159 'steps' = \"7\", 'digits' = \"26\"\n160 'steps' = \"7\", 'digits' = \"27\"\n161 'steps' = \"7\", 'digits' = \"28\"\n162 'steps' = \"7\", 'digits' = \"29\"\n163 'steps' = \"7\", 'digits' = \"30\"\n164 'steps' = \"7\", 'digits' = \"31\"\n165 'steps' = \"7\", 'digits' = \"32\"\n166 'steps' = \"8\", 'digits' = \"22\"\n167 'steps' = \"8\", 'digits' = \"23\"\n168 'steps' = \"8\", 'digits' = \"24\"\n169 'steps' = \"8\", 'digits' = \"25\"\n170 'steps' = \"8\", 'digits' = \"26\"\n171 'steps' = \"8\", 'digits' = \"27\"\n172 'steps' = \"8\", 'digits' = \"28\"\n173 'steps' = \"8\", 'digits' = \"29\"\n174 'steps' = \"8\", 'digits' = \"30\"\n175 'steps' = \"8\", 'digits' = \"31\"\n176 'steps' = \"8\", 'digits' = \"32\"\n177 'steps' = \"9\", 'digits' = \"23\"\n178 'steps' = \"9\", 'digits' = \"24\"\n179 'steps' = \"9\", 'digits' = \"25\"\n180 'steps' = \"9\", 'digits' = \"26\"\n181 'steps' = \"9\", 'digits' = \"27\"\n182 'steps' = \"9\", 'digits' = \"28\"\n183 'steps' = \"9\", 'digits' = \"29\"\n184 'steps' = \"9\", 'digits' = \"30\"\n185 'steps' = \"10\", 'digits' = \"23\"\n186 'steps' = \"10\", 'digits' = \"24\"\n187 'steps' = \"10\", 'digits' = \"25\"\n188 'steps' = \"10\", 'digits' = \"26\"\n189 'steps' = \"10\", 'digits' = \"27\"\n190 'steps' = \"10\", 'digits' = \"28\"\n191 'steps' = \"10\", 'digits' = \"29\"\n192 'steps' = \"10\", 'digits' = \"30\"\n193 'steps' = \"11\", 'digits' = \"23\"\n194 'steps' = \"11\", 'digits' = \"24\"\n195 'steps' = \"11\", 'digits' = \"25\"\n196 'steps' = \"11\", 'digits' = \"26\"\n197 'steps' = \"11\", 'digits' = \"27\"\n198 'steps' = \"12\", 'digits' = \"24\"\n199 'steps' = \"12\", 'digits' = \"26\"\n200 'steps' = \"13\", 'digits' = \"25\"\nskk&gt;exit\n$<\/code><\/pre>\n\n\n\n<p>Seuraavassa desimaaliviisas merkkijonojen vertailu db8:in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static long db8_atol_dec(unsigned char **p, int *decimals) \/\/ JariK 2025\n{\n  int count = 0, decimals2 = 0;\n  long num = 0;\n\n  while(**p == '0')\n    (*p)++;\n  \n  while(isdigit(**p) &amp;&amp; count &lt; 18) { \/\/ calculate 19 first digits\n    num = num * 10 + (**p - '0');\n    \/\/more_printf(stdout,\"%ld\\n\", num);\n    (*p)++;\n    count++;\n  }\n  if(**p == '.') {\n    (*p)++;\n    while(isdigit(**p) &amp;&amp; count &lt; 18) { \/\/ calculate 19 first digits\n      num = num * 10 + (**p - '0');\n      \/\/more_printf(stdout,\"%ld\\n\", num);\n      (*p)++;\n      count++;\n      decimals2++;\n    }\n  }\n  if(decimals != NULL)\n    *decimals = decimals2;\n  \n  while(isdigit(**p)) { \/\/ skip rest\n    (*p)++;\n  }\n  return(num);\n}\n\nstatic long db8_strcmp_numdec(unsigned char *p, unsigned char *q) \/\/ JariK 2025\n{\n  int dec1, dec2;\n  long num1, num2;\n  \n  for(;;) {\n    \/\/more_printf(stdout,\"p:%s, q:%s\\n\", p, q);\n    if(isdigit(*p) &amp;&amp; isdigit(*q)) {\n      num1 = db8_atol_dec(&amp;p, &amp;dec1);\n      num2 = db8_atol_dec(&amp;q, &amp;dec2);\n      if(dec2 &gt; dec1)\n\tnum1 *= (int) pow((double) 10, (double) dec2-dec1);\n      else if(dec1 &gt; dec2)\n\tnum2 *= (int) pow((double) 10, (double) dec1-dec2);\n\t\n      if(num1 - num2 != 0)\n\treturn(num1 - num2);\n    } else if(*p - *q != 0) {\n      return(*p - *q);\n    } else {\n      if(*p == '\\0' || *q == '\\0')\n\tbreak;\n      p++;\n      q++;\n    }\n  }\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>Ja uusi koodi merkkijonojen vertailuun. T\u00e4m\u00e4 tekee simppeli\u00e4 merkkijonojen mats\u00e4ily\u00e4 huomaten &#8216;*&#8217; ja &#8216;?&#8217; merkkijonot. T\u00e4hti korvaa yhden tai useamman merkin ja kysymysmerkki korvaa yhden merkin: Koodi on viel\u00e4 vaiheessa, db8:n k\u00e4ytt\u00f6koodi puuttuu viel\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG92 2\n#define DEBUG96 2\n\nint my_match(unsigned char *pattern, unsigned char *string)\n{\n  unsigned char *p, *s;\n\n  p = pattern;\n  s = string;\n\n#ifdef DEBUG92\n  more_printf(stdout,\"\\npattern=%s\",p);\n  more_printf(stdout,\", string=%s\",s);\n#endif\n\n  while(*p != '\\0') {\n    if(*p == '*') { \/\/ one or many characters\n      if(*s == '\\0')\n\treturn(0);\n      while(*s != '\\0') {\n\tif(my_match(p + 1, ++s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(*s == '\\0')\n\treturn(0);\n      s++;\n    } else if(*p == *s) {\n      s++;\n    } else\n      return(0);\n    p++;\n  }\n  if(*s == '\\0')\n    return(1);\n  else\n    return(0);\n}\n\nint my_match_test(unsigned char *pattern, unsigned char *string)\n{\n  int retval;\n  static unsigned int testid = 0;\n\n  more_printf(stdout,\"%d\", testid++);\n\n  more_printf(stdout,\" pattern=%s\", pattern);\n  more_printf(stdout,\", string=%s\", string);\n\n  retval = my_match(pattern, string);\n  if(retval)\n    more_printf(stdout,\" match!\");\n  else\n    more_printf(stdout,\" no match!\");\n\n  more_printf(stdout,\"\\n\");\n  \n  return(retval);\n}\n\nint main(int argc, char *argv&#91;])\n{\n...\n#ifdef DEBUG96\n\n  if(more)\n    more_init(); \/\/ adjust thee screensize\n  \n  my_match_test(\"abcdef\",\"abcdef\");\n  my_match_test(\"abc*def\",\"abcdefdef\");\n  my_match_test(\"abc*def\",\"abcdefdefdef\");\n  my_match_test(\"abc*\",\"abcdef\");\n  my_match_test(\"*def\",\"abcdef\");\n  my_match_test(\"*cd*\",\"abcdef\");\n  my_match_test(\"ab??ef\",\"abcdef\");\n  my_match_test(\"??def\",\"abcdef\");\n  my_match_test(\"???def\",\"abcdef\");\n  my_match_test(\"*gh*\",\"abcdef\");\n  my_match_test(\"abcdef\",\"abcgef\");\n  my_match_test(\"?*def\",\"abcdef\");\n  my_match_test(\"?*def\",\"abcdefg\");\n  my_match_test(\"?b\",\"ab\");\n  my_match_test(\"a?\",\"ab\");\n  my_match_test(\"a?c\",\"abc\");\n  my_match_test(\"a??d\",\"abcd\");\n  my_match_test(\"a??*d\",\"abcd\");\n  my_match_test(\"?b\",\"ac\");\n#endif\n...\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa db8:n alun merkkijonojen vertailu testituloste:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\n0 pattern=abcdef, string=abcdef match!\n1 pattern=abc*def, string=abcdefdef match!\n2 pattern=abc*def, string=abcdefdefdef match!\n3 pattern=abc*, string=abcdef match!\n4 pattern=*def, string=abcdef match!\n5 pattern=*cd*, string=abcdef match!\n6 pattern=ab??ef, string=abcdef match!\n7 pattern=??def, string=abcdef no match!\n8 pattern=???def, string=abcdef match!\n9 pattern=*gh*, string=abcdef no match!\n10 pattern=abcdef, string=abcgef no match!\n11 pattern=?*def, string=abcdef match!\n12 pattern=?*def, string=abcdefg no match!\n13 pattern=?b, string=ab match!\n14 pattern=a?, string=ab match!\n15 pattern=a?c, string=abc match!\n16 pattern=a??d, string=abcd match!\n17 pattern=a??*d, string=abcd no match!\n18 pattern=?b, string=ac no match!\nDB8 version 0.04 \u00a9\nskk&gt;exit<\/code><\/pre>\n\n\n\n<p>Db8 tarvitsee merkkijonojen m\u00e4ts\u00e4ilyst\u00e4 version jossa merkkijonojen pituus toimitetaan erillisiss\u00e4 kentiss\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int my_match_len(unsigned int plen, unsigned char *p, unsigned int slen, unsigned char *s)\n{\n  while(plen &gt; 0) {\n#ifdef DEBUG92\n    more_printf(stdout,\"\\nplen=%d\", plen);\n    more_printf(stdout,\", p=\");\n    db8_fputs_len(stdout, plen, p);\n    more_printf(stdout,\", slen=%d\", slen);\n    more_printf(stdout,\", s=\");\n    db8_fputs_len(stdout, slen, s);\n#endif\n\n    if(*p == '*') { \/\/ one or many characters\n      if(slen == 0)\n\treturn(0);\n      while(slen &gt; 0) {\n\ts++;\n\tslen--;\n\tif(my_match_len(plen - 1, p + 1, slen, s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(slen == 0)\n\treturn(0);\n      s++;\n      slen--;\n    } else if(*p == *s) {\n      s++;\n      slen--;\n    } else\n      return(0);\n    p++;\n    plen--;\n  }\n  if(slen == 0)\n    return(1);\n  else\n    return(0);\n}\n\nvoid db8_fputs_len(FILE *fp1, unsigned int slen, unsigned char *s)\n{\n  while(slen-- &gt; 0)\n    fputc(*s++, fp1);\n}<\/code><\/pre>\n\n\n\n<p>Edellinen nimettyn\u00e4 db8:a varten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_match_pattern_len(unsigned int plen, unsigned char *p, unsigned int slen, unsigned char *s)\n{\n  while(plen &gt; 0) {\n#ifdef DEBUG92\n    more_printf(stdout,\"\\nplen=%d\", plen);\n    more_printf(stdout,\", p=\");\n    db8_fputs_len(stdout, plen, p);\n    more_printf(stdout,\", slen=%d\", slen);\n    more_printf(stdout,\", s=\");\n    db8_fputs_len(stdout, slen, s);\n#endif\n\n    if(*p == '*') { \/\/ one or many characters\n      if(slen == 0)\n\treturn(0);\n      while(slen &gt; 0) {\n\ts++;\n\tslen--;\n\tif(db8_match_pattern_len(plen - 1, p + 1, slen, s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(slen == 0)\n\treturn(0);\n      s++;\n      slen--;\n    } else if(*p == *s) {\n      s++;\n      slen--;\n    } else\n      return(0);\n    p++;\n    plen--;\n  }\n  if(slen == 0)\n    return(1);\n  else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>Ja uuden merkkijonom\u00e4ts\u00e4ilyn k\u00e4yt\u00f6t:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int db8_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_match: match:%s\", match);\n    fprintf(stdout,\", set:%s\", set);\n    fflush(stdout);\n  }\n#endif\n  \n#ifdef DEBUG48\n  fprintf(stdout,\"db8_match: match:%s\", match);\n  fprintf(stdout,\", set:%s\", set);\n  fflush(stdout);\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db8_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db8_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;m); \/\/ match\n    db8_skipwhite(&amp;m);\n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb8_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s); \/\/ set\n      db8_skipwhite(&amp;s);\n#ifdef OLD1\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value2, value, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n#endif\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || db8_match_pattern_len(valuelen, value, valuelen2, value2) == 1)) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n\n#ifdef DEBUG48\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n#ifdef DEBUG5\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n\n  return(ok);\n}\n\n#define aDEBUG52 2\n\nstatic void db8_project(unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG52\n  more_printf(stdout,\"db8_project: \");\n  more_printf(stdout,\", query:%s\", query);\n  more_printf(stdout,\", set:%s\\n\", set);\n  fflush(stdout); fflush(stdout);\n#endif\n\n#ifdef DEBUG52\n  more_printf(stdout,\"db8_project: \");\n  more_printf(stdout,\" set:%s\\n\", set);\n#endif\n  \n  if(*project != NULL)\n    *(project&#91;0]) = '\\0';\n  \n  q = query;\n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db8_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb8_skipwhite(&amp;s);\n      }\n\n#ifdef OLD1\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n#endif\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || db8_match_pattern_len(valuelen, value, valuelen2, value2) == 1)) {\n#ifdef DEBUG52\n\tmore_printf(stdout,\"db8_project: \");\n\tmore_printf(stdout,\"'%.*s'\", namelen, name);\n\tmore_printf(stdout,\" = \\\"%.*s\\\"\", valuelen2, value2);\n\tmore_printf(stdout,\"\\n\");\n#endif\n\tdb8_put(project, namelen, name, valuelen2, value2);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n#ifdef DEBUG5\n  more_printf(stdout,\", project:(%s)\", *project);\n  more_printf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}'<\/code><\/pre>\n\n\n\n<p>Kokeillaan edellist\u00e4 m\u00e4ts\u00e4illy\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DB8 version 0.05 \u00a9\nskk&gt;steps=\"1?\"\nquery:steps=\"1?\"\ndb8_squery(): name:steps(5), value:1?(2)\nquery2:'steps' = \"1?\"\n4 rows.\n0 'steps' = \"10\"\n1 'steps' = \"11\"\n2 'steps' = \"12\"\n3 'steps' = \"13\"\nskk&gt;digits=\"*5\"\nquery:digits=\"*5\"\ndb8_squery(): name:digits(6), value:*5(2)\nquery2:'digits' = \"*5\"\n4 rows.\n0 'digits' = \"25\"\n1 'digits' = \"35\"\n2 'digits' = \"45\"\n3 'digits' = \"55\"\nskk&gt;exit<\/code><\/pre>\n\n\n\n<p>Db8 source db8.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryheader {\n  unsigned char *queryname;\n  int flags;\n  unsigned char *query;\n  unsigned char *match;\n  int count;\n  int preread;\n  unsigned char *cline;\n  struct queryheader *next;\n  struct queryline *first;\n};\n\nstruct queryline {\n  unsigned int rownum;\n  unsigned char *line;\n  unsigned int save;\n  struct queryline *next;\n};\n\n#define DB8_DISTINCT 1\n#define DB8_ROWSORT 2\n\nint db8_set_filename(unsigned char *filename);\nint db8_set_query(unsigned char *queryname, unsigned char *query);\nint db8_set_match(unsigned char *queryname, unsigned char *match);\nint db8_get_queryflags(unsigned char *queryname);\nint db8_set_queryflags(unsigned char *queryname, int flags);\n\nvoid db8_put(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value); \/\/ 2023 JariK\n\nint db8_get_element(unsigned char *queryname, int row, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value);\nint db8_get_element_current(unsigned char *queryname, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value);\nint db8_get_element_num(unsigned char *queryname, int row, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value);\nvoid db8_dump(unsigned char *queryname);\nint db8_put_element(unsigned char *queryname, int row, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value);\nint db8_save(unsigned char *queryname);\nint db8_save_all();\nint db8_clear(unsigned char *queryname);\nint db8_clear_all();\n\nvoid db8_squery(unsigned char *query); \/\/ JariK 2025 single\nvoid db8_iquery(); \/\/ JariK 2025 interactive\n\nextern int db8_verbose;<\/code><\/pre>\n\n\n\n<p>Db8 source db8.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;unistd.h&gt;\n\n#include \"db8.h\"\n#include \"more.h\"\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"DB8 version 0.05 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n\/\/#define MAIN 2 \/\/ in Makefile\n\/\/#define QUERY 2 \/\/ in Makefile\n\nint db8_verbose = 0;\n\nunsigned char *db8_set = NULL;\n\nstatic void db8_skipwhite(unsigned char **p)\n{\n  while(isblank(**p))\n    (*p)++;\n}\n\n#define aDEBUG8 2\n#define aDEBUG9 2\n#define aDEBUG10 2\n#define aDEBUG11 2\n\nvoid db8_get_element2(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  *namelen = -1;\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *namelen = 0;\n    *name = p;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db8_skipwhite(&amp;p);\n\n  *valuelen = -1;\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *valuelen = 0;\n    *value = p;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG8\n  if(db8_verbose) {\n    fprintf(stderr,\"db8_get_element2():\");\n    fprintf(stderr,\" name:%.*s(%d)\", *namelen, *name, *namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", *valuelen, *value, *valuelen);\n    fprintf(stderr,\", next:%s\",p);\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n#endif\n  \n  *p2 = p;\n}\n\n#define aDEBUG5 2\n\nint db8_get(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  if(*set == NULL)\n    return(0);\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n    \n  value&#91;0] = '\\0';\n\n  if(*set != NULL) {\n\n    firstelement = 1;\n    p = *set;\n    \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n            \n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}\n\nint db8_get_num(unsigned char **set, unsigned int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, col2, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  value&#91;0] = '\\0';\n  \n  if(*set != NULL) {\n    firstelement = 1;\n    p = *set;\n    col2 = 0;\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n\n      if(col2 == col &amp;&amp; name != NULL &amp;&amp; value != NULL) {\n\n\tstrncpy(name, name2, namesize);\n\tif(namesize &gt;= namelen2)\n\t  name&#91;namelen2] = '\\0';\n\telse\n\t  name&#91;namesize - 1] = '\\0';\n\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\n\tretval = 1;\n\tbreak;\n      }\n      col2++;\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}\n\n#define aSORTED 2\n#define aDEBUG17 2\n\nvoid db8_put(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n\n#ifdef DEBUG5\n  fprintf(stdout,\"\\ndb8_put: oldset:%s\", *set);\n  if(*set != NULL)\n    fprintf(stdout,\"(%ld)\", strlen(*set));\n\n  fprintf(stdout,\", namelen:%d\", namelen);\n  fprintf(stdout,\", name:%.*s\", namelen, name);\n  fprintf(stdout,\", valuelen:%d\", valuelen);\n  fprintf(stdout,\", value:%.*s\", valuelen, value);\n  fflush(stdout);\n#endif\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  firstelement = 1;\n  lastelement = 0;\n\n  if(*set != NULL &amp;&amp; strlen(*set) == 0) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set == NULL) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set != NULL) {\n\n    p = *set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      } else {\n\tif(*p == '\\0') {\n\t  lastelement = 1;\n\t  break;\n\t}\n      }\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } \/\/ end of if(set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n  if(value != NULL) {\n    if((firstelement &amp;&amp; found) || \/\/ first and existing\n       (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n      elementfmt = \"'%.*s' = \\\"%.*s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n    else if(firstelement) \/\/ first and not existing element\n      elementfmt = \"'%.*s' = \\\"%.*s\\\", \"; \/\/ --&gt; comma in the end (first new)\n    else\n      elementfmt = \", '%.*s' = \\\"%.*s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n  \n    count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n    if(elementsize &lt; count) {\n      elementsize = count;\n      if((element = realloc(element, elementsize)) == NULL) {\n\tfprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n\texit(1);\n      }\n      count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n    }\n  } else { \/\/ else of if(value != NULL\n\n    if((firstelement &amp;&amp; found) || \/\/ first and existing\n       (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n      elementfmt = \"'%.*s'\"; \/\/ --&gt; no commas (first existing or only)\n    else if(firstelement) \/\/ first and not existing element\n      elementfmt = \"'%.*s', \"; \/\/ --&gt; comma in the end (first new)\n    else\n      elementfmt = \", '%.*s'\"; \/\/ ..&gt; comma in the beginning (other)\n  \n    count = snprintf(element, elementsize, elementfmt, namelen, name) + 1;\n    if(elementsize &lt; count) {\n      elementsize = count;\n      if((element = realloc(element, elementsize)) == NULL) {\n\tfprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n\texit(1);\n      }\n      count = snprintf(element, elementsize, elementfmt, namelen, name) + 1;\n    } \/\/ end of if(elementsize &lt; count\n  } \/\/ end of if(value != NULL\n\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(*set != NULL) {\n    count += strlen(*set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr, \"old length:%ld %s\\n\", oldcount, set);\n    fflush(stderr);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempset = *set;\n    if((*set = realloc(*set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = *set + (thiselement - tempset);\n    if(nextelement != NULL)\n      nextelement = *set + (nextelement - tempset);\n\n    if(tempset == NULL)\n      *set&#91;0] = '\\0';\n  }\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = *set + strlen(*set);\n  if(nextelement == NULL)\n    nextelement = *set + strlen(*set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr,\"new length:%ld %s\\n\", count, *set);\n    fflush(stderr);\n  }\n#endif  \n\n#ifdef DEBUG5\n  fprintf(stdout,\", newset:%s\\n\", *set);\n  fflush(stdout);\n#endif\n}\n\nunsigned char db8_filename&#91;128];\n\nint db8_set_filename(unsigned char *filename)\n{\n  FILE *fp1;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: set_filename\");\n    fprintf(stdout,\", filename=%s\", filename);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  if((fp1 = fopen(filename, \"r\"))==NULL) {\n    fprintf(stderr,\"%s: db8 cannot open file '%s'\\n\", procname, filename);\n    exit(1);\n  }\n  fclose(fp1);\n\n  strcpy(db8_filename, filename);\n\n  return(0);\n}\n\nstruct queryheader *firstqueryheader = NULL;\n\nstruct queryheader *db8_queryheader(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *thisqh;\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh == NULL) { \/\/ create new\n    thisqh = malloc(sizeof(struct queryheader));\n    thisqh-&gt;queryname = malloc(strlen(queryname) + 1);\n    strcpy(thisqh-&gt;queryname, queryname);\n    thisqh-&gt;flags = 0;\n    thisqh-&gt;query = NULL;\n    thisqh-&gt;match = NULL;\n    thisqh-&gt;count = 0;\n    thisqh-&gt;preread = 20;\n    thisqh-&gt;cline = NULL;\n    thisqh-&gt;next = firstqueryheader;\n    thisqh-&gt;first = NULL;\n    firstqueryheader = thisqh;\n  } else { \/\/ allready in list\n    \/\/ remove from list\n    thisqh = *ppqh;\n    *ppqh = thisqh-&gt;next;\n    \/\/ add back to 1st of list\n    thisqh-&gt;next = firstqueryheader;\n    firstqueryheader = thisqh;\n  }\n  return(thisqh);\n}\n\nint db8_set_query(unsigned char *queryname, unsigned char *query)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_query\");\n  fprintf(stdout,\", query:%s\", query);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;query != NULL)\n    free(qh-&gt;query);\n\n  qh-&gt;query = malloc(strlen(query) + 1);\n  strcpy(qh-&gt;query, query);\n  \n  return(0);\n}\n\n#define aDEBUG42 2\n\nint db8_set_match(unsigned char *queryname, unsigned char *match)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_match\");\n  fprintf(stdout,\", match:%s\", match);\n  fprintf(stdout,\"\\n\");\n#endif\n#ifdef DEBUG42\n  fprintf(stdout,\"db8: set_match\");\n  fprintf(stdout,\", match:%s\", match);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;match != NULL)\n    free(qh-&gt;match);\n\n  qh-&gt;match = malloc(strlen(match) + 1);\n  strcpy(qh-&gt;match, match);\n  \n  return(0);\n}\n\nint db8_get_queryflags(unsigned char *queryname)\n{\n  struct queryheader *qh;\n\n  qh = db8_queryheader(queryname);\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: get_queryflags\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", flags=%d\", qh-&gt;flags);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  \n  return(qh-&gt;flags);\n}\n\nint db8_set_queryflags(unsigned char *queryname, int flags)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_queryflags\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", flags=%d\", flags);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n  qh-&gt;flags = flags;\n  \n  return(0);\n}\n\nstatic struct queryline *db8_lineheader(unsigned char *queryname, int rownum)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n\n  add = 1;\n  qh = db8_queryheader(queryname);\n  ppql = &amp;qh-&gt;first;\n  while(*ppql != NULL) {\n    if(rownum == (*ppql)-&gt;rownum) { \/\/ matching row found\n      add = 0; \/\/ no need to add new\n      break;\n    } else if(rownum &lt; (*ppql)-&gt;rownum) { \/\/ first larger row\n      add = 1; \/\/ add new before\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n  if(add) {\n    struct queryline *thisql;\n    thisql = malloc(sizeof(struct queryline));\n    thisql-&gt;line = NULL;\n    thisql-&gt;rownum = rownum;\n    thisql-&gt;save = 0;\n    thisql-&gt;next = *ppql;\n    *ppql = thisql;\n  }\n  return(*ppql);\n}\n\n#define aDEBUG26 2\n\n#define aDEBUG92 2\n\nvoid db8_fputs_len(FILE *fp1, unsigned int slen, unsigned char *s)\n{\n  while(slen-- &gt; 0)\n    fputc(*s++, fp1);\n}\n\nint db8_match_pattern_len(unsigned int plen, unsigned char *p, unsigned int slen, unsigned char *s)\n{\n  while(plen &gt; 0) {\n#ifdef DEBUG92\n    more_printf(stdout,\"\\nplen=%d\", plen);\n    more_printf(stdout,\", p=\");\n    db8_fputs_len(stdout, plen, p);\n    more_printf(stdout,\", slen=%d\", slen);\n    more_printf(stdout,\", s=\");\n    db8_fputs_len(stdout, slen, s);\n#endif\n\n    if(*p == '*') { \/\/ one or many characters\n      if(slen == 0)\n\treturn(0);\n      while(slen &gt; 0) {\n\ts++;\n\tslen--;\n\tif(db8_match_pattern_len(plen - 1, p + 1, slen, s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(slen == 0)\n\treturn(0);\n      s++;\n      slen--;\n    } else if(*p == *s) {\n      s++;\n      slen--;\n    } else\n      return(0);\n    p++;\n    plen--;\n  }\n  if(slen == 0)\n    return(1);\n  else\n    return(0);\n}\n\n#define aDEBUG48 2\n\nstatic int db8_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_match: match:%s\", match);\n    fprintf(stdout,\", set:%s\", set);\n    fflush(stdout);\n  }\n#endif\n  \n#ifdef DEBUG48\n  fprintf(stdout,\"db8_match: match:%s\", match);\n  fprintf(stdout,\", set:%s\", set);\n  fflush(stdout);\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db8_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db8_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;m); \/\/ match\n    db8_skipwhite(&amp;m);\n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb8_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s); \/\/ set\n      db8_skipwhite(&amp;s);\n#ifdef OLD1\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value2, value, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n#endif\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || db8_match_pattern_len(valuelen, value, valuelen2, value2) == 1)) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n\n#ifdef DEBUG48\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n#ifdef DEBUG5\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n\n  return(ok);\n}\n\nstatic void db8_free_set(unsigned char **set)\n{\n  if(*set != NULL) {\n    free(*set);\n    *set = NULL;\n  }\n}\n\n#define aDEBUG52 2\n\nstatic void db8_project(unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG52\n  more_printf(stdout,\"db8_project: \");\n  more_printf(stdout,\", query:%s\", query);\n  more_printf(stdout,\", set:%s\\n\", set);\n  fflush(stdout); fflush(stdout);\n#endif\n\n#ifdef DEBUG52\n  more_printf(stdout,\"db8_project: \");\n  more_printf(stdout,\" set:%s\\n\", set);\n#endif\n  \n  if(*project != NULL)\n    *(project&#91;0]) = '\\0';\n  \n  q = query;\n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db8_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb8_skipwhite(&amp;s);\n      }\n\n#ifdef OLD1\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n#endif\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || db8_match_pattern_len(valuelen, value, valuelen2, value2) == 1)) {\n#ifdef DEBUG52\n\tmore_printf(stdout,\"db8_project: \");\n\tmore_printf(stdout,\"'%.*s'\", namelen, name);\n\tmore_printf(stdout,\" = \\\"%.*s\\\"\", valuelen2, value2);\n\tmore_printf(stdout,\"\\n\");\n#endif\n\tdb8_put(project, namelen, name, valuelen2, value2);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n#ifdef DEBUG5\n  more_printf(stdout,\", project:(%s)\", *project);\n  more_printf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}\n\n#define aDEBUG63 2\n#define aDEBUG54 2\n\nstatic unsigned char *db8_fgets(int *stringlen, unsigned char **string, FILE *fp1)\n{\n  int count, retval, done;\n  unsigned char buffer&#91;128];\n  unsigned char *buf = *string;\n\n  if(buf != NULL)\n    buf&#91;0] = '\\0';\n\n  retval = 1;\n  done = 0;\n\n  for(;;) {\n    if(fgets(buffer, sizeof(buffer), fp1) == NULL) {\n      retval = 0;\n      break;\n    }\n    \n    if(buffer&#91;strlen(buffer)-1] == '\\n') {\n      buffer&#91;strlen(buffer)-1] = '\\0';\n      done = 1;\n    }\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: buffer: %s\\n\", buffer);\n#endif\n    count = 0;\n    if(buf != NULL)\n      count += strlen(buf);\n    count += strlen(buffer) + 1;\n    \n    if(*stringlen &lt; count) {\n      unsigned char *prevbuf = buf;\n      *stringlen = count;\n      buf = realloc(buf, *stringlen);\n      if(prevbuf == NULL)\n\tbuf&#91;0] = '\\0';\n    }\n    \n    strcat(buf, buffer);\n\n    if(done)\n      break;\n  }\n  *string = buf;\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: string: %s\\n\", *string);\n#endif\n  \n#ifdef DEBUG63\n  fprintf(stdout,\"%s\\n\", *string);\n#endif\n  \n  if(retval == 0)\n    return(NULL);\n  else {\n    return(*string);\n  }\n}\n\n#define aDEBUG62 2\n\nstatic void db8_renumbersets(unsigned char *queryname) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rownum;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rownum = 0;\n  while(ql != NULL) {\n    ql-&gt;rownum = rownum;\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_renumbersets:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rownum++;\n    ql = ql-&gt;next;\n  }\n}\n\nstatic void db8_countsets(unsigned char *queryname) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rows;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rows = 0;\n  while(ql != NULL) {\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_countsets:\");\n    more_printf(stdout,\" %d:\", rows);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rows++;\n    ql = ql-&gt;next;\n  }\n  qh-&gt;count = rows;\n  if(qh-&gt;flags)\n    more_printf(stdout,\"%d rows.\\n\", rows);\n}\n\n#ifdef OLD\n\nstatic long db8_atol(unsigned char **p, int *length) \/\/ JariK 2025\n{\n  int count = 0;\n  long num = 0;\n\n  while(isdigit(**p) &amp;&amp; count &lt; 18) { \/\/ calculate 19 first digits\n    num = num * 10 + (**p - '0');\n    \/\/more_printf(stdout,\"%ld\\n\", num);\n    (*p)++;\n    count++;\n  }\n  if(length != NULL)\n    *length = count;\n     \n  while(isdigit(**p)) { \/\/ skip rest\n    (*p)++;\n  }\n  return(num);\n}\n\n#endif\n\nstatic long db8_atol_dec(unsigned char **p, int *decimals) \/\/ JariK 2025\n{\n  int count = 0, decimals2 = 0;\n  long num = 0;\n\n  while(**p == '0')\n    (*p)++;\n  \n  while(isdigit(**p) &amp;&amp; count &lt; 18) { \/\/ calculate 19 first digits\n    num = num * 10 + (**p - '0');\n    \/\/more_printf(stdout,\"%ld\\n\", num);\n    (*p)++;\n    count++;\n  }\n  if(**p == '.') {\n    (*p)++;\n    while(isdigit(**p) &amp;&amp; count &lt; 18) { \/\/ calculate 19 first digits\n      num = num * 10 + (**p - '0');\n      \/\/more_printf(stdout,\"%ld\\n\", num);\n      (*p)++;\n      count++;\n      decimals2++;\n    }\n  }\n  if(decimals != NULL)\n    *decimals = decimals2;\n  \n  while(isdigit(**p)) { \/\/ skip rest\n    (*p)++;\n  }\n  return(num);\n}\n\n#ifdef OLD\n\nstatic long db8_strcmp_num(unsigned char *p, unsigned char *q) \/\/ JariK 2025\n{\n  long num1, num2;\n\n  for(;;) {\n    \/\/more_printf(stdout,\"p:%s, q:%s\\n\", p, q);\n    if(isdigit(*p) &amp;&amp; isdigit(*q)) {\n      num1 = db8_atol(&amp;p, NULL);\n      num2 = db8_atol(&amp;q, NULL);\n      if(num1 - num2 != 0)\n\treturn(num1 - num2);\n    } else if(*p - *q != 0) {\n      return(*p - *q);\n    } else {\n      if(*p == '\\0' || *q == '\\0')\n\tbreak;\n      p++;\n      q++;\n    }\n  }\n  return(0);\n}\n\n#endif\n\n#include &lt;math.h&gt;\n\nstatic long db8_strcmp_numdec(unsigned char *p, unsigned char *q) \/\/ JariK 2025\n{\n  int dec1, dec2;\n  long num1, num2;\n  \n  for(;;) {\n    \/\/more_printf(stdout,\"p:%s, q:%s\\n\", p, q);\n    if(isdigit(*p) &amp;&amp; isdigit(*q)) {\n      num1 = db8_atol_dec(&amp;p, &amp;dec1);\n      num2 = db8_atol_dec(&amp;q, &amp;dec2);\n      if(dec2 &gt; dec1)\n\tnum1 *= (int) pow((double) 10, (double) dec2-dec1);\n      else if(dec1 &gt; dec2)\n\tnum2 *= (int) pow((double) 10, (double) dec1-dec2);\n\t\n      if(num1 - num2 != 0)\n\treturn(num1 - num2);\n    } else if(*p - *q != 0) {\n      return(*p - *q);\n    } else {\n      if(*p == '\\0' || *q == '\\0')\n\tbreak;\n      p++;\n      q++;\n    }\n  }\n  return(0);\n}\n\nstatic int db8_matchandproject(unsigned char *queryname, unsigned char *row)\n{\n  struct queryheader *qh;\n  int match;\n  unsigned char *project = NULL;\n  \n  qh = db8_queryheader(queryname);\n  match = 0;\n  if(qh-&gt;match == NULL ||\n     strstr(row, qh-&gt;match) != NULL)\n    match = 1;\n  if(match) {\n    match = 0;\n    if(qh-&gt;query == NULL)\n      match = 1;\n    else if(db8_match(row, qh-&gt;query)) {\n      db8_free_set(&amp;project);\n      db8_project(&amp;project, row, qh-&gt;query);\n      strcpy(row, project);\n      match = 1;\n    }\n  }\n  return(match);\n}\n\n#ifdef OLD1\n\nint db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n \n  FILE *fp1;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      \/\/if(buffer&#91;strlen(buffer) - 1] == '\\n')\n      \/\/  buffer&#91;strlen(buffer) - 1] = '\\0';\n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_free_set(&amp;project);\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  fprintf(stdout,\"\\n====row:%s\", row);\n\t  match = 1;\n\t}\n      }\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;qline-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n  FILE *fp1;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  match = 1;\n\t}\n      }\n      \/\/fprintf(stdout,\"match:%d\\n\",match);\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element_num:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  \n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;qline-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}\n\n#endif\n\n#ifdef OLD1\n\nstruct queryline *db8_cache_set(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  struct queryline *ql;\n  \n#ifdef DEBUG59\n  fprintf(stdout,\"db8_cache_set:\");\n  fprintf(stdout,\" %d\", rownum);\n  fprintf(stdout,\" %s\", set);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  ql = db8_lineheader(queryname, rownum);\n  if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n    exit(1);\n  }\n  strcpy(ql-&gt;line, set);\n\n  return(ql);\n}\n\nstruct queryline *db8_cacheset_flags(unsigned char *queryname, int rownum, unsigned char *set) \/\/ JariK 2025\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n  \n  qh = db8_queryheader(queryname);\n\n  add = 1;\n\n  ppql = &amp;qh-&gt;first;\n\n  while(*ppql != NULL) {\n    if((qh-&gt;flags &amp; DB8_DISTINCT) &amp;&amp;\n       !strcmp(set, (*ppql)-&gt;line) ) {\n      add = 0;\n      break;\n    }\n    if((qh-&gt;flags &amp; DB8_ROWSORT) &amp;&amp;\n       db8_strcmp_numdec(set, (*ppql)-&gt;line) &lt; 0) {\n      \/\/strcmp(set, (*ppql)-&gt;line) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n\n  if(add) {\n    struct queryline *ql;\n    ql = malloc(sizeof(struct queryline));\n    if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n      fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n      exit(1);\n    }\n    strcpy(ql-&gt;line, set);\n#ifdef DEBUG61\n    more_printf(stdout,\"db8_cacheset_flags:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    ql-&gt;rownum = 0;\n    ql-&gt;next = *ppql;\n    *ppql = ql;\n  }\n  \n  return(NULL);\n}\n\nstruct queryline *db8_get_line(unsigned char *queryname, int rownum) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2, count;\n  \n  FILE *fp1;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n\n  if(ql == NULL &amp;&amp; qh-&gt;flags &amp;&amp; qh-&gt;count != 0)\n    return(NULL);\n\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n      if(db8_matchandproject(queryname, row)) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  if(qh-&gt;flags) {\n\t    ql = db8_cacheset_flags(queryname, rownum2, row);\n\t  } else {\n\t    ql = db8_cache_set(queryname, rownum2, row);\n\t  }\n#ifdef DEBUG65\n\t  more_printf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\t  if(qh-&gt;flags) \/\/ sorting --&gt; read all\n\t    continue;\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 ||\n\t     count &gt; rownum + qh-&gt;preread)\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n\n    fclose(fp1);\n\n    if(qh-&gt;flags) {\n      db8_renumbersets(queryname);\n      db8_countsets(queryname);\n      qline = qh-&gt;first;\n    }\n  }\n\n  return(qline);\n}\n\n#endif \/\/ end of #ifdef OLD1\n\nstruct queryline *db8_getline_cache(unsigned char *queryname, int rownum) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  return(ql);\n}\n\n#define aDEBUG61 2\n#define aDEBUG57 2\n#define aDEBUG58 2\n#define aDEBUG65 2\n#define aDEBUG59 2\n\nstruct queryline *db8_getline(unsigned char *queryname, int rownum) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2, count;\n  \n  FILE *fp1;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = db8_getline_cache(queryname, rownum);\n  \n  qline = ql;\n\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n#ifdef DEBUG58\n      more_printf(stdout,\"input:    \");\n      more_printf(stdout,\"%s\", row);\n      more_printf(stdout,\"\\n\");\n#endif\n      if(db8_matchandproject(queryname, row)) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG57\n\t  more_printf(stdout,\"selected: \");\n\t  more_printf(stdout,\"%s\", row);\n\t  more_printf(stdout,\"\\n\");\n#endif\n\n#ifdef DEBUG65\n\t  more_printf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 ||\n\t     count &gt; rownum + qh-&gt;preread)\n\t    break;\n\t} \/\/ end of if(rownum2\n\trownum2++;\n      } \/\/ end of if(db8_matchandproject\n    } \/\/ end of for(;;\n\n    fclose(fp1);\n\n    db8_countsets(queryname);\n  } \/\/ end of if(ql == NULL\n\n  qh-&gt;cline = qline-&gt;line;\n    \n  return(qline);\n}\n\nstruct queryline *db8_getline_flags(unsigned char *queryname, int rownum) \/\/ JariK 2025\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline, **ppql;\n\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2;\n  \n  FILE *fp1;\n\n  qh = db8_queryheader(queryname);\n\n  ql = db8_getline_cache(queryname, rownum);\n  \n  if(ql == NULL &amp;&amp; qh-&gt;count != 0) { \/\/ flags --&gt; read only once\n    qh-&gt;cline = NULL;\n    return(NULL);\n  }\n\n  qline = ql;\n\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n#ifdef DEBUG58\n      more_printf(stdout,\"input:    \");\n      more_printf(stdout,\"%s\", row);\n      more_printf(stdout,\"\\n\");\n#endif\n      if(db8_matchandproject(queryname, row)) {\n\tint add = 1;\n\n\tppql = &amp;qh-&gt;first;\n\t\n\twhile(*ppql != NULL) {\n\t  if((qh-&gt;flags &amp; DB8_DISTINCT) &amp;&amp;\n\t     !strcmp(row, (*ppql)-&gt;line) ) {\n\t    add = 0;\n\t    break;\n\t  }\n\t  if((qh-&gt;flags &amp; DB8_ROWSORT) &amp;&amp;\n\t     db8_strcmp_numdec(row, (*ppql)-&gt;line) &lt; 0) {\n\t    \/\/strcmp(row, (*ppql)-&gt;line) &lt; 0) {\n\t    add = 1;\n\t    break;\n\t  }\n\t  ppql = &amp;((*ppql)-&gt;next);\n\t} \/\/ end of while(*ppql != NULL\n\t\n\tif(add) {\n\t  struct queryline *ql;\n\t  ql = malloc(sizeof(struct queryline));\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG57\n\t  more_printf(stdout,\"selected: \");\n\t  more_printf(stdout,\"%s\", row);\n\t  more_printf(stdout,\"\\n\");\n#endif\n#ifdef DEBUG61\n\t  more_printf(stdout,\"db8_cacheset_flags:\");\n\t  more_printf(stdout,\" %d:\", rownum);\n\t  more_printf(stdout,\" %s\", ql-&gt;line);\n\t  more_printf(stdout,\"\\n\");\n#endif\n\t  ql-&gt;rownum = 0; \/\/ rownumbers come from renumber\n\t  ql-&gt;next = *ppql;\n\t  *ppql = ql;\n\t} \/\/ end of if(add\n\t\n#ifdef DEBUG65\n\tmore_printf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\trownum2++;\n      } \/\/ end of if(db8_matchandproject\n    } \/\/ end of for(;;\n\n    fclose(fp1);\n\n    db8_renumbersets(queryname); \/\/ flags\n    db8_countsets(queryname);\n    qline = qh-&gt;first;\n  }\n    \n  qh-&gt;cline = qline-&gt;line;\n\n  return(qline);\n}\n\n#define aDEBUG69 2\n\nint db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n  qh = db8_queryheader(queryname);\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  if(qh-&gt;flags)\n    ql = db8_getline_flags(queryname, rownum);\n  else\n    ql = db8_getline(queryname, rownum);\n    \n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;ql-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_current(unsigned char *queryname, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 20250602 JariK\n{\n  struct queryheader *qh;\n\n  qh = db8_queryheader(queryname);\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  if(qh-&gt;cline != NULL) {\n    int retval = db8_get(&amp;qh-&gt;cline, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n  qh = db8_queryheader(queryname);\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  if(qh-&gt;flags)\n    ql = db8_getline_flags(queryname, rownum);\n  else\n    ql = db8_getline(queryname, rownum);\n    \n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;ql-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}\n\nint db8_get_element_num_current(unsigned char *queryname, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryheader *qh;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n  qh = db8_queryheader(queryname);\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  if(qh-&gt;cline != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;qh-&gt;cline, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}\n\nint db8_put_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: put_element\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", namelen=%u\", namelen);\n    fprintf(stdout,\", name=%.*s\", namelen, name);\n    fprintf(stdout,\", valuelen=%u\", valuelen);\n    fprintf(stdout,\", value=%.*s\", valuelen, value);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  \/\/db8_set = db8_find_set(queryname, rownum);\n\n  ql = db8_lineheader(queryname, rownum);\n  db8_put(&amp;ql-&gt;line, namelen, name, valuelen, value); \/\/ 2023 JariK\n  ql-&gt;save = 1;\n  return(0);\n}\n\nvoid db8_dump(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n  qh = db8_queryheader(queryname);\n  fprintf(stdout,\"qh=%p\", qh);\n  fprintf(stdout,\", queryname=%s\", qh-&gt;queryname);\n  fprintf(stdout,\", flags=%d\", qh-&gt;flags);\n  fprintf(stdout,\", query=%s\", qh-&gt;query);\n  fprintf(stdout,\", count=%d\", qh-&gt;count);\n  fprintf(stdout,\", preread=%d\", qh-&gt;preread);\n  fprintf(stdout,\", next=%p\", qh-&gt;next);\n  fprintf(stdout,\", first=%p\", qh-&gt;first);\n  fprintf(stdout,\"\\n\");\n  \n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    fprintf(stdout,\"ql=%p\", ql);\n    fprintf(stdout,\", rownum=%d\", ql-&gt;rownum);\n    fprintf(stdout,\", save=%d\", ql-&gt;save);\n    fprintf(stdout,\", next=%p\", ql-&gt;next);\n    fprintf(stdout,\", line=%p\", ql-&gt;line);\n    if(ql-&gt;line != NULL)\n      fprintf(stdout,\" %s\", ql-&gt;line);\n    fprintf(stdout,\"\\n\");\n    ql = ql-&gt;next;\n  }\n  fflush(stdout);\n}\n\nint db8_save(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save:\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  qh = db8_queryheader(queryname);\n\n  fprintf(stdout,\"%s\\n\", db8_set);\n\n  FILE *fp1;\n  if((fp1 = fopen(db8_filename, \"a\"))==NULL) {\n    fprintf(stdout,\"%s: db8 cannot open file '%s'\\n\", procname, db8_filename);\n    exit(1);\n  }\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(ql-&gt;save) {\n      fprintf(fp1,\"%s\\n\", ql-&gt;line);\n      ql-&gt;save = 0;\n    }\n    ql = ql-&gt;next;\n  }\n  \n  fclose(fp1);\n\n  db8_dump(queryname);\n\n  return(0);\n}\n\nint db8_save_all()\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    db8_save(qh-&gt;queryname);\n    qh = qh-&gt;next;\n  }\n  return(0);\n}\n\nint db8_clear(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *qh;\n  struct queryline *ql, *qlnext;\n  \n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"clear %s\", queryname);\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh != NULL) {\n    qh = *ppqh;\n    ql = qh-&gt;first;\n    *ppqh = qh-&gt;next;\n    free(qh);\n    \n    while(ql != NULL) {\n      qlnext = ql-&gt;next;\n      if(ql-&gt;line != NULL)\n\tfree(ql-&gt;line);\n      free(ql);\n      ql = qlnext;\n    }\n  }\n  return(0);\n}\n\nint db8_clear_all()\n{\n  struct queryheader *qh, *qhnext;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_clear_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    qhnext = qh-&gt;next;\n    db8_clear(qh-&gt;queryname);\n    qh = qhnext;\n  }\n  return(0);\n}\n\nint db8_exit()\n{\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_exit:\\n\");\n  }\n#endif\n  \n  return(0);\n}\n\nvoid db8_version()\n{\n  fprintf(stdout, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stdout, \", %s\", copyright);\n}\n#ifdef QUERY\n#include &lt;signal.h&gt;\n\nint ctrlcquit = 0;\n\nstatic void sig_handler()\n{\n  fprintf(stderr,\"Ctrl-c pressed\\n\");\n  ctrlcquit = 1;\n  \/\/signal(SIGINT, SIG_DFL);\n}\n\nstatic int db8_ischar(int c)\n{\n  if(isalpha(c) || isdigit(c) || c &gt;= 0x80 || c == '_')\n    return(1);\n  else\n    return(0);\n}\n\nint db8_isquote(int c)\n{\n  if(ispunct(c) &amp;&amp; c != ',' &amp;&amp; c != '=')\n    return(1);\n  else\n    return(0);\n}\n\n#define aDEBUG60\n\nstatic int namequote = -1, valuequote = -1;\n\nstatic void db8_get_element3(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  if(namequote == -1) {\n    if(db8_isquote(*p))\n      namequote = *p;\n    else\n      namequote = 0;\n  }\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 1 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *namelen = -1;\n  if((*p == namequote &amp;&amp; namequote) ||\n     (db8_ischar(*p) &amp;&amp; !namequote)) { \/\/ name\n    *namelen = 0;\n#ifdef DEBUG60\n    fprintf(stdout,\"db8_get_element: 2 %s\\n\", p);\n#endif\n    if(namequote) {\n      p++;\n      *name = p;\n      while(*p != namequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 3 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n      if(*p == namequote)\n\tp++;\n    } else {\n      *name = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 4 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n    }\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n    db8_skipwhite(&amp;p);\n  }\n\n  if(valuequote == -1) {\n    if(db8_isquote(*p))\n      valuequote = *p;\n    else\n      valuequote = 0;\n  }\n  \n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 5 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *valuelen = -1;\n  if((*p == valuequote &amp;&amp; valuequote) ||\n     (db8_ischar(*p) &amp;&amp; !valuequote)) { \/\/ value\n    *valuelen = 0;\n    if(valuequote) {\n      p++;\n#ifdef DEBUG60\n      fprintf(stdout,\"db8_get_element: 6 %s\\n\", p);\n#endif\n      *value = p;\n      while(*p != valuequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 7 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n      if(*p == valuequote)\n\tp++;\n    } else {\n      *value = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 8 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n    }\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 9 %s\\n\", p);\n#endif\n  *p2 = p;\n}\n\nvoid db8_squery(unsigned char *query) \/\/ JariK 2025 single\n{\n  int row, col, first, ok, print;\n\n  unsigned int namelen;\n  unsigned int valuelen;\n  unsigned char *name, *value;\n\n  unsigned char *q;\n  unsigned char *query2 = NULL;\n\n  if(more)\n    more_init(); \/\/ adjust thee screensize\n  \n  q = query;\n  fprintf(stdout,\"query:%s\\n\", query);\n  fflush(stdout);\n\n  namequote = -1;\n  valuequote = -1;  \n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element3(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    if(name == NULL)\n      break;\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n    fprintf(stderr,\"db8_squery():\");\n    fprintf(stderr,\" name:%.*s(%d)\", namelen, name, namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", valuelen, value, valuelen);\n    fprintf(stderr,\"\\n\");\n    db8_put(&amp;query2, namelen, name, valuelen, value);\n  }\n  db8_set_filename(db8_filename);\n  fprintf(stdout,\"query2:%s\\n\", query2);\n  db8_clear(\"query\");\n  db8_set_query(\"query\", query2);\n  \/\/db8_set_queryflags(\"query\", 0);\n  \/\/db8_set_queryflags(\"query\", DB8_DISTINCT);\n  \/\/db8_set_queryflags(\"query\", DB8_ROWSORT);\n  db8_set_queryflags(\"query\", DB8_ROWSORT | DB8_DISTINCT);\n\n  free(query2);\n\n  row = 0;\n\n  unsigned int namesize2, namelen2, valuesize2, valuelen2;\n  unsigned char name2&#91;128], value2&#91;128];\n\n  namesize2 = sizeof(name2);\n  valuesize2 = sizeof(value2);\n\n  for(;;) {\n\n    morequit = 0;\n    print = 0;\n    first = 1;\n    col = 0;\n    ok = 0;\n\n    if(db8_get_queryflags(\"query\"))\n      db8_getline_flags(\"query\", row);\n    else\n      db8_getline(\"query\", row);\n\n    for(;;) {\n      \/\/fprintf(stdout,\"row:%d, col:%d, \", row, col);\n      \n      if(db8_get_element_num_current(\"query\", col, namesize2, &amp;namelen2, name2, valuesize2, &amp;valuelen2, value2))\n\tok = 1;\n      else\n\tbreak;\n\n      if(col == 0)\n\tfprintf(stdout,\"%d \", row);\n      \n      if(!first)\n\tfprintf(stdout,\", \");\n\n      print = 1;\n      \n      more_printf(stdout,\"'%s' = \\\"%s\\\"\", name2, value2);\n      fflush(stdout);\n      col++;\n      first = 0;      \n    }\n    if(print) {\n      more_printf(stdout,\"\\n\");\n      fflush(stdout);\n    }\n#ifdef DB8_QUERY_CALL\n    extern void db8_query_call();\n    db8_get_element_num(\"query\", row, 0, namesize2, &amp;namelen2, name2, valuesize2, &amp;valuelen2, value2);\n    db8_query_call(\"\");\n#endif\n    if(!ok)\n      break;\n    if(more &amp;&amp; morequit)\n      break;\n    if(ctrlcquit) {\n      ctrlcquit = 0;\n      break;\n    }\n    \n    row++;\n  }\n  \/\/db8_dump(\"query\");\n}\n\nunsigned char prompt&#91;128] = \"skk&gt;\";\n\nstatic int db8_isword(unsigned char **p2, unsigned char *word)\n{\n  unsigned char *p;\n\n  int wlen = strlen(word);\n  \n  p = *p2;\n  db8_skipwhite(&amp;p);\n  if(!strncmp(word, p, wlen) &amp;&amp;\n     ( (isblank(*(p + wlen))) ||\n       (ispunct(*(p + wlen))) ||\n       (*(p + wlen) == '\\0') ) ) {\n    p += wlen;\n    db8_skipwhite(&amp;p);\n    *p2 = p;\n    return(1);\n  } else\n    return(0);\n}\n\nvoid db8_iquery() \/\/ JariK 2025 interactive\n{\n  unsigned char *command = NULL, *p;\n  int commandsize = 0;\n\n  ctrlcquit = 0;\n  signal(SIGINT, sig_handler);\n  fprintf(stdout,\"%s\\n\", programname);\n  \n  for(;;) {\n    fprintf(stdout, \"%s\", prompt);\n    db8_fgets(&amp;commandsize, &amp;command, stdin);\n    p = command;\n    db8_skipwhite(&amp;p);\n    if(*p == '\\0')\n       continue;\n    if(db8_isword(&amp;p, \"more\")) {\n      if(db8_isword(&amp;p, \"on\")) {\n\tmore = 1;\n\tcontinue;\n      }\n      if(db8_isword(&amp;p, \"off\")) {\n\tmore = 0;\n\tcontinue;\n      }\n      more = !more;\n      fprintf(stderr,\"more \");\n      if(more)\n\tfprintf(stderr,\"on\");\n      else\n\tfprintf(stderr,\"off\");\n      fprintf(stderr,\"\\n\");\n      continue;\n    }\n    if(db8_isword(&amp;p, \"copyright\") ||\n       db8_isword(&amp;p, \"version\") ) {\n      fprintf(stderr, \"%s\", programname);\n      fprintf(stderr, \", %s\\n\", copyright);\n      continue;\n    }\n    if(db8_isword(&amp;p, \"exit\"))\n      break;\n    if(db8_isword(&amp;p, \"quit\"))\n      break;\n    if(db8_isword(&amp;p, \"*\")) {\n      db8_squery(NULL);      \n    } else\n      db8_squery(p);\n  }\n  signal(SIGINT, SIG_DFL);\n}\n\n#endif\n\n#ifdef MAIN\n\n#define aDEBUG92 2\n#define DEBUG96 2\n\nint my_match(unsigned char *pattern, unsigned char *string)\n{\n  unsigned char *p, *s;\n\n  p = pattern;\n  s = string;\n\n  while(*p != '\\0') {\n#ifdef DEBUG92\n    more_printf(stdout,\"\\npattern=%s\",p);\n    more_printf(stdout,\", string=%s\",s);\n#endif\n\n    if(*p == '*') { \/\/ one or many characters\n      if(*s == '\\0')\n\treturn(0);\n      while(*s != '\\0') {\n\tif(my_match(p + 1, ++s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(*s == '\\0')\n\treturn(0);\n      s++;\n    } else if(*p == *s) {\n      s++;\n    } else\n      return(0);\n    p++;\n  }\n  if(*s == '\\0')\n    return(1);\n  else\n    return(0);\n}\n\nint my_match_len(unsigned int plen, unsigned char *p, unsigned int slen, unsigned char *s)\n{\n  while(plen &gt; 0) {\n#ifdef DEBUG92\n    more_printf(stdout,\"\\nplen=%d\", plen);\n    more_printf(stdout,\", p=\");\n    db8_fputs_len(stdout, plen, p);\n    more_printf(stdout,\", slen=%d\", slen);\n    more_printf(stdout,\", s=\");\n    db8_fputs_len(stdout, slen, s);\n#endif\n\n    if(*p == '*') { \/\/ one or many characters\n      if(slen == 0)\n\treturn(0);\n      while(slen &gt; 0) {\n\ts++;\n\tslen--;\n\tif(my_match_len(plen - 1, p + 1, slen, s))\n\t  return(1);\n      }\n    } else if(*p == '?') { \/\/ one character\n      if(slen == 0)\n\treturn(0);\n      s++;\n      slen--;\n    } else if(*p == *s) {\n      s++;\n      slen--;\n    } else\n      return(0);\n    p++;\n    plen--;\n  }\n  if(slen == 0)\n    return(1);\n  else\n    return(0);\n}\n\nint my_match_test(unsigned char *p, unsigned char *s) \/\/ 2025 JariK\n{\n  int retval, plen, slen;\n  static unsigned int testid = 0;\n\n  more_printf(stdout,\"%d\", testid);\n\n  more_printf(stdout,\", p=%s\", p);\n  more_printf(stdout,\", s=%s\", s);\n\n  retval = my_match(p, s);\n  if(retval)\n    more_printf(stdout,\" match!\");\n  else\n    more_printf(stdout,\" no match!\");\n\n  more_printf(stdout,\"\\n\");\n\n  more_printf(stdout,\"%d\", testid++);\n\n  plen = strlen(p);\n  slen = strlen(s);\n\n  \/\/more_printf(stdout,\" plen=%d\", plen);\n  more_printf(stdout,\", p=%s\", p);\n  \/\/more_printf(stdout,\", slen=%d\", slen);\n  more_printf(stdout,\", s=%s\", s);\n\n  retval = my_match_len(plen, p, slen, s);\n  if(retval)\n    more_printf(stdout,\" match!\");\n  else\n    more_printf(stdout,\" no match!\");\n\n  more_printf(stdout,\"\\n\");\n    \n  return(retval);\n}\n\nunsigned char *procname;\n\nchar *query = NULL;\nunsigned char filename&#91;128] = \"newressusudoku.skk.db\";\n\nint main(int argc, char *argv&#91;])\n{\n  int c, args = 0, help = 0;\n  \n  procname = argv&#91;0];\n\n  more = 0;\n  if(isatty(STDOUT_FILENO))\n    more = 1;\n  \n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n    \n    if(!strcmp(\"--help\", argv&#91;c])) {\n      help = 1;\n\n    } else if(!strcmp(\"--args\", argv&#91;c])) {\n      args = !args;\n\n    } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t      !strcmp(\"--version\", argv&#91;c])) {\n      fprintf(stderr, \"%s\", programname);\n      fprintf(stderr, \", %s\\n\", copyright);\n      exit(0);\n      \n    } else if(!strncmp(\"--skkfile\", argv&#91;c], 9)) { \/\/ JariK 2025\n      if(*(argv&#91;c] + 9) != '\\0') {\n\tstrcpy(filename, argv&#91;c] + 9);\n      } else if(c + 1 &lt; argc) {\n\tstrcpy(filename, argv&#91;c + 1]);\n\tc++;\n      }\n\n    } else if(!strncmp(\"--query\", argv&#91;c], 7)) { \/\/ JariK 2025\n      query = NULL;\n      if(*(argv&#91;c] + 7) != '\\0') {\n\tquery = argv&#91;c] + 7;\n      } else if(c + 1 &lt; argc &amp;&amp; *(argv&#91;c + 1]) != '-') {\n\tquery = argv&#91;c + 1];\n\tc++;\n      }\n      \n    } else if(!strncmp(\"--more\", argv&#91;c], 6)) { \/\/ JariK 2025\n      more = !more;\n\n    }\n  }\n\n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--skkfile&#91;filename]]\");\n    fprintf(stderr,\" &#91;--query&#91;querytext]]\");\n    fprintf(stderr,\" &#91;--more]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n#ifdef DEBUG96\n\n  if(more)\n    more_init(); \/\/ adjust thee screensize\n\n  more_printf(stdout, \"zero delimited match\\n\");\n  my_match_test(\"?\",\"\");\n  my_match_test(\"*\",\"\");\n  my_match_test(\"a?\",\"a\");\n  my_match_test(\"a*\",\"a\");\n  my_match_test(\"abcdef\",\"abcdef\");\n  my_match_test(\"abc*def\",\"abcdefdef\");\n  my_match_test(\"abc*def\",\"abcdefdefdef\");\n  my_match_test(\"abc*\",\"abcdef\");\n  my_match_test(\"*def\",\"abcdef\");\n  my_match_test(\"*cd*\",\"abcdef\");\n  my_match_test(\"*cd*\",\"abcdefcdefcdef\");\n  my_match_test(\"ab??ef\",\"abcdef\");\n  my_match_test(\"??def\",\"abcdef\");\n  my_match_test(\"???def\",\"abcdef\");\n  my_match_test(\"*gh*\",\"abcdef\");\n  my_match_test(\"abcdef\",\"abcgef\");\n  my_match_test(\"?*def\",\"abcdef\");\n  my_match_test(\"?*def\",\"abcdefg\");\n  my_match_test(\"?b\",\"ab\");\n  my_match_test(\"a?\",\"ab\");\n  my_match_test(\"a?c\",\"abc\");\n  my_match_test(\"a??d\",\"abcd\");\n  my_match_test(\"a??*d\",\"abcd\");\n  my_match_test(\"?b\",\"ac\");\n#endif\n\n  if(args) {\n    fprintf(stderr,\"argc: %d\\n\", argc);\n    for(c = 0; c &lt; argc; c++) {\n      fprintf(stderr,\"argv&#91;%d]: %s\\n\", c, argv&#91;c]);\n    }\n    exit(1);\n  }\n\n#ifdef TEST\n\n  unsigned long l = 0;\n  c = 0;\n  for(;;) {\n    unsigned long oldl = l;\n    l = l * 10 + 9;\n    fprintf(stdout,\"%d %lu\\n\", c++, l);\n    if((l - 9) \/ 10 != oldl)\n      break;\n  }\n\n#endif\n\n  db8_set_filename(filename);\n  \n  if(query !=NULL)\n    db8_squery(query);\n  else\n    db8_iquery();\n\n  exit(0);\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>Db8 source more.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;string.h&gt;\n#include &lt;malloc.h&gt;\n\n#include &lt;termios.h&gt;\n\nstatic unsigned char *programname = \"more version 0.1 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nstruct termios old, new;\n\nvoid startprompt()\n{\n  setvbuf(stdout, NULL, _IONBF, 0);\n  tcgetattr(0, &amp;old);\n  new = old;\n  new.c_lflag &amp;= ~(ICANON | ECHO);\n  \/\/new.c_lflag &amp;= ~(ISIG | ICANON | ECHO);\n  new.c_cc&#91;VMIN] = 1;\n  new.c_cc&#91;VTIME] = 2;\n  tcsetattr(0, TCSANOW, &amp;new);\n}\n\nvoid endprompt()\n{\n  tcsetattr(0, TCSANOW, &amp;old);\n}\n\nvoid more_backspacechars(int chars)\n{\n  int c;\n  \n  for(c = 0; c &lt; chars; c++)\n    fputc('\\b', stdout);\n  for(c = 0; c &lt; chars; c++)\n    fputc(' ', stdout);\n  for(c = 0; c &lt; chars; c++) \n    fputc('\\b', stdout);\n}\n\nint more = 1;\n\nint screenlinesleft = 0, screenmaxchars, screenmaxlines;\nint screenchars = 0;\nint morequit = 0;\n\n#include &lt;sys\/ioctl.h&gt; \/\/ for TIOCGWINSZ\n\nvoid more_init()\n{\n  struct winsize w;\n  ioctl(0, TIOCGWINSZ, &amp;w);\n  screenmaxchars = w.ws_col;\n  screenmaxlines = w.ws_row - 1;\n  screenlinesleft = screenmaxlines;\n}\n\nvoid more_version()\n{\n  fprintf(stderr, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stderr, \", %s\", copyright);\n}\n\nvoid more_wait()\n{\n  int c;\n  unsigned char *moretext = \"---more---\";\n  \n  fprintf(stderr,\"%s\", moretext);\n\n  if(more) {\n    startprompt();\n\n    \/\/ wait until something below is pressed\n  \n    for(;;) {\n      c = getchar();\n      if(c == ' ') {\n\tmore_init(); \/\/ adjust for screensize\n\tscreenlinesleft = screenmaxlines; \/\/ full screen\n\tbreak;\n      } else if(c == '\\n') {\n\tmore_init(); \/\/ adjust for screensize\n\tscreenlinesleft = 1; \/\/ one line\n\tbreak;\n      } else if(c == 'q') { \/\/ quit\n\tmorequit = 1;\n\tbreak;\n      }\n    }\n  \n    more_backspacechars(strlen(moretext));\n  \n    endprompt();\n  } \/\/ end of if(more\n}\n\n#include &lt;stdarg.h&gt;\n\nvoid more_printf(FILE *fp1, const char *format, ...)\n{\n  int count;\n  va_list args;\n  unsigned char *p;\n  static char *printbuf = NULL;\n  static int printbuf_len = 0;\n\n  va_start(args, format);\n  count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf = realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ prompt more for full screen pages.\n  \n  p = printbuf;\n  while(*p!='\\0') {\n    fputc(*p, fp1);\n    if(*p == '\\n' || ++screenchars == screenmaxchars) {\n      screenchars = 0;\n      if(more &amp;&amp; --screenlinesleft == 0) {\n\tmore_wait();\n      }\n    }\n    p++;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Toinen t\u00e4rke\u00e4 asia edellisess\u00e4 postissa oli tietysti satunnaisbittigeneraattori: seuraava ohjelma yritt\u00e4\u00e4 laskea pi:n pseudoressun satunnaisbittien perusteella:<\/p>\n\n\n\n<p>Pi ohjelmassa  on jo aiemmista posteista tuttuja p\u00e4tki\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define KILO 1024\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2) \/\/ 2023 JariK\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p) \/\/ 2023 JariK\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p) \/\/ 2023 JariK\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n#define DEBUG32 2\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nunsigned long long getlonglong(unsigned char *p2) \/\/ 2023 JariK\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value: %d\", digit);\n      fprintf(stderr,\", base: %d\", base);\n      fprintf(stderr,\", ll: %llu\", prevll);\n      fprintf(stderr,\", multiplier: %llu\", multiplier);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb, 1gb or 1mb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value: %d\", digit);\n    fprintf(stderr,\", base: %d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n\n  return(totll);\n}<\/code><\/pre>\n\n\n\n<p>Toinen tuttu p\u00e4tk\u00e4, jolla arvotaan satunnaisuus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define GENT_SIZE 1024\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\nint newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n    pseudoressu_bytes(sizeof(gent), gent);\n  } \/\/ if(gent_pos == 0\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n  return(ch);\n}\n\nunsigned long newressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n\n  return(word);\n}<\/code><\/pre>\n\n\n\n<p>Ja pi ohjelma kokonaisuudessaan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;math.h&gt;\n#include &lt;ctype.h&gt;\n#include \"newressu.h\"\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressupi version 0.06 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nunsigned char *log_filename = \"newressupi.log\";\n\n#include &lt;time.h&gt;\n\n#include &lt;stdarg.h&gt;\n\nvoid log_printf(const char *format, ...) \/\/ JariK 2025\n{\n  int count;\n  va_list args;\n  static char *printbuf = NULL;\n  static int printbuf_len = 0;\n  static int printtime = 1;\n  va_start(args, format);\n  count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf = realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ print all characters to log adding time and date.\n  \n  fputs(printbuf, stdout);\n\n  FILE *fp1;\n  if((fp1 = fopen(log_filename, \"a\")) != NULL) {\n    if(printtime) {\n      time_t now = time(NULL);\n      unsigned char timestamp&#91;32];\n      strftime(timestamp, sizeof(timestamp), \"%Y%m%d%H%M%S%Z\", localtime((time_t *)&amp;now));\n      fputs(timestamp, fp1);\n      fputc(' ', fp1);\n      printtime = 0;\n    }\n    fputs(printbuf, fp1);\n    fclose(fp1);\n    if(printbuf&#91;strlen(printbuf) - 1] == '\\n')\n      printtime = 1;\n  }\n}\n\n#define KILO 1024\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2) \/\/ 2023 JariK\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p) \/\/ 2023 JariK\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p) \/\/ 2023 JariK\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n#define DEBUG32 2\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nunsigned long long getlonglong(unsigned char *p2) \/\/ 2023 JariK\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value: %d\", digit);\n      fprintf(stderr,\", base: %d\", base);\n      fprintf(stderr,\", ll: %llu\", prevll);\n      fprintf(stderr,\", multiplier: %llu\", multiplier);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb, 1gb or 1mb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value: %d\", digit);\n    fprintf(stderr,\", base: %d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n\n  return(totll);\n}\n\n#define GENT_SIZE 1024\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\nint newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n    pseudoressu_bytes(sizeof(gent), gent);\n  } \/\/ if(gent_pos == 0\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n  return(ch);\n}\n\n#define DEBUG13 2\n\nunsigned long newressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n#ifdef DEBUG13\n    fprintf(stdout,\"%s: newressu_gen_limit:\", procname);\n    fprintf(stdout,\" limit:%lu(\", limit);\n    readablelonglong(stdout, limit);\n    fprintf(stdout,\")\");\n    fprintf(stdout,\", highlimit:%lu(\", highlimit);\n    readablelonglong(stdout, highlimit);\n    fprintf(stdout,\")\");\n    fprintf(stdout,\", bytes:%u\", bytes);\n    fprintf(stdout,\"\\n\");\n#endif\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n\n  return(word);\n}\n\n#define aDEBUG10 2\n\n\/\/#define BLOCK 1000000000\n#define BLOCK 1000000000\nunsigned int block = BLOCK;\n#define RANDFUNC pseudoressu_bytes\n\n#define DECIMALS 20\n\nvoid main(int argc, char *argv&#91;])\n{\n  int c, bytes = 0, help = 0;\n  unsigned long long limit = 0, divider, round, llx, lly, inside = 0;\n  double x, y;\n#ifdef DEBUG10\n  double minx = 999, miny = 999, maxx = -999, maxy = -999;\n#endif\n\n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n    if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strncmp(\"--bytes\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  bytes = atoi(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  bytes = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tif(bytes &lt; 1 || bytes &gt; 8) {\n\t  fprintf(stderr,\"%s: --bytes must be between 1 and 8\\n\", procname);\n\t  exit(1);\n\t}\n\tlimit = 0;\n\n      } else if(!strncmp(\"--limit\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  limit = getlonglong(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  limit = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tif(limit &lt; 2) {\n\t  fprintf(stderr,\"%s: --limit must be greater or equal than 2\\n\", procname);\n\t  exit(1);\n\t}\n\tbytes = 0;\n\n      } else if(!strncmp(\"--block\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  block = getlonglong(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  block = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tif(block &lt; 2) {\n\t  fprintf(stderr,\"%s: --block must be greater or equal than 2\\n\", procname);\n\t  exit(1);\n\t}\n      }\n    }\n  }\n  \n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--bytes n]\");\n    fprintf(stderr,\" &#91;--limit n]\");\n    fprintf(stderr,\" &#91;--block n]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n#ifdef OLD1\n  \n  switch(bytes) {\n    case 1:\n      divider = 0xff;\n      break;\n    case 2:\n      divider = 0xffff;\n      break;\n    case 3:\n      divider = 0xffffff;\n      break;\n    case 4:\n      divider = 0xffffffff;\n      break;\n    case 5:\n      divider = 0xffffffffff;\n      break;\n    case 6:\n      divider = 0xffffffffffff;\n      break;\n    case 7:\n      divider = 0xffffffffffffff;\n      break;\n    case 8:\n      divider = (unsigned long long) 0xffffffffffffffff;\n      break;\n  }\n\n#endif \/\/ end of #ifdef OLD1\n\n  if(limit == 0 &amp;&amp; bytes == 0)\n    bytes = 4;\n\n  if(bytes != 0) {\n    divider = 0;\n    for(c = 0; c &lt; bytes; c++) {\n      divider = (divider &lt;&lt; 8) + 0xff;\n    }\n  } else\n    divider = limit - 1;\n\n  if(bytes)\n    fprintf(stdout,\"bytes %d\", bytes);\n  if(limit) {\n    fprintf(stdout,\"limit %llu(\", limit);\n    readablelonglong(stdout, limit);\n    fprintf(stdout,\")\");\n  }\n  fprintf(stdout,\", block %u\", block);\n  fprintf(stdout,\", step %1.*f\", DECIMALS, (double)2 \/ divider - (double)1 \/ divider);\n  fprintf(stdout,\", divider %llu(\", divider);\n  readablelonglong(stdout, divider);\n  fprintf(stdout,\")\");\n  fprintf(stdout,\"\\n\");\n\n  for(round = 0;; round++) {\n    llx = 0;\n    lly = 0;\n\n#ifdef DEBUG10\n    fprintf(stdout,\"rounds=%llu\", round);\n#endif\n\n    if(bytes) {\n      RANDFUNC(bytes, (unsigned char *)&amp;llx); \/\/ little endian\n      RANDFUNC(bytes, (unsigned char *)&amp;lly); \/\/ little endian\n      \/\/RANDFUNC(bytes, (unsigned char *)&amp;llx + 8 - bytes); \/\/ big endian\n      \/\/RANDFUNC(bytes, (unsigned char *)&amp;lly + 8 - bytes); \/\/ big endian\n    } else if(limit) {\n      llx = newressu_gen_limit(limit);\n      lly = newressu_gen_limit(limit);\n    }\n\n#ifdef DEBUG10\n    fprintf(stdout,\", llx=%llx\", (unsigned long long)llx);\n    fprintf(stdout,\", lly=%llx\", (unsigned long long)lly);\n#endif\n\n    x = (double) llx \/ divider; \/\/ random number between 0 and 1\n    y = (double) lly \/ divider; \/\/ random number between 0 and 1\n    \n#ifdef DEBUG10\n    fprintf(stdout,\", x=%f\", x);\n    fprintf(stdout,\", y=%f\", y);\n#endif\n    \n#ifdef DEBUG10\n\n    if(minx &gt; x)\n      minx = x;    \n    if(miny &gt; y)\n      miny = y;\n    if(maxx &lt; x)\n      maxx = x;    \n    if(maxy &lt; y)\n      maxy = y;\n\n    fprintf(stdout,\", minx=%f\", minx);\n    fprintf(stdout,\", miny=%f\", miny);\n    fprintf(stdout,\", maxx=%f\", maxx);\n    fprintf(stdout,\", maxy=%f\", maxy);\n#endif\n\n    if(sqrt(x * x + y * y) &lt; 1)\n      inside++;\n\n#ifdef DEBUG10\n    fprintf(stdout,\", inside=%llu\", inside);\n    fprintf(stdout,\", pi=%1.*f\", DECIMALS, (double)4 * inside \/ round);\n    fprintf(stdout,\"\\n\");\n#endif\n\n    if(round &gt; 0 &amp;&amp; round % block == 0) {\n      log_printf(\"rounds = %llu\", round);\n      log_printf(\", inside = %llu\", inside);\n      log_printf(\", pi = %1.*f\", DECIMALS, (double)4 * inside \/ round);\n      if(bytes != 0)\n\tlog_printf(\", bytes = %d\", bytes);\n      if(limit != 0)\n\tlog_printf(\", limit = %llu\", limit);\n      log_printf(\"\\n\");\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa p\u00e4tk\u00e4 pi:n haun logista (newressupi.log):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>20250728111134EEST rounds = 591000000000, inside = 464170507728, pi = 3.14159396093400999916, bytes = 7\n20250728111628EEST rounds = 633000000000, inside = 497156881071, pi = 3.14159166553554491941, bytes = 6\n20250728112348EEST rounds = 955000000000, inside = 750055265602, pi = 3.14159273550575912637, limit = 17293822569102704640\n20250728112357EEST rounds = 733000000000, inside = 575689846725, pi = 3.14155441596180073915, bytes = 2\n20250728112552EEST rounds = 599000000000, inside = 470453646868, pi = 3.14159363517863088333, bytes = 8\n20250728113232EEST rounds = 656000000000, inside = 515221382817, pi = 3.14159379766463420225, bytes = 5\n20250728114328EEST rounds = 685000000000, inside = 537997696622, pi = 3.14159238903357662664, bytes = 4\n20250728114727EEST rounds = 956000000000, inside = 750840642527, pi = 3.14159264655648540199, limit = 17293822569102704640\n20250728114944EEST rounds = 724000000000, inside = 568627945710, pi = 3.14159086027624301352, bytes = 3\n20250728120621EEST rounds = 782000000000, inside = 612285705793, pi = 3.13189619331457791418, bytes = 1\n20250728120946EEST rounds = 957000000000, inside = 751626011893, pi = 3.14159252619853690547, limit = 17293822569102704640\n20250728122446EEST rounds = 592000000000, inside = 464955901877, pi = 3.14159393160135147482, bytes = 7\n20250728122640EEST rounds = 734000000000, inside = 576475228866, pi = 3.14155438074114456981, bytes = 2\n20250728123006EEST rounds = 634000000000, inside = 497942282544, pi = 3.14159168797476340274, bytes = 6\n20250728123126EEST rounds = 958000000000, inside = 752411423621, pi = 3.14159258296868459936, limit = 17293822569102704640\n20250728123623EEST rounds = 657000000000, inside = 516006768084, pi = 3.14159371740639281612, bytes = 5\n20250728124124EEST rounds = 600000000000, inside = 471239037042, pi = 3.14159358027999990881, bytes = 8\n20250728124919EEST rounds = 686000000000, inside = 538783103661, pi = 3.14159244117201152946, bytes = 4\n20250728125049EEST rounds = 725000000000, inside = 569413330861, pi = 3.14159079095724136366, bytes = 3\n20250728125306EEST rounds = 959000000000, inside = 753196826239, pi = 3.14159260162252351734, limit = 17293822569102704640\n20250728130422EEST rounds = 783000000000, inside = 613068702173, pi = 3.13189630739719016006, bytes = 1\n20250728131320EEST rounds = 960000000000, inside = 753982213607, pi = 3.14159255669583314940, limit = 17293822569102704640\n20250728132348EEST rounds = 735000000000, inside = 577260619699, pi = 3.14155439291972804483, bytes = 2<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Suomessa lahjoituksen voi tehd\u00e4, mutta sit\u00e4 ei voi pyyt\u00e4\u00e4. Jos haluat lahjoittaa kuitenkin projektille, laita lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Jos lahjoitat sata euroa tai enemm\u00e4n ja haluat vastalahjan, voit saada vastalahjana sudokun tai t\u00e4m\u00e4nhetkisen sorsan. Vastalahjasudokua tai sorsaa varten kirjoita&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=2930\">Continue reading <span class=\"screen-reader-text\">Sudokues everywhere: summer sudokues, new hardest steps 13 sudoku found, revisiting db8: db8 list on harder sudokues by digits and by steps, db8 source, db8 string pattern matching, trying to find pi using pseudoressu pseudo random bit generator<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/2930"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2930"}],"version-history":[{"count":39,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/2930\/revisions"}],"predecessor-version":[{"id":2988,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/2930\/revisions\/2988"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}