Skip to content

Commit

Permalink
Merge branch 'sysprog21:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
m561247 authored Apr 26, 2024
2 parents c75b4d8 + bef955a commit 3db3bd0
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 42 deletions.
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ Use your best judgment, and feel free to propose changes to this document in a p
This project uses GitHub Issues to track ongoing development, discuss project plans, and keep track of bugs.
Be sure to search for existing issues before you create another one.

Initially, it is advisable to create an issue on GitHub for bug reports, feature requests,
or substantial pull requests, as this offers a platform for discussion with both the community and project maintainers.

Engaging in a conversation through a GitHub issue before making a contribution is crucial to ensure the acceptance of your work.
We aim to prevent situations where significant effort is expended on a pull request that might not align with the project's design principles.
For example, it might turn out that the feature you propose is more suited as an independent module that complements this project,
in which case we would recommend that direction.

For minor corrections, such as typo fixes, small refactoring, or updates to documentation/comments,
filing an issue is not typically necessary.
What constitutes a "minor" fix involves discretion; however, examples include:
- Correcting spelling mistakes
- Minor code refactoring
- Updating or editing documentation and comments

Nevertheless, there may be instances where, upon reviewing your pull requests,
we might request an issue to be filed to facilitate discussion on broader design considerations.

Visit our [Issues page on GitHub](https://github.com/sysprog21/lab0-c/issues) to search and submit.

## Coding Convention
Expand All @@ -21,6 +39,10 @@ However, participation requires adherence to fundamental ground rules:
While there is some flexibility in basic style, it is crucial to stick to the current coding standards.
Complex algorithmic constructs without proper comments will not be accepted.
* External pull requests should include thorough documentation in the pull request comments for consideration.
* When composing documentation, code comments, and other materials in English,
please adhere to the American English (`en_US`) dialect.
This variant should be considered the standard for all documentation efforts.
For instance, opt for "initialize" over "initialise" and "color" rather than "colour".

Software requirement: [clang-format](https://clang.llvm.org/docs/ClangFormat.html) version 12 or later.

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ Some distros like Arch Linux won't install `aspell-en` with `aspell`, and you mu
$ sudo pacman -S aspell-en
```

Note: [Cppcheck](http://cppcheck.sourceforge.net/) version must be at least 1.90, otherwise
Note: [Cppcheck](https://cppcheck.sourceforge.net/) version must be at least 1.90, otherwise
it might report errors with false positives. You can get its version by executing `$ cppcheck --version`.
Check [Developer Info](http://cppcheck.sourceforge.net/devinfo/) for building Cppcheck from source.
Check [Developer Info](https://cppcheck.sourceforge.net/devinfo/) for building Cppcheck from source.

### Integrate `clang-format` to `vim`
If you want to run `clang-format` automatically after saving with vim,
Expand Down
39 changes: 29 additions & 10 deletions harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <setjmp.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -58,6 +59,12 @@ static jmp_buf env;
static volatile sig_atomic_t jmp_ready = false;
static bool time_limited = false;

/* For test_malloc and test_calloc */
typedef enum {
TEST_MALLOC,
TEST_CALLOC,
} alloc_t;

/* Internal functions */

/* Should this allocation fail? */
Expand Down Expand Up @@ -115,17 +122,23 @@ static size_t *find_footer(block_element_t *b)
return p;
}

/* Implementation of application functions */

void *test_malloc(size_t size)
static void *alloc(alloc_t alloc_type, size_t size)
{
if (noallocate_mode) {
report_event(MSG_FATAL, "Calls to malloc disallowed");
char *msg_alloc_forbidden[] = {
"Calls to malloc are disallowed",
"Calls to calloc are disallowed",
};
report_event(MSG_FATAL, "%s", msg_alloc_forbidden[alloc_type]);
return NULL;
}

if (fail_allocation()) {
report_event(MSG_WARN, "Malloc returning NULL");
char *msg_alloc_failure[] = {
"Malloc returning NULL",
"Calloc returning NULL",
};
report_event(MSG_WARN, "%s", msg_alloc_failure[alloc_type]);
return NULL;
}

Expand All @@ -142,7 +155,7 @@ void *test_malloc(size_t size)
new_block->payload_size = size;
*find_footer(new_block) = MAGICFOOTER;
void *p = (void *) &new_block->payload;
memset(p, FILLCHAR, size);
memset(p, !alloc_type * FILLCHAR, size);
// cppcheck-suppress nullPointerRedundantCheck
new_block->next = allocated;
// cppcheck-suppress nullPointerRedundantCheck
Expand All @@ -156,16 +169,22 @@ void *test_malloc(size_t size)
return p;
}

/* Implementation of application functions */

void *test_malloc(size_t size)
{
return alloc(TEST_MALLOC, size);
}

// cppcheck-suppress unusedFunction
void *test_calloc(size_t nelem, size_t elsize)
{
/* Reference: Malloc tutorial
* https://danluu.com/malloc-tutorial/
*/
size_t size = nelem * elsize; // TODO: check for overflow
void *ptr = test_malloc(size);
memset(ptr, 0, size);
return ptr;
if (!nelem || !elsize || nelem > SIZE_MAX / elsize)
return NULL;
return alloc(TEST_CALLOC, nelem * elsize);
}

void test_free(void *p)
Expand Down
1 change: 1 addition & 0 deletions harness.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void trigger_exception(char *msg);

/* Tested program use our versions of malloc and free */
#define malloc test_malloc
#define calloc test_calloc
#define free test_free

/* Use undef to avoid strdup redefined error */
Expand Down
62 changes: 53 additions & 9 deletions qtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,11 @@ static void fill_rand_string(char *buf, size_t buf_size)
while (len < MIN_RANDSTR_LEN)
len = rand() % buf_size;

randombytes((uint8_t *) buf, len);
uint64_t randstr_buf_64[MAX_RANDSTR_LEN] = {0};
randombytes((uint8_t *) randstr_buf_64, len * sizeof(uint64_t));
for (size_t n = 0; n < len; n++)
buf[n] = charset[buf[n] % (sizeof(charset) - 1)];
buf[n] = charset[randstr_buf_64[n] % (sizeof(charset) - 1)];

buf[len] = '\0';
}

Expand Down Expand Up @@ -540,11 +542,6 @@ static bool do_size(int argc, char *argv[])

int reps = 1;
bool ok = true;
if (argc != 1 && argc != 2) {
report(1, "%s needs 0-1 arguments", argv[0]);
return false;
}

if (argc == 2) {
if (!get_int(argv[1], &reps))
report(1, "Invalid number of calls to size '%s'", argv[2]);
Expand Down Expand Up @@ -598,6 +595,23 @@ bool do_sort(int argc, char *argv[])
error_check();

set_noallocate_mode(true);

/* If the number of elements is too large, it may take a long time to check the
* stability of the sort. So, MAX_NODES is used to limit the number of elements
* to check the stability of the sort. */
#define MAX_NODES 100000
struct list_head *nodes[MAX_NODES];
unsigned no = 0;
if (current && current->size && current->size <= MAX_NODES) {
element_t *entry;
list_for_each_entry (entry, current->q, list)
nodes[no++] = &entry->list;
} else if (current && current->size > MAX_NODES)
report(1,
"Warning: Skip checking the stability of the sort because the "
"number of elements %d is too large, exceeds the limit %d.",
current->size, MAX_NODES);

if (current && exception_setup(true))
q_sort(current->q, descend);
exception_cancel();
Expand All @@ -622,8 +636,32 @@ bool do_sort(int argc, char *argv[])
ok = false;
break;
}
/* Ensure the stability of the sort */
if (current->size <= MAX_NODES &&
!strcmp(item->value, next_item->value)) {
bool unstable = false;
for (unsigned i = 0; i < MAX_NODES; i++) {
if (nodes[i] == cur_l->next) {
unstable = true;
break;
}
if (nodes[i] == cur_l) {
break;
}
}
if (unstable) {
report(
1,
"ERROR: Not stable sort. The duplicate strings \"%s\" "
"are not in the same order.",
item->value);
ok = false;
break;
}
}
}
}
#undef MAX_NODES

q_show(3);
return ok && !error_check();
Expand Down Expand Up @@ -878,17 +916,23 @@ static bool do_merge(int argc, char *argv[])
static bool is_circular()
{
struct list_head *cur = current->q->next;
struct list_head *fast = (cur) ? cur->next : NULL;
while (cur != current->q) {
if (!cur)
if (!cur || !fast || !fast->next)
return false;
if (cur == fast)
return false;
cur = cur->next;
fast = fast->next->next;
}

cur = current->q->prev;
fast = (cur) ? cur->prev : NULL;
while (cur != current->q) {
if (!cur)
if (!cur || !fast || !fast->prev)
return false;
cur = cur->prev;
fast = fast->prev->prev;
}
return true;
}
Expand Down
4 changes: 3 additions & 1 deletion queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ bool q_delete_mid(struct list_head *head);
* Reference:
* https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
*
* Return: true for success, false if list is NULL.
* Return: true for success, false if list is NULL or empty.
*/
bool q_delete_dup(struct list_head *head);

Expand Down Expand Up @@ -207,6 +207,7 @@ void q_sort(struct list_head *head, bool descend);
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
* Memory allocated to removed nodes must be freed.
*
* Reference:
* https://leetcode.com/problems/remove-nodes-from-linked-list/
Expand All @@ -222,6 +223,7 @@ int q_ascend(struct list_head *head);
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
* Memory allocated to removed nodes must be freed.
*
* Reference:
* https://leetcode.com/problems/remove-nodes-from-linked-list/
Expand Down
30 changes: 14 additions & 16 deletions random.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static ssize_t getrandom(void *buf, size_t buflen, unsigned int flags)
}
#endif

static int randombytes_linux_randombytes_getrandom(void *buf, size_t n)
static int linux_getrandom(void *buf, size_t n)
{
size_t offset = 0;
int ret;
Expand All @@ -114,12 +114,12 @@ static int randombytes_linux_randombytes_getrandom(void *buf, size_t n)
#if defined(__linux__) && !defined(SYS_getrandom)

#if defined(__linux__)
static inline int randombytes_linux_read_entropy_ioctl(int device, int *entropy)
static inline int linux_read_entropy_ioctl(int device, int *entropy)
{
return ioctl(device, RNDGETENTCNT, entropy);
}

static int randombytes_linux_read_entropy_proc(FILE *stream, int *entropy)
static int linux_read_entropy_proc(FILE *stream, int *entropy)
{
int retcode;
do {
Expand All @@ -131,7 +131,7 @@ static int randombytes_linux_read_entropy_proc(FILE *stream, int *entropy)
return 0;
}

static int randombytes_linux_wait_for_entropy(int device)
static int linux_wait_for_entropy(int device)
{
/* We will block on /dev/random, because any increase in the OS' entropy
* level will unblock the request. I use poll here (as does libsodium),
Expand All @@ -144,7 +144,7 @@ static int randombytes_linux_wait_for_entropy(int device)
int entropy = 0;

/* If the device has enough entropy already, we will want to return early */
int retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
int retcode = linux_read_entropy_ioctl(device, &entropy);
if (retcode != 0 && (errno == ENOTTY || errno == ENOSYS)) {
/* The ioctl call on /dev/urandom has failed due to a
* - ENOTTY (unsupported action), or
Expand Down Expand Up @@ -184,11 +184,9 @@ static int randombytes_linux_wait_for_entropy(int device)
continue;
} else if (retcode == 1) {
if (strategy == IOCTL) {
retcode =
randombytes_linux_read_entropy_ioctl(device, &entropy);
retcode = linux_read_entropy_ioctl(device, &entropy);
} else if (strategy == PROC) {
retcode =
randombytes_linux_read_entropy_proc(proc_file, &entropy);
retcode = linux_read_entropy_proc(proc_file, &entropy);
} else {
return -1; /* Unreachable */
}
Expand Down Expand Up @@ -220,7 +218,7 @@ static int randombytes_linux_wait_for_entropy(int device)
}
#endif /* defined(__linux__) */

static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
static int linux_urandom(void *buf, size_t n)
{
int fd;
do {
Expand All @@ -229,7 +227,7 @@ static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
if (fd == -1)
return -1;
#if defined(__linux__)
if (randombytes_linux_wait_for_entropy(fd) == -1)
if (linux_wait_for_entropy(fd) == -1)
return -1;
#endif

Expand Down Expand Up @@ -259,7 +257,7 @@ static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
#include <CommonCrypto/CommonRandom.h>
#endif
#endif
static int randombytes_bsd_randombytes(void *buf, size_t n)
static int bsd_randombytes(void *buf, size_t n)
{
#if defined(MAC_OS_X_VERSION_10_15) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
Expand All @@ -279,16 +277,16 @@ int randombytes(uint8_t *buf, size_t n)
#if defined(__linux__) || defined(__GNU__)
#if defined(USE_GLIBC)
/* Use getrandom system call */
return randombytes_linux_randombytes_getrandom(buf, n);
return linux_getrandom(buf, n);
#elif defined(SYS_getrandom)
/* Use getrandom system call */
return randombytes_linux_randombytes_getrandom(buf, n);
return linux_getrandom(buf, n);
#else
/* When we have enough entropy, we can read from /dev/urandom */
return randombytes_linux_randombytes_urandom(buf, n);
return linux_urandom(buf, n);
#endif
#elif defined(BSD)
return randombytes_bsd_randombytes(buf, n);
return bsd_randombytes(buf, n);
#else
#error "randombytes(...) is not supported on this platform"
#endif
Expand Down
2 changes: 1 addition & 1 deletion report.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void report_event(message_t msg, char *fmt, ...)
"ERROR",
"FATAL ERROR",
};
char *msg_name = msg_name_text[2];
const char *msg_name = msg_name_text[2];
if (msg < N_MSG)
msg_name = msg_name_text[msg];
int level = N_MSG - msg - 1;
Expand Down
3 changes: 3 additions & 0 deletions scripts/aspell-pws
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,6 @@ adjtime
perf
uring
Shannon
http
https
tcp
2 changes: 1 addition & 1 deletion scripts/checksums
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
444bab14cb8ad4c949f61b3c10a22a3ed2401425 queue.h
db6784ff3917888db4d1dceaa0570d99ed40e762 queue.h
3337dbccc33eceedda78e36cc118d5a374838ec7 list.h
Loading

0 comments on commit 3db3bd0

Please sign in to comment.