- Add missing comments;
- Reimplement a more safer dirname; - Implement a simple and safe tokenize function;
This commit is contained in:
@@ -43,4 +43,4 @@ typedef struct termios {
|
||||
#define IEXTEN 0x00000400 ///< Enables implementation-defined input processing.
|
||||
|
||||
/// @brief Mask for extracting control values.
|
||||
#define CTRL(x) (x & 037)
|
||||
#define CTRL(x) ((x) & 037)
|
||||
|
||||
+7
-14
@@ -5,20 +5,13 @@
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
// TODO: doxygen comment.
|
||||
/// @brief
|
||||
/// @param out
|
||||
/// @param cur
|
||||
/// @param sep
|
||||
/// @param max
|
||||
/// @result
|
||||
int parse_path(char *out, char **cur, char sep, size_t max);
|
||||
|
||||
// TODO: doxygen comment.
|
||||
/// @brief
|
||||
/// @param path
|
||||
/// @result
|
||||
char *dirname(const char *path);
|
||||
/// @brief Extracts the parent directory of the given path and saves it inside
|
||||
/// the given buffer, e.g., from "/home/user/test.txt" it extracts "/home/user".
|
||||
/// @param path the path we are parsing.
|
||||
/// @param buffer the buffer where we save the directory name.
|
||||
/// @param buflen the length of the buffer.
|
||||
/// @return 1 if succesfull, or 0 if the buffer cannot contain the path.
|
||||
int dirname(const char *path, char *buffer, size_t buflen);
|
||||
|
||||
// TODO: doxygen comment.
|
||||
/// @brief
|
||||
|
||||
@@ -170,6 +170,15 @@ char *strtok(char *str, const char *delim);
|
||||
/// should be NULL, and saveptr should be unchanged since the previous call.
|
||||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
|
||||
/// @brief Parses the string using the separator, and at each call it saves the
|
||||
/// parsed token in buffer. The pointer `string` will be modified.
|
||||
/// @param string cursor used to parse the string, it will be modified.
|
||||
/// @param separator the separator we are using.
|
||||
/// @param buffer the buffer where we save the parsed token.
|
||||
/// @param buflen the length of the buffer.
|
||||
/// @return 1 if we still have things to parse, 0 if we finished parsing.
|
||||
int tokenize(char **string, char separator, char *buffer, ssize_t buflen);
|
||||
|
||||
/// @brief Copies the values of num bytes from the location pointed by source
|
||||
/// to the memory block pointed by destination.
|
||||
/// @param dst Pointer to the destination array where the content is to be
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
/// @return the position of the first zero bit.
|
||||
static inline int find_first_zero(unsigned long value)
|
||||
{
|
||||
for (int i = 0; i < 32; ++i)
|
||||
if (!bit_check(value, i))
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
if (!bit_check(value, i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,8 +41,10 @@ static inline int find_first_zero(unsigned long value)
|
||||
/// @return the position of the first non-zero bit.
|
||||
static inline int find_first_non_zero(unsigned long value)
|
||||
{
|
||||
for (int i = 0; i < 32; ++i)
|
||||
if (bit_check(value, i))
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
if (bit_check(value, i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -74,8 +74,9 @@ static inline int list_head_empty(const list_head *head)
|
||||
static inline unsigned list_head_size(const list_head *head)
|
||||
{
|
||||
unsigned size = 0;
|
||||
if (!list_head_empty(head))
|
||||
if (!list_head_empty(head)) {
|
||||
list_for_each_decl(it, head) size += 1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -191,7 +192,8 @@ static inline void list_head_swap(list_head *entry1, list_head *entry2)
|
||||
{
|
||||
list_head *pos = entry2->prev;
|
||||
list_head_replace(entry1, entry2);
|
||||
if (pos == entry1)
|
||||
if (pos == entry1) {
|
||||
pos = entry2;
|
||||
}
|
||||
list_head_insert_after(entry1, pos);
|
||||
}
|
||||
|
||||
@@ -14,35 +14,34 @@ typedef int (*list_head_compare)(const list_head *, const list_head *);
|
||||
/// @brief -
|
||||
/// @param list
|
||||
/// @param compare
|
||||
void list_head_sort(list_head *list, list_head_compare compare)
|
||||
static inline void list_head_sort(list_head *list, list_head_compare compare)
|
||||
{
|
||||
list_head *current = NULL, *index = NULL, *next = NULL;
|
||||
// Check whether list is empty
|
||||
if (list_head_empty(list)) {
|
||||
return;
|
||||
}
|
||||
// Keeps track if we need to restart the outer loop.
|
||||
int restart = 0;
|
||||
// Current will point to head
|
||||
for (current = list->next; current->next != list;) {
|
||||
// Save pointer to next.
|
||||
next = current->next;
|
||||
// Reset restart flag.
|
||||
restart = 0;
|
||||
// Index will point to node next to current
|
||||
for (index = current->next; index != list; index = index->next) {
|
||||
// If current's data is greater than index's data, swap the data of
|
||||
// current and index
|
||||
if (compare(current, index)) {
|
||||
list_head_swap(index, current);
|
||||
restart = 1;
|
||||
if (!list_head_empty(list)) {
|
||||
// Keeps track if we need to restart the outer loop.
|
||||
int restart = 0;
|
||||
// Current will point to head
|
||||
for (current = list->next; current->next != list;) {
|
||||
// Save pointer to next.
|
||||
next = current->next;
|
||||
// Reset restart flag.
|
||||
restart = 0;
|
||||
// Index will point to node next to current
|
||||
for (index = current->next; index != list; index = index->next) {
|
||||
// If current's data is greater than index's data, swap the data of
|
||||
// current and index
|
||||
if (compare(current, index)) {
|
||||
list_head_swap(index, current);
|
||||
restart = 1;
|
||||
}
|
||||
}
|
||||
// Check if we need to restart.
|
||||
if (restart) {
|
||||
current = list->next;
|
||||
} else {
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
// Check if we need to restart.
|
||||
if (restart)
|
||||
current = list->next;
|
||||
else
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -6,9 +6,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys/ipc.h"
|
||||
|
||||
#include "sys/types.h"
|
||||
#include "stddef.h"
|
||||
#include "sys/types.h"
|
||||
#include "time.h"
|
||||
|
||||
/// The maximum size for a message text.
|
||||
|
||||
+1
-2
@@ -6,9 +6,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys/types.h"
|
||||
#include "sys/ipc.h"
|
||||
|
||||
#include "stddef.h"
|
||||
#include "sys/ipc.h"
|
||||
#include "time.h"
|
||||
|
||||
#define SEM_UNDO 0x1000 ///< Undo the operation on exit.
|
||||
|
||||
+1
-2
@@ -5,10 +5,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sys/ipc.h"
|
||||
|
||||
#include "sys/types.h"
|
||||
#include "stddef.h"
|
||||
#include "sys/ipc.h"
|
||||
#include "time.h"
|
||||
|
||||
/// Data type for storing the number of attaches.
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys/types.h"
|
||||
#include "sys/dirent.h"
|
||||
#include "stddef.h"
|
||||
#include "sys/dirent.h"
|
||||
|
||||
#define STDIN_FILENO 0 ///< Standard input.
|
||||
#define STDOUT_FILENO 1 ///< Standard output.
|
||||
|
||||
+25
-50
@@ -9,63 +9,38 @@
|
||||
#include "libgen.h"
|
||||
#include "string.h"
|
||||
#include "limits.h"
|
||||
#include "io/debug.h"
|
||||
|
||||
int parse_path(char *out, char **cur, char sep, size_t max)
|
||||
int dirname(const char *path, char *buffer, size_t buflen)
|
||||
{
|
||||
if (**cur == '\0') {
|
||||
if ((path == NULL) || (buffer == NULL) || (buflen == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out++ = **cur;
|
||||
++*cur;
|
||||
--max;
|
||||
|
||||
while ((max > 0) && (**cur != '\0') && (**cur != sep)) {
|
||||
*out++ = **cur;
|
||||
++*cur;
|
||||
--max;
|
||||
// Search for the last slash.
|
||||
const char *last_slash = NULL;
|
||||
for (const char *it = path; *it; it++) {
|
||||
if ((*it) == '/') {
|
||||
last_slash = it;
|
||||
}
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *dirname(const char *path)
|
||||
{
|
||||
static char s[PATH_MAX];
|
||||
|
||||
static char dot[2] = ".";
|
||||
|
||||
// Check the input path.
|
||||
if (path == NULL) {
|
||||
return dot;
|
||||
}
|
||||
|
||||
// Copy the path to the support string.
|
||||
strcpy(s, path);
|
||||
|
||||
// Get the last occurrence of '/'.
|
||||
char *last_slash = strrchr(s, '/');
|
||||
|
||||
if (last_slash == s) {
|
||||
// If the slash is acutally the first character of the string, move the
|
||||
// pointer to the last slash after it.
|
||||
++last_slash;
|
||||
} else if ((last_slash != NULL) && (last_slash[1] == '\0')) {
|
||||
// If the slash is the last character, we need to search before it.
|
||||
last_slash = memchr(s, '/', last_slash - s);
|
||||
}
|
||||
|
||||
if (last_slash != NULL) {
|
||||
// If we have found it, close the string.
|
||||
last_slash[0] = '\0';
|
||||
// If we were able to find a slash, and the slash is not in the first
|
||||
// position, copy the substring.
|
||||
if (last_slash) {
|
||||
// Get the length of the substring, if the last slash is at the beginning,
|
||||
// add 1.
|
||||
size_t dirlen = last_slash - path + (last_slash == path);
|
||||
// Check if the path will fit inside the buffer.
|
||||
if (dirlen >= buflen) {
|
||||
return 0;
|
||||
}
|
||||
// Copy the substring.
|
||||
strncpy(buffer, path, dirlen);
|
||||
// Close the buffer.
|
||||
buffer[dirlen] = 0;
|
||||
} else {
|
||||
// Otherwise, return '.'.
|
||||
return dot;
|
||||
strcpy(buffer, ".");
|
||||
}
|
||||
|
||||
return s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *basename(const char *path)
|
||||
|
||||
@@ -212,6 +212,28 @@ char *strpbrk(const char *string, const char *control)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int tokenize(char **path, char separator, char *buffer, ssize_t buflen)
|
||||
{
|
||||
// If we reached the end of the parsed string, stop.
|
||||
if (**path == '\0') {
|
||||
return 0;
|
||||
}
|
||||
// If the first character is the separator, skip it/
|
||||
if (**path == separator) {
|
||||
++(*path);
|
||||
}
|
||||
// Keep copying character until we either reach 1) the end of the buffer, 2) a
|
||||
// separator, or 3) the end of the string we are parsing.
|
||||
while ((buflen > 0) && (**path != '\0') && (**path != separator)) {
|
||||
*buffer++ = **path;
|
||||
++(*path);
|
||||
--buflen;
|
||||
}
|
||||
// Close the buffer.
|
||||
*buffer = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n)
|
||||
{
|
||||
void *ret = dst;
|
||||
|
||||
Reference in New Issue
Block a user