0706 nwnss: audit queue sharedsrc runtime

This commit is contained in:
Mario Fetka
2026-06-17 11:57:24 +00:00
parent 22afa3941b
commit 2d854e0d76
4 changed files with 327 additions and 4 deletions

View File

@@ -114,6 +114,7 @@ still stay original and remain listed, because later imports may rely on them.
| PARTIAL | `src/nwnss/comn/common/ndp_messagehandler.c` | ORIG wrapper | link smoke | Novell wrapper name/pattern; full audit open. |
| TEMP | `src/nwnss/comn/comnModule.c` | TEMP | link smoke | Transition module identity bridge; should disappear later. |
| AUDITED | `src/nwnss/library/bit.c` | PORT | nwnss.bit, nwnss.bitmap | No original provider found beyond bit.h/libNSS.imp; native-NINT semantics fixed/tested in 0698. |
| AUDITED | `src/nwnss/library/que.c` + `src/nwnss/sharedsrc/que.c.h` + `include/nwnss/library/que.h` | ORIG wrapper + ORIG+FIX sharedsrc/header | nwnss.que | Wrapper matches Novell sharedsrc pattern; header and sharedsrc compared with original. Abweichungen sind Include-Pfad-Fixes, legacy callback casts and whitespace/diff-check cleanup only; STK/SQ/CIR/DQ/SET semantics tested in 0706. |
| AUDITED | `src/nwnss/library/misc/rand.c` | PORT | nwnss.rand, nwnss.namespace | No original provider found beyond rand.h/libNSS.imp/callers; seed-deterministic PRNG port checked in 0700/0701; libsodium only initializes default state before explicit seeding. |
| AUDITED | `src/nwnss/library/misc/rbpTree.c` | PORT | nwnss.rbpTree | No original provider found beyond rbpTree.h/libNSS.imp/callers; CLRS-style algorithmic port checked against header contract in 0703 and strengthened in 0705 with explicit red/black, parent-link, binary-search-order, black-height, and Coin3D-style insertion/deletion stress coverage. Coin3D rbptree.cpp was checked only as an external BSD-licensed CLRS comparison and was not imported. |
| TODO | `src/nwnss/library/os/currentTime.c` | PORT | nwnss.utc | Userspace time port; full audit open. |
@@ -303,9 +304,9 @@ even if it already compiles or has indirect test coverage.
| TODO | ORIG header? | not yet classified | `include/nwnss/library/intlatch.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `include/nwnss/library/nssDebug.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `include/nwnss/library/omni.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `include/nwnss/library/que.h` | Must be compared against original source and classified. |
| AUDITED | ORIG+FIX | nwnss.que | `include/nwnss/library/que.h` | Compared with original `shared/sdk/library/que.h`; complete header kept. Differences are include path normalization (`<library/omni.h>`) and whitespace-only cleanup; extensive header-documented STK/SQ/CIR/DQ/SET contracts tested in 0706. |
| AUDITED | ORIG | nwnss.rand | `include/nwnss/library/rand.h` | Byte-identical to shared/sdk/library/rand.h; audited with rand.c in 0700. |
| AUDITED | ORIG header | nwnss.rbpTree | `include/nwnss/library/rbpTree.h` | Byte-identical to original shared/sdk/library/rbpTree.h; complete header kept. Header itself cites CLRS/Sedgewick and defines the RBP parent-pointer contract. |
| AUDITED | ORIG header | nwnss.rbpTree | `include/nwnss/library/rbpTree.h` | Byte-identical to original shared/sdk/library/rbpTree.h; complete header kept. Header itself cites CLRS/Sedgewick and defines the RBP parent-pointer contract. |
| TODO | ORIG header? | not yet classified | `include/nwnss/library/size_t.h` | Must be compared against original source and classified. |
| AUDITED | ORIG+FIX | nwnss.xstring | `include/nwnss/library/string.h` | Compared with original; MARS userspace include_next/strings.h branch only. |
| AUDITED | ORIG | nwnss.xctype | `include/nwnss/library/xCtype.h` | Byte-identical to original. |
@@ -562,7 +563,7 @@ even if it already compiles or has indirect test coverage.
| AUDITED | PORT | nwnss.bit, nwnss.bitmap | `src/nwnss/library/bit.c` | No original provider found beyond bit.h/libNSS.imp; native-NINT semantics fixed/tested in 0698. |
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/functionPtrs.c` | Must be compared against original source and classified. |
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/qdiv.c` | Must be compared against original source and classified. |
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/que.c` | Must be compared against original source and classified. |
| AUDITED | ORIG wrapper | nwnss.que | `src/nwnss/library/que.c` | Wrapper translation unit for original sharedsrc `que.c.h`; matches Novell sharedsrc-wrapper pattern. |
| AUDITED | PORT | nwnss.xctype | `src/nwnss/library/xCtype.c` | No original provider found beyond xCtype.h/libNSS.imp; ASCII table/toupper/tolower semantics tested in 0698. |
| AUDITED | PORT/ORIG+FIX | nwnss.xstring | `src/nwnss/library/xString.c` | LB_stricmp uses original sharedsrc; no original provider found for remaining libNSS.imp helpers; baseline semantics tested in 0698. |
@@ -795,7 +796,7 @@ even if it already compiles or has indirect test coverage.
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/ndp_messagehandler.c.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/otherErrorTables.c.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/parseDSObjectName.c.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/que.c.h` | Must be compared against original source and classified. |
| AUDITED | ORIG+FIX | nwnss.que | `src/nwnss/sharedsrc/que.c.h` | Compared with original `public_core/sharedsrc/que.c.h`; differences limited to include paths, legacy callback casts for modern compiler types, and whitespace/diff-check cleanup. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/stricmp.c.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/sysimp.c.h` | Must be compared against original source and classified. |
| TODO | ORIG header? | not yet classified | `src/nwnss/sharedsrc/uni2utf.c.h` | Must be compared against original source and classified. |

View File

@@ -25,6 +25,7 @@ add_subdirectory(pssmpk)
add_subdirectory(register)
add_subdirectory(rbpTree)
add_subdirectory(qdiv)
add_subdirectory(que)
add_subdirectory(rand)
add_subdirectory(schedule)
add_subdirectory(slab)

View File

@@ -0,0 +1,4 @@
add_executable(test_nwnss_que test_nwnss_que.c)
target_compile_features(test_nwnss_que PRIVATE c_std_99)
target_link_libraries(test_nwnss_que PRIVATE mars_nwe::nwnss)
add_test(NAME nwnss.que COMMAND test_nwnss_que)

View File

@@ -0,0 +1,317 @@
#include "library/que.h"
#include <stdio.h>
#define CHECK(expr) \
do { \
if (!(expr)) { \
fprintf(stderr, "CHECK failed at %s:%d: %s\n", __FILE__, __LINE__, #expr); \
return 1; \
} \
} while (0)
typedef struct QueNode_s {
int id;
struct STKlink_s stk;
struct SQlink_s sq;
struct CIRlink_s cir;
DQlink_t dq;
SETlink_t set;
} QueNode;
static void init_node(QueNode *node, int id)
{
node->id = id;
node->stk.next = NULL;
node->sq.next = NULL;
node->cir.next = NULL;
node->dq.next = NULL;
node->dq.prev = NULL;
node->set.next = NULL;
node->set.prev = NULL;
node->set.setNum = 0;
}
static void init_nodes(QueNode *nodes, int count)
{
int i;
for (i = 0; i < count; ++i) {
init_node(&nodes[i], i + 1);
}
}
static STATUS apply_sum(SETlink_t *link, void *arg)
{
QueNode *node = STRUCT(link, QueNode, set);
int *sum = (int *)arg;
*sum += node->id;
return zOK;
}
static int test_stack(void)
{
QueNode nodes[4];
STKtop_t top;
QueNode *item;
init_nodes(nodes, 4);
STK_INIT(top);
CHECK(STK_EMPTY(top));
CHECK(!STK_NOT_EMPTY(top));
STK_PUSH(top, &nodes[0], stk);
STK_PUSH(top, &nodes[1], stk);
STK_PUSH(top, &nodes[2], stk);
CHECK(STK_NOT_EMPTY(top));
STK_PEEK(top, item, QueNode, stk);
CHECK(item == &nodes[2]);
CHECK(STK_RMV(top, &nodes[1], stk) == TRUE);
CHECK(nodes[1].stk.next == NULL);
STK_POP(top, item, QueNode, stk);
CHECK(item == &nodes[2]);
CHECK(nodes[2].stk.next == NULL);
STK_POP_NO_CHECK(top, item, QueNode, stk);
CHECK(item == &nodes[0]);
CHECK(STK_EMPTY(top));
STK_POP(top, item, QueNode, stk);
CHECK(item == NULL);
init_nodes(nodes, 4);
STK_INIT_ELEMENTS(top, nodes, 4, QueNode, stk);
CHECK(!STK_EMPTY(top));
CHECK(STK_RMV(top, &nodes[2], stk) == TRUE);
CHECK(STK_RMV(top, &nodes[2], stk) == FALSE);
return 0;
}
static int test_singly_linked_queue(void)
{
QueNode nodes[6];
SQhead_t head;
SQhead_t other;
QueNode *item;
init_nodes(nodes, 6);
SQ_INIT(&head);
CHECK(SQ_EMPTY(&head));
CHECK(SQ_CNT(&head) == 0);
SQ_ENQ(&head, &nodes[0], sq);
SQ_ENQ(&head, &nodes[1], sq);
SQ_PUSH(&head, &nodes[2], sq);
CHECK(SQ_CNT(&head) == 3);
CHECK(SQ_FIND(&head, &nodes[1], sq) == TRUE);
CHECK(SQ_FIND(&head, &nodes[3], sq) == FALSE);
SQ_PEEK(&head, item, QueNode, sq);
CHECK(item == &nodes[2]);
SQ_DEQ(&head, item, QueNode, sq);
CHECK(item == &nodes[2]);
CHECK(nodes[2].sq.next == NULL);
CHECK(SQ_RMV(&head, &nodes[1], sq) == TRUE);
CHECK(nodes[1].sq.next == NULL);
SQ_DEQ_NO_CHECK(&head, item, QueNode, sq);
CHECK(item == &nodes[0]);
CHECK(SQ_EMPTY(&head));
SQ_INIT(&head);
SQ_INIT(&other);
SQ_ENQ(&head, &nodes[0], sq);
SQ_ENQ(&head, &nodes[1], sq);
SQ_ENQ(&other, &nodes[2], sq);
SQ_ENQ(&other, &nodes[3], sq);
SQ_APPEND(&head, &other);
CHECK(SQ_EMPTY(&other));
CHECK(SQ_CNT(&head) == 4);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[0]);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[1]);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[2]);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[3]);
CHECK(SQ_EMPTY(&head));
init_nodes(nodes, 6);
SQ_INIT(&head);
SQ_INIT(&other);
SQ_ENQ(&head, &nodes[4], sq);
SQ_ENQ(&other, &nodes[0], sq);
SQ_ENQ(&other, &nodes[1], sq);
SQ_PREPEND(&head, &other);
CHECK(SQ_EMPTY(&other));
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[0]);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[1]);
SQ_DEQ(&head, item, QueNode, sq); CHECK(item == &nodes[4]);
CHECK(SQ_EMPTY(&head));
return 0;
}
static int test_circular_queue(void)
{
QueNode nodes[6];
CIRhead_t head;
CIRhead_t other;
QueNode *item;
init_nodes(nodes, 6);
CIR_INIT(head);
CHECK(CIR_EMPTY(head));
CHECK(CIR_CNT(head) == 0);
CIR_ENQ(head, &nodes[0], cir);
CIR_ENQ(head, &nodes[1], cir);
CIR_PUSH(head, &nodes[2], cir);
CHECK(CIR_CNT(head) == 3);
CHECK(CIR_FIND(head, &nodes[1], cir) == TRUE);
CHECK(CIR_FIND(head, &nodes[4], cir) == FALSE);
CIR_PEEK(head, item, QueNode, cir);
CHECK(item == &nodes[2]);
CHECK(CIR_RMV(head, &nodes[1], cir) == TRUE);
CHECK(nodes[1].cir.next == NULL);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[2]);
CIR_DEQ_NO_CHECK(head, item, QueNode, cir); CHECK(item == &nodes[0]);
CHECK(CIR_EMPTY(head));
init_nodes(nodes, 6);
CIR_INIT(head);
CIR_INIT(other);
CIR_ENQ(head, &nodes[0], cir);
CIR_ENQ(head, &nodes[1], cir);
CIR_ENQ(other, &nodes[2], cir);
CIR_ENQ(other, &nodes[3], cir);
CIR_APPEND(head, other);
CHECK(CIR_EMPTY(other));
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[0]);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[1]);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[2]);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[3]);
CHECK(CIR_EMPTY(head));
init_nodes(nodes, 6);
CIR_INIT(head);
CIR_INIT(other);
CIR_ENQ(head, &nodes[4], cir);
CIR_ENQ(other, &nodes[0], cir);
CIR_ENQ(other, &nodes[1], cir);
CIR_PREPEND(head, other);
CHECK(CIR_EMPTY(other));
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[0]);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[1]);
CIR_DEQ(head, item, QueNode, cir); CHECK(item == &nodes[4]);
CHECK(CIR_EMPTY(head));
return 0;
}
static int test_doubly_linked_queue(void)
{
QueNode nodes[6];
DQhead_t head;
DQhead_t other;
QueNode *item;
init_nodes(nodes, 6);
DQ_INIT(&head);
CHECK(DQ_EMPTY(&head));
CHECK(DQ_CNT(&head) == 0);
CHECK(LBQ_DQaudit(&head) == 0);
DQ_ENQ(&head, &nodes[0], dq);
DQ_ENQ(&head, &nodes[1], dq);
DQ_PUSH(&head, &nodes[2], dq);
CHECK(DQ_CNT(&head) == 3);
CHECK(DQ_FIND(&head, &nodes[1], dq) == TRUE);
CHECK(DQ_FIND(&head, &nodes[4], dq) == FALSE);
CHECK(LBQ_DQaudit(&head) == 3);
DQ_PEEK(&head, item, QueNode, dq); CHECK(item == &nodes[2]);
DQ_PEEK_END(&head, item, QueNode, dq); CHECK(item == &nodes[1]);
DQ_RMV(&nodes[0], dq);
CHECK(nodes[0].dq.next == NULL);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[2]);
DQ_TAKE(&head, item, QueNode, dq); CHECK(item == &nodes[1]);
CHECK(DQ_EMPTY(&head));
init_nodes(nodes, 6);
DQ_INIT(&head);
DQ_INIT(&other);
DQ_ENQ(&head, &nodes[0], dq);
DQ_ENQ(&head, &nodes[1], dq);
DQ_ENQ(&other, &nodes[2], dq);
DQ_ENQ(&other, &nodes[3], dq);
DQ_APPEND(&head, &other);
CHECK(DQ_EMPTY(&other));
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[0]);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[1]);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[2]);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[3]);
CHECK(DQ_EMPTY(&head));
init_nodes(nodes, 6);
DQ_INIT(&head);
DQ_INIT(&other);
DQ_ENQ(&head, &nodes[4], dq);
DQ_ENQ(&other, &nodes[0], dq);
DQ_ENQ(&other, &nodes[1], dq);
DQ_PREPEND(&head, &other);
CHECK(DQ_EMPTY(&other));
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[0]);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[1]);
DQ_DEQ(&head, item, QueNode, dq); CHECK(item == &nodes[4]);
CHECK(DQ_EMPTY(&head));
return 0;
}
static int test_ordered_set(void)
{
QueNode nodes[6];
SEThead_t head;
QueNode *item;
int sum = 0;
init_nodes(nodes, 6);
SET_INIT(&head);
CHECK(SET_EMPTY(&head));
CHECK(SET_CNT(&head) == 0);
SET_ENQ(&head, &nodes[0], set);
SET_ENQ(&head, &nodes[1], set);
SET_PUSH(&head, &nodes[2], set);
CHECK(SET_CNT(&head) == 3);
CHECK(nodes[2].set.setNum < nodes[0].set.setNum);
CHECK(nodes[0].set.setNum < nodes[1].set.setNum);
CHECK(SET_FIND(&head, &nodes[1], set) == TRUE);
CHECK(SET_FIND(&head, &nodes[4], set) == FALSE);
SET_PEEK(&head, item, QueNode, set); CHECK(item == &nodes[2]);
SET_PEEK_END(&head, item, QueNode, set); CHECK(item == &nodes[1]);
CHECK(SET_APPLY(&head, (statusfunc_t)apply_sum, &sum) == zOK);
CHECK(sum == (nodes[2].id + nodes[0].id + nodes[1].id));
SET_RMV(&nodes[0], set);
CHECK(nodes[0].set.next == NULL);
SET_DEQ(&head, item, QueNode, set); CHECK(item == &nodes[2]);
SET_TAKE(&head, item, QueNode, set); CHECK(item == &nodes[1]);
CHECK(SET_EMPTY(&head));
init_nodes(nodes, 6);
SET_INIT(&head);
SET_ENQ(&head, &nodes[0], set);
SET_ENQ(&head, &nodes[1], set);
SET_DEQ_NO_CHECK(&head, item, QueNode, set); CHECK(item == &nodes[0]);
SET_DROP(&head, &nodes[1], set);
CHECK(SET_EMPTY(&head));
return 0;
}
int main(void)
{
CHECK(test_stack() == 0);
CHECK(test_singly_linked_queue() == 0);
CHECK(test_circular_queue() == 0);
CHECK(test_doubly_linked_queue() == 0);
CHECK(test_ordered_set() == 0);
return 0;
}