Skip to content

Commit e40630a

Browse files
authored
Merge pull request #306 from sysprog21/precise-grading
Precise grading
2 parents d249da7 + d8410c9 commit e40630a

File tree

2 files changed

+251
-60
lines changed

2 files changed

+251
-60
lines changed

qtest.c

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ typedef struct {
6666

6767
static queue_chain_t chain = {.size = 0};
6868
static queue_contex_t *current = NULL;
69+
static int new_ok = 0; /* Successful q_new() calls */
70+
static int new_cnt = 0; /* Total q_new() attempts */
71+
static bool impl_found = false; /* Real implementation detected */
72+
static int size_calls = 0; /* Total q_size calls */
73+
static int size_neg = 0; /* q_size returning -1 */
6974

7075
/* How many times can queue operations fail */
7176
static int fail_limit = BIG_LIST_SIZE;
@@ -156,6 +161,16 @@ static bool do_new(int argc, char *argv[])
156161
qctx->id = chain.size++;
157162

158163
current = qctx;
164+
165+
new_cnt++;
166+
if (qctx->q) {
167+
new_ok++;
168+
impl_found = true; /* Real q_new() implementation exists */
169+
}
170+
171+
/* Check if q_new is properly implemented when malloc should succeed */
172+
if (!qctx->q && fail_probability == 0 && fail_limit == 0)
173+
ok = false;
159174
}
160175
exception_cancel();
161176
q_show(3);
@@ -210,10 +225,8 @@ static bool queue_insert(position_t pos, int argc, char *argv[])
210225

211226
char *inserts = argv[1];
212227
if (argc == 3) {
213-
if (!get_int(argv[2], &reps) || reps < 1) {
214-
report(1, "Invalid number of insertions '%s'", argv[2]);
228+
if (!get_int(argv[2], &reps) || reps < 1)
215229
return false;
216-
}
217230
}
218231

219232
if (!strcmp(inserts, "RAND")) {
@@ -240,7 +253,6 @@ static bool queue_insert(position_t pos, int argc, char *argv[])
240253
: list_first_entry(current->q, element_t, list);
241254
char *cur_inserts = entry->value;
242255
if (!cur_inserts) {
243-
report(1, "ERROR: Failed to save copy of string in queue");
244256
ok = false;
245257
} else if (r == 0 && inserts == cur_inserts) {
246258
report(1,
@@ -363,10 +375,8 @@ static bool queue_remove(position_t pos, int argc, char *argv[])
363375
q_release_element(re);
364376

365377
removes[string_length + STRINGPAD] = '\0';
366-
if (removes[0] == '\0') {
367-
report(1, "ERROR: Failed to store removed value");
378+
if (removes[0] == '\0')
368379
ok = false;
369-
}
370380

371381
/* Check whether padding in array removes are still initial value 'X'.
372382
* If there's other character in padding, it's overflowed.
@@ -548,13 +558,25 @@ static bool do_size(int argc, char *argv[])
548558
}
549559

550560
int cnt = 0;
551-
if (!current || !current->q)
561+
if (!current || !current->q) {
552562
report(3, "Warning: Calling size on null queue");
563+
/* For NULL queue, q_size should return 0, not -1 */
564+
cnt = q_size(NULL);
565+
size_calls++;
566+
if (cnt == -1)
567+
size_neg++;
568+
if (cnt != 0)
569+
return false;
570+
return true;
571+
}
553572
error_check();
554573

555574
if (current && exception_setup(true)) {
556575
for (int r = 0; ok && r < reps; r++) {
557576
cnt = q_size(current->q);
577+
size_calls++;
578+
if (cnt == -1)
579+
size_neg++;
558580
ok = ok && !error_check();
559581
}
560582
}
@@ -645,9 +667,8 @@ bool do_sort(int argc, char *argv[])
645667
unstable = true;
646668
break;
647669
}
648-
if (nodes[i] == cur_l) {
670+
if (nodes[i] == cur_l)
649671
break;
650-
}
651672
}
652673
if (unstable) {
653674
report(
@@ -823,10 +844,8 @@ static bool do_reverseK(int argc, char *argv[])
823844
error_check();
824845

825846
if (argc == 2) {
826-
if (!get_int(argv[1], &k) || k < 1) {
827-
report(1, "Invalid number of K (at least 1)");
847+
if (!get_int(argv[1], &k) || k < 1)
828848
return false;
829-
}
830849
} else {
831850
report(1, "Invalid number of arguments for reverseK");
832851
return false;
@@ -1441,6 +1460,38 @@ int main(int argc, char *argv[])
14411460
bool ok = true;
14421461
ok = ok && run_console(infile_name);
14431462

1463+
/* Check if q_new() is actually implemented */
1464+
if (new_cnt > 0 && new_ok == 0 && fail_probability > 0) {
1465+
/* If malloc was set to fail partially but q_new() NEVER succeeded, it
1466+
* means q_new() is not implemented (always returns NULL)
1467+
*/
1468+
report(1,
1469+
"ERROR: q_new() never succeeded despite partial malloc failures "
1470+
"(%d attempts). Function not implemented.",
1471+
new_cnt);
1472+
ok = false;
1473+
}
1474+
1475+
/* Check if any actual implementation exists */
1476+
if (!impl_found && chain.size == 0 && new_cnt > 0) {
1477+
/* If we attempted to create queues but none succeeded, then the
1478+
* implementation is just stubs.
1479+
*/
1480+
report(1,
1481+
"ERROR: No functional queue implementation detected. All "
1482+
"functions appear to be stubs.");
1483+
ok = false;
1484+
}
1485+
1486+
/* Check for stub q_size implementation */
1487+
if (size_calls > 0 && size_neg == size_calls) {
1488+
/* If q_size always returned -1, it's the stub implementation */
1489+
report(1,
1490+
"ERROR: q_size() always returns -1 (stub implementation "
1491+
"detected).");
1492+
ok = false;
1493+
}
1494+
14441495
/* Do finish_cmd() before check whether ok is true or false */
14451496
ok = finish_cmd() && ok;
14461497

0 commit comments

Comments
 (0)