commit 6fc620e8f4f07acd666cdd58e7528a2173047837 Author: thrieg Date: Thu Dec 11 06:18:16 2025 +0100 skeletton untested project diff --git a/includes/ft_strace.h b/includes/ft_strace.h new file mode 100644 index 0000000..587b694 --- /dev/null +++ b/includes/ft_strace.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strace.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/12/11 04:06:00 by thrieg #+# #+# */ +/* Updated: 2025/12/11 05:54:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_STRACE_H +#define FT_STRACE_H + +#include +#include +#include +#include +#include +#include "../libft/libft.h" + +//returns 64 for x84_64, or 32 for 32 bits, -1 for open/read error, -2 for unrecognised file type +ssize_t binary_type(char *path_to_binary); + +typedef struct s_syscall_desc { + const char *name; + unsigned char argc; +} t_syscall_desc; + +#endif \ No newline at end of file diff --git a/includes/syscalls_x64.h b/includes/syscalls_x64.h new file mode 100644 index 0000000..933d91b --- /dev/null +++ b/includes/syscalls_x64.h @@ -0,0 +1,353 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* syscalls_x64.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/12/11 05:55:53 by thrieg #+# #+# */ +/* Updated: 2025/12/11 05:58:18 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_strace.h" + +/* Auto-generated from https://x64.syscall.sh/ */ +const t_syscall_desc g_syscalls_64[] = { + [ 0] = { "read", 3 }, + [ 1] = { "write", 3 }, + [ 2] = { "open", 3 }, + [ 3] = { "close", 1 }, + [ 4] = { "stat", 2 }, + [ 5] = { "fstat", 2 }, + [ 6] = { "lstat", 2 }, + [ 7] = { "poll", 3 }, + [ 8] = { "lseek", 3 }, + [ 9] = { "mmap", 6 }, + [ 10] = { "mprotect", 3 }, + [ 11] = { "munmap", 2 }, + [ 12] = { "brk", 1 }, + [ 13] = { "rt_sigaction", 4 }, + [ 14] = { "rt_sigprocmask", 4 }, + [ 15] = { "rt_sigreturn", 6 }, + [ 16] = { "ioctl", 3 }, + [ 17] = { "pread64", 4 }, + [ 18] = { "pwrite64", 4 }, + [ 19] = { "readv", 3 }, + [ 20] = { "writev", 3 }, + [ 21] = { "access", 2 }, + [ 22] = { "pipe", 1 }, + [ 23] = { "select", 5 }, + [ 24] = { "sched_yield", 0 }, + [ 25] = { "mremap", 5 }, + [ 26] = { "msync", 3 }, + [ 27] = { "mincore", 3 }, + [ 28] = { "madvise", 3 }, + [ 29] = { "shmget", 3 }, + [ 30] = { "shmat", 3 }, + [ 31] = { "shmctl", 3 }, + [ 32] = { "dup", 1 }, + [ 33] = { "dup2", 2 }, + [ 34] = { "pause", 0 }, + [ 35] = { "nanosleep", 2 }, + [ 36] = { "getitimer", 2 }, + [ 37] = { "alarm", 1 }, + [ 38] = { "setitimer", 3 }, + [ 39] = { "getpid", 0 }, + [ 40] = { "sendfile", 4 }, + [ 41] = { "socket", 3 }, + [ 42] = { "connect", 3 }, + [ 43] = { "accept", 3 }, + [ 44] = { "sendto", 6 }, + [ 45] = { "recvfrom", 6 }, + [ 46] = { "sendmsg", 3 }, + [ 47] = { "recvmsg", 3 }, + [ 48] = { "shutdown", 2 }, + [ 49] = { "bind", 3 }, + [ 50] = { "listen", 2 }, + [ 51] = { "getsockname", 3 }, + [ 52] = { "getpeername", 3 }, + [ 53] = { "socketpair", 4 }, + [ 54] = { "setsockopt", 5 }, + [ 55] = { "getsockopt", 5 }, + [ 56] = { "clone", 5 }, + [ 57] = { "fork", 0 }, + [ 58] = { "vfork", 0 }, + [ 59] = { "execve", 3 }, + [ 60] = { "exit", 1 }, + [ 61] = { "wait4", 4 }, + [ 62] = { "kill", 2 }, + [ 63] = { "uname", 1 }, + [ 64] = { "semget", 3 }, + [ 65] = { "semop", 3 }, + [ 66] = { "semctl", 4 }, + [ 67] = { "shmdt", 1 }, + [ 68] = { "msgget", 2 }, + [ 69] = { "msgsnd", 4 }, + [ 70] = { "msgrcv", 5 }, + [ 71] = { "msgctl", 3 }, + [ 72] = { "fcntl", 3 }, + [ 73] = { "flock", 2 }, + [ 74] = { "fsync", 1 }, + [ 75] = { "fdatasync", 1 }, + [ 76] = { "truncate", 2 }, + [ 77] = { "ftruncate", 2 }, + [ 78] = { "getdents", 3 }, + [ 79] = { "getcwd", 2 }, + [ 80] = { "chdir", 1 }, + [ 81] = { "fchdir", 1 }, + [ 82] = { "rename", 2 }, + [ 83] = { "mkdir", 2 }, + [ 84] = { "rmdir", 1 }, + [ 85] = { "creat", 2 }, + [ 86] = { "link", 2 }, + [ 87] = { "unlink", 1 }, + [ 88] = { "symlink", 2 }, + [ 89] = { "readlink", 3 }, + [ 90] = { "chmod", 2 }, + [ 91] = { "fchmod", 2 }, + [ 92] = { "chown", 3 }, + [ 93] = { "fchown", 3 }, + [ 94] = { "lchown", 3 }, + [ 95] = { "umask", 1 }, + [ 96] = { "gettimeofday", 2 }, + [ 97] = { "getrlimit", 2 }, + [ 98] = { "getrusage", 2 }, + [ 99] = { "sysinfo", 1 }, + [100] = { "times", 1 }, + [101] = { "ptrace", 4 }, + [102] = { "getuid", 0 }, + [103] = { "syslog", 3 }, + [104] = { "getgid", 0 }, + [105] = { "setuid", 1 }, + [106] = { "setgid", 1 }, + [107] = { "geteuid", 0 }, + [108] = { "getegid", 0 }, + [109] = { "setpgid", 2 }, + [110] = { "getppid", 0 }, + [111] = { "getpgrp", 0 }, + [112] = { "setsid", 0 }, + [113] = { "setreuid", 2 }, + [114] = { "setregid", 2 }, + [115] = { "getgroups", 2 }, + [116] = { "setgroups", 2 }, + [117] = { "setresuid", 3 }, + [118] = { "getresuid", 3 }, + [119] = { "setresgid", 3 }, + [120] = { "getresgid", 3 }, + [121] = { "getpgid", 1 }, + [122] = { "setfsuid", 1 }, + [123] = { "setfsgid", 1 }, + [124] = { "getsid", 1 }, + [125] = { "capget", 2 }, + [126] = { "capset", 2 }, + [127] = { "rt_sigpending", 2 }, + [128] = { "rt_sigtimedwait", 4 }, + [129] = { "rt_sigqueueinfo", 3 }, + [130] = { "rt_sigsuspend", 2 }, + [131] = { "sigaltstack", 2 }, + [132] = { "utime", 2 }, + [133] = { "mknod", 3 }, + [134] = { "uselib", 1 }, + [135] = { "personality", 1 }, + [136] = { "ustat", 2 }, + [137] = { "statfs", 2 }, + [138] = { "fstatfs", 2 }, + [139] = { "sysfs", 3 }, + [140] = { "getpriority", 2 }, + [141] = { "setpriority", 3 }, + [142] = { "sched_setparam", 2 }, + [143] = { "sched_getparam", 2 }, + [144] = { "sched_setscheduler", 3 }, + [145] = { "sched_getscheduler", 1 }, + [146] = { "sched_get_priority_max", 1 }, + [147] = { "sched_get_priority_min", 1 }, + [148] = { "sched_rr_get_interval", 2 }, + [149] = { "mlock", 2 }, + [150] = { "munlock", 2 }, + [151] = { "mlockall", 1 }, + [152] = { "munlockall", 0 }, + [153] = { "vhangup", 0 }, + [154] = { "modify_ldt", 6 }, + [155] = { "pivot_root", 2 }, + [156] = { "_sysctl", 6 }, + [157] = { "prctl", 5 }, + [158] = { "arch_prctl", 6 }, + [159] = { "adjtimex", 1 }, + [160] = { "setrlimit", 2 }, + [161] = { "chroot", 1 }, + [162] = { "sync", 0 }, + [163] = { "acct", 1 }, + [164] = { "settimeofday", 2 }, + [165] = { "mount", 5 }, + [166] = { "umount2", 6 }, + [167] = { "swapon", 2 }, + [168] = { "swapoff", 1 }, + [169] = { "reboot", 4 }, + [170] = { "sethostname", 2 }, + [171] = { "setdomainname", 2 }, + [172] = { "iopl", 6 }, + [173] = { "ioperm", 3 }, + [174] = { "create_module", 6 }, + [175] = { "init_module", 3 }, + [176] = { "delete_module", 2 }, + [177] = { "get_kernel_syms", 6 }, + [178] = { "query_module", 6 }, + [179] = { "quotactl", 4 }, + [180] = { "nfsservctl", 6 }, + [181] = { "getpmsg", 6 }, + [182] = { "putpmsg", 6 }, + [183] = { "afs_syscall", 6 }, + [184] = { "tuxcall", 6 }, + [185] = { "security", 6 }, + [186] = { "gettid", 0 }, + [187] = { "readahead", 3 }, + [188] = { "setxattr", 5 }, + [189] = { "lsetxattr", 5 }, + [190] = { "fsetxattr", 5 }, + [191] = { "getxattr", 4 }, + [192] = { "lgetxattr", 4 }, + [193] = { "fgetxattr", 4 }, + [194] = { "listxattr", 3 }, + [195] = { "llistxattr", 3 }, + [196] = { "flistxattr", 3 }, + [197] = { "removexattr", 2 }, + [198] = { "lremovexattr", 2 }, + [199] = { "fremovexattr", 2 }, + [200] = { "tkill", 2 }, + [201] = { "time", 1 }, + [202] = { "futex", 6 }, + [203] = { "sched_setaffinity", 3 }, + [204] = { "sched_getaffinity", 3 }, + [205] = { "set_thread_area", 6 }, + [206] = { "io_setup", 2 }, + [207] = { "io_destroy", 1 }, + [208] = { "io_getevents", 5 }, + [209] = { "io_submit", 3 }, + [210] = { "io_cancel", 3 }, + [211] = { "get_thread_area", 6 }, + [212] = { "lookup_dcookie", 3 }, + [213] = { "epoll_create", 1 }, + [214] = { "epoll_ctl_old", 6 }, + [215] = { "epoll_wait_old", 6 }, + [216] = { "remap_file_pages", 5 }, + [217] = { "getdents64", 3 }, + [218] = { "set_tid_address", 1 }, + [219] = { "restart_syscall", 0 }, + [220] = { "semtimedop", 4 }, + [221] = { "fadvise64", 4 }, + [222] = { "timer_create", 3 }, + [223] = { "timer_settime", 4 }, + [224] = { "timer_gettime", 2 }, + [225] = { "timer_getoverrun", 1 }, + [226] = { "timer_delete", 1 }, + [227] = { "clock_settime", 2 }, + [228] = { "clock_gettime", 2 }, + [229] = { "clock_getres", 2 }, + [230] = { "clock_nanosleep", 4 }, + [231] = { "exit_group", 1 }, + [232] = { "epoll_wait", 4 }, + [233] = { "epoll_ctl", 4 }, + [234] = { "tgkill", 3 }, + [235] = { "utimes", 2 }, + [236] = { "vserver", 6 }, + [237] = { "mbind", 6 }, + [238] = { "set_mempolicy", 3 }, + [239] = { "get_mempolicy", 5 }, + [240] = { "mq_open", 4 }, + [241] = { "mq_unlink", 1 }, + [242] = { "mq_timedsend", 5 }, + [243] = { "mq_timedreceive", 5 }, + [244] = { "mq_notify", 2 }, + [245] = { "mq_getsetattr", 3 }, + [246] = { "kexec_load", 4 }, + [247] = { "waitid", 5 }, + [248] = { "add_key", 5 }, + [249] = { "request_key", 4 }, + [250] = { "keyctl", 5 }, + [251] = { "ioprio_set", 3 }, + [252] = { "ioprio_get", 2 }, + [253] = { "inotify_init", 0 }, + [254] = { "inotify_add_watch", 3 }, + [255] = { "inotify_rm_watch", 2 }, + [256] = { "migrate_pages", 4 }, + [257] = { "openat", 4 }, + [258] = { "mkdirat", 3 }, + [259] = { "mknodat", 4 }, + [260] = { "fchownat", 5 }, + [261] = { "futimesat", 3 }, + [262] = { "newfstatat", 4 }, + [263] = { "unlinkat", 3 }, + [264] = { "renameat", 4 }, + [265] = { "linkat", 5 }, + [266] = { "symlinkat", 3 }, + [267] = { "readlinkat", 4 }, + [268] = { "fchmodat", 3 }, + [269] = { "faccessat", 3 }, + [270] = { "pselect6", 6 }, + [271] = { "ppoll", 5 }, + [272] = { "unshare", 1 }, + [273] = { "set_robust_list", 2 }, + [274] = { "get_robust_list", 3 }, + [275] = { "splice", 6 }, + [276] = { "tee", 4 }, + [277] = { "sync_file_range", 4 }, + [278] = { "vmsplice", 4 }, + [279] = { "move_pages", 6 }, + [280] = { "utimensat", 4 }, + [281] = { "epoll_pwait", 6 }, + [282] = { "signalfd", 3 }, + [283] = { "timerfd_create", 2 }, + [284] = { "eventfd", 1 }, + [285] = { "fallocate", 4 }, + [286] = { "timerfd_settime", 4 }, + [287] = { "timerfd_gettime", 2 }, + [288] = { "accept4", 4 }, + [289] = { "signalfd4", 4 }, + [290] = { "eventfd2", 2 }, + [291] = { "epoll_create1", 1 }, + [292] = { "dup3", 3 }, + [293] = { "pipe2", 2 }, + [294] = { "inotify_init1", 1 }, + [295] = { "preadv", 5 }, + [296] = { "pwritev", 5 }, + [297] = { "rt_tgsigqueueinfo", 4 }, + [298] = { "perf_event_open", 5 }, + [299] = { "recvmmsg", 5 }, + [300] = { "fanotify_init", 2 }, + [301] = { "fanotify_mark", 5 }, + [302] = { "prlimit64", 4 }, + [303] = { "name_to_handle_at", 5 }, + [304] = { "open_by_handle_at", 3 }, + [305] = { "clock_adjtime", 2 }, + [306] = { "syncfs", 1 }, + [307] = { "sendmmsg", 4 }, + [308] = { "setns", 2 }, + [309] = { "getcpu", 3 }, + [310] = { "process_vm_readv", 6 }, + [311] = { "process_vm_writev", 6 }, + [312] = { "kcmp", 5 }, + [313] = { "finit_module", 3 }, + [314] = { "sched_setattr", 3 }, + [315] = { "sched_getattr", 4 }, + [316] = { "renameat2", 5 }, + [317] = { "seccomp", 3 }, + [318] = { "getrandom", 3 }, + [319] = { "memfd_create", 2 }, + [320] = { "kexec_file_load", 5 }, + [321] = { "bpf", 3 }, + [322] = { "execveat", 5 }, + [323] = { "userfaultfd", 1 }, + [324] = { "membarrier", 2 }, + [325] = { "mlock2", 3 }, + [326] = { "copy_file_range", 6 }, + [327] = { "preadv2", 6 }, + [328] = { "pwritev2", 6 }, + [329] = { "pkey_mprotect", 4 }, + [330] = { "pkey_alloc", 2 }, + [331] = { "pkey_free", 1 }, + [332] = { "statx", 5 }, +}; + +const size_t g_syscalls_64_len = + sizeof(g_syscalls_64) / sizeof(g_syscalls_64[0]); diff --git a/includes/syscalls_x86.h b/includes/syscalls_x86.h new file mode 100644 index 0000000..f938ae2 --- /dev/null +++ b/includes/syscalls_x86.h @@ -0,0 +1,405 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* syscalls_x86.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/12/11 05:56:09 by thrieg #+# #+# */ +/* Updated: 2025/12/11 05:58:14 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_strace.h" + +/* Auto-generated from https://x86.syscall.sh/ */ +static const t_syscall_desc g_syscalls_32[] = { + [ 0] = { "restart_syscall", 0 }, + [ 1] = { "exit", 1 }, + [ 2] = { "fork", 0 }, + [ 3] = { "read", 3 }, + [ 4] = { "write", 3 }, + [ 5] = { "open", 3 }, + [ 6] = { "close", 1 }, + [ 7] = { "waitpid", 3 }, + [ 8] = { "creat", 2 }, + [ 9] = { "link", 2 }, + [ 10] = { "unlink", 1 }, + [ 11] = { "execve", 3 }, + [ 12] = { "chdir", 1 }, + [ 13] = { "time", 1 }, + [ 14] = { "mknod", 3 }, + [ 15] = { "chmod", 2 }, + [ 16] = { "lchown", 3 }, + [ 17] = { "break", 6 }, + [ 18] = { "oldstat", 6 }, + [ 19] = { "lseek", 3 }, + [ 20] = { "getpid", 0 }, + [ 21] = { "mount", 5 }, + [ 22] = { "umount", 2 }, + [ 23] = { "setuid", 1 }, + [ 24] = { "getuid", 0 }, + [ 25] = { "stime", 1 }, + [ 26] = { "ptrace", 4 }, + [ 27] = { "alarm", 1 }, + [ 28] = { "oldfstat", 6 }, + [ 29] = { "pause", 0 }, + [ 30] = { "utime", 2 }, + [ 31] = { "stty", 6 }, + [ 32] = { "gtty", 6 }, + [ 33] = { "access", 2 }, + [ 34] = { "nice", 1 }, + [ 35] = { "ftime", 6 }, + [ 36] = { "sync", 0 }, + [ 37] = { "kill", 2 }, + [ 38] = { "rename", 2 }, + [ 39] = { "mkdir", 2 }, + [ 40] = { "rmdir", 1 }, + [ 41] = { "dup", 1 }, + [ 42] = { "pipe", 1 }, + [ 43] = { "times", 1 }, + [ 44] = { "prof", 6 }, + [ 45] = { "brk", 1 }, + [ 46] = { "setgid", 1 }, + [ 47] = { "getgid", 0 }, + [ 48] = { "signal", 2 }, + [ 49] = { "geteuid", 0 }, + [ 50] = { "getegid", 0 }, + [ 51] = { "acct", 1 }, + [ 52] = { "umount2", 6 }, + [ 53] = { "lock", 6 }, + [ 54] = { "ioctl", 3 }, + [ 55] = { "fcntl", 3 }, + [ 56] = { "mpx", 6 }, + [ 57] = { "setpgid", 2 }, + [ 58] = { "ulimit", 6 }, + [ 59] = { "oldolduname", 6 }, + [ 60] = { "umask", 1 }, + [ 61] = { "chroot", 1 }, + [ 62] = { "ustat", 2 }, + [ 63] = { "dup2", 2 }, + [ 64] = { "getppid", 0 }, + [ 65] = { "getpgrp", 0 }, + [ 66] = { "setsid", 0 }, + [ 67] = { "sigaction", 3 }, + [ 68] = { "sgetmask", 0 }, + [ 69] = { "ssetmask", 1 }, + [ 70] = { "setreuid", 2 }, + [ 71] = { "setregid", 2 }, + [ 72] = { "sigsuspend", 3 }, + [ 73] = { "sigpending", 1 }, + [ 74] = { "sethostname", 2 }, + [ 75] = { "setrlimit", 2 }, + [ 76] = { "getrlimit", 2 }, + [ 77] = { "getrusage", 2 }, + [ 78] = { "gettimeofday", 2 }, + [ 79] = { "settimeofday", 2 }, + [ 80] = { "getgroups", 2 }, + [ 81] = { "setgroups", 2 }, + [ 82] = { "select", 5 }, + [ 83] = { "symlink", 2 }, + [ 84] = { "oldlstat", 6 }, + [ 85] = { "readlink", 3 }, + [ 86] = { "uselib", 1 }, + [ 87] = { "swapon", 2 }, + [ 88] = { "reboot", 4 }, + [ 89] = { "readdir", 6 }, + [ 90] = { "mmap", 6 }, + [ 91] = { "munmap", 2 }, + [ 92] = { "truncate", 2 }, + [ 93] = { "ftruncate", 2 }, + [ 94] = { "fchmod", 2 }, + [ 95] = { "fchown", 3 }, + [ 96] = { "getpriority", 2 }, + [ 97] = { "setpriority", 3 }, + [ 98] = { "profil", 6 }, + [ 99] = { "statfs", 2 }, + [100] = { "fstatfs", 2 }, + [101] = { "ioperm", 3 }, + [102] = { "socketcall", 2 }, + [103] = { "syslog", 3 }, + [104] = { "setitimer", 3 }, + [105] = { "getitimer", 2 }, + [106] = { "stat", 2 }, + [107] = { "lstat", 2 }, + [108] = { "fstat", 2 }, + [109] = { "olduname", 1 }, + [110] = { "iopl", 6 }, + [111] = { "vhangup", 0 }, + [112] = { "idle", 6 }, + [113] = { "vm86old", 6 }, + [114] = { "wait4", 4 }, + [115] = { "swapoff", 1 }, + [116] = { "sysinfo", 1 }, + [117] = { "ipc", 6 }, + [118] = { "fsync", 1 }, + [119] = { "sigreturn", 6 }, + [120] = { "clone", 5 }, + [121] = { "setdomainname", 2 }, + [122] = { "uname", 1 }, + [123] = { "modify_ldt", 6 }, + [124] = { "adjtimex", 1 }, + [125] = { "mprotect", 3 }, + [126] = { "sigprocmask", 3 }, + [127] = { "create_module", 6 }, + [128] = { "init_module", 3 }, + [129] = { "delete_module", 2 }, + [130] = { "get_kernel_syms", 6 }, + [131] = { "quotactl", 4 }, + [132] = { "getpgid", 1 }, + [133] = { "fchdir", 1 }, + [134] = { "bdflush", 2 }, + [135] = { "sysfs", 3 }, + [136] = { "personality", 1 }, + [137] = { "afs_syscall", 6 }, + [138] = { "setfsuid", 1 }, + [139] = { "setfsgid", 1 }, + [140] = { "_llseek", 6 }, + [141] = { "getdents", 3 }, + [142] = { "_newselect", 6 }, + [143] = { "flock", 2 }, + [144] = { "msync", 3 }, + [145] = { "readv", 3 }, + [146] = { "writev", 3 }, + [147] = { "getsid", 1 }, + [148] = { "fdatasync", 1 }, + [149] = { "_sysctl", 6 }, + [150] = { "mlock", 2 }, + [151] = { "munlock", 2 }, + [152] = { "mlockall", 1 }, + [153] = { "munlockall", 0 }, + [154] = { "sched_setparam", 2 }, + [155] = { "sched_getparam", 2 }, + [156] = { "sched_setscheduler", 3 }, + [157] = { "sched_getscheduler", 1 }, + [158] = { "sched_yield", 0 }, + [159] = { "sched_get_priority_max", 1 }, + [160] = { "sched_get_priority_min", 1 }, + [161] = { "sched_rr_get_interval", 2 }, + [162] = { "nanosleep", 2 }, + [163] = { "mremap", 5 }, + [164] = { "setresuid", 3 }, + [165] = { "getresuid", 3 }, + [166] = { "vm86", 6 }, + [167] = { "query_module", 6 }, + [168] = { "poll", 3 }, + [169] = { "nfsservctl", 6 }, + [170] = { "setresgid", 3 }, + [171] = { "getresgid", 3 }, + [172] = { "prctl", 5 }, + [173] = { "rt_sigreturn", 6 }, + [174] = { "rt_sigaction", 4 }, + [175] = { "rt_sigprocmask", 4 }, + [176] = { "rt_sigpending", 2 }, + [177] = { "rt_sigtimedwait", 4 }, + [178] = { "rt_sigqueueinfo", 3 }, + [179] = { "rt_sigsuspend", 2 }, + [180] = { "pread64", 4 }, + [181] = { "pwrite64", 4 }, + [182] = { "chown", 3 }, + [183] = { "getcwd", 2 }, + [184] = { "capget", 2 }, + [185] = { "capset", 2 }, + [186] = { "sigaltstack", 2 }, + [187] = { "sendfile", 4 }, + [188] = { "getpmsg", 6 }, + [189] = { "putpmsg", 6 }, + [190] = { "vfork", 0 }, + [191] = { "ugetrlimit", 6 }, + [192] = { "mmap2", 6 }, + [193] = { "truncate64", 2 }, + [194] = { "ftruncate64", 2 }, + [195] = { "stat64", 2 }, + [196] = { "lstat64", 2 }, + [197] = { "fstat64", 2 }, + [198] = { "lchown32", 6 }, + [199] = { "getuid32", 6 }, + [200] = { "getgid32", 6 }, + [201] = { "geteuid32", 6 }, + [202] = { "getegid32", 6 }, + [203] = { "setreuid32", 6 }, + [204] = { "setregid32", 6 }, + [205] = { "getgroups32", 6 }, + [206] = { "setgroups32", 6 }, + [207] = { "fchown32", 6 }, + [208] = { "setresuid32", 6 }, + [209] = { "getresuid32", 6 }, + [210] = { "setresgid32", 6 }, + [211] = { "getresgid32", 6 }, + [212] = { "chown32", 6 }, + [213] = { "setuid32", 6 }, + [214] = { "setgid32", 6 }, + [215] = { "setfsuid32", 6 }, + [216] = { "setfsgid32", 6 }, + [217] = { "pivot_root", 2 }, + [218] = { "mincore", 3 }, + [219] = { "madvise", 3 }, + [220] = { "getdents64", 3 }, + [221] = { "fcntl64", 3 }, + [222] = { "not implemented", 0 }, + [223] = { "not implemented", 0 }, + [224] = { "gettid", 0 }, + [225] = { "readahead", 3 }, + [226] = { "setxattr", 5 }, + [227] = { "lsetxattr", 5 }, + [228] = { "fsetxattr", 5 }, + [229] = { "getxattr", 4 }, + [230] = { "lgetxattr", 4 }, + [231] = { "fgetxattr", 4 }, + [232] = { "listxattr", 3 }, + [233] = { "llistxattr", 3 }, + [234] = { "flistxattr", 3 }, + [235] = { "removexattr", 2 }, + [236] = { "lremovexattr", 2 }, + [237] = { "fremovexattr", 2 }, + [238] = { "tkill", 2 }, + [239] = { "sendfile64", 4 }, + [240] = { "futex", 6 }, + [241] = { "sched_setaffinity", 3 }, + [242] = { "sched_getaffinity", 3 }, + [243] = { "set_thread_area", 6 }, + [244] = { "get_thread_area", 6 }, + [245] = { "io_setup", 2 }, + [246] = { "io_destroy", 1 }, + [247] = { "io_getevents", 5 }, + [248] = { "io_submit", 3 }, + [249] = { "io_cancel", 3 }, + [250] = { "fadvise64", 4 }, + [251] = { "not implemented", 0 }, + [252] = { "exit_group", 1 }, + [253] = { "lookup_dcookie", 3 }, + [254] = { "epoll_create", 1 }, + [255] = { "epoll_ctl", 4 }, + [256] = { "epoll_wait", 4 }, + [257] = { "remap_file_pages", 5 }, + [258] = { "set_tid_address", 1 }, + [259] = { "timer_create", 3 }, + [260] = { "timer_settime", 4 }, + [261] = { "timer_gettime", 2 }, + [262] = { "timer_getoverrun", 1 }, + [263] = { "timer_delete", 1 }, + [264] = { "clock_settime", 2 }, + [265] = { "clock_gettime", 2 }, + [266] = { "clock_getres", 2 }, + [267] = { "clock_nanosleep", 4 }, + [268] = { "statfs64", 3 }, + [269] = { "fstatfs64", 3 }, + [270] = { "tgkill", 3 }, + [271] = { "utimes", 2 }, + [272] = { "fadvise64_64", 4 }, + [273] = { "vserver", 6 }, + [274] = { "mbind", 6 }, + [275] = { "get_mempolicy", 5 }, + [276] = { "set_mempolicy", 3 }, + [277] = { "mq_open", 4 }, + [278] = { "mq_unlink", 1 }, + [279] = { "mq_timedsend", 5 }, + [280] = { "mq_timedreceive", 5 }, + [281] = { "mq_notify", 2 }, + [282] = { "mq_getsetattr", 3 }, + [283] = { "kexec_load", 4 }, + [284] = { "waitid", 5 }, + [285] = { "not implemented", 0 }, + [286] = { "add_key", 5 }, + [287] = { "request_key", 4 }, + [288] = { "keyctl", 5 }, + [289] = { "ioprio_set", 3 }, + [290] = { "ioprio_get", 2 }, + [291] = { "inotify_init", 0 }, + [292] = { "inotify_add_watch", 3 }, + [293] = { "inotify_rm_watch", 2 }, + [294] = { "migrate_pages", 4 }, + [295] = { "openat", 4 }, + [296] = { "mkdirat", 3 }, + [297] = { "mknodat", 4 }, + [298] = { "fchownat", 5 }, + [299] = { "futimesat", 3 }, + [300] = { "fstatat64", 4 }, + [301] = { "unlinkat", 3 }, + [302] = { "renameat", 4 }, + [303] = { "linkat", 5 }, + [304] = { "symlinkat", 3 }, + [305] = { "readlinkat", 4 }, + [306] = { "fchmodat", 3 }, + [307] = { "faccessat", 3 }, + [308] = { "pselect6", 6 }, + [309] = { "ppoll", 5 }, + [310] = { "unshare", 1 }, + [311] = { "set_robust_list", 2 }, + [312] = { "get_robust_list", 3 }, + [313] = { "splice", 6 }, + [314] = { "sync_file_range", 4 }, + [315] = { "tee", 4 }, + [316] = { "vmsplice", 4 }, + [317] = { "move_pages", 6 }, + [318] = { "getcpu", 3 }, + [319] = { "epoll_pwait", 6 }, + [320] = { "utimensat", 4 }, + [321] = { "signalfd", 3 }, + [322] = { "timerfd_create", 2 }, + [323] = { "eventfd", 1 }, + [324] = { "fallocate", 4 }, + [325] = { "timerfd_settime", 4 }, + [326] = { "timerfd_gettime", 2 }, + [327] = { "signalfd4", 4 }, + [328] = { "eventfd2", 2 }, + [329] = { "epoll_create1", 1 }, + [330] = { "dup3", 3 }, + [331] = { "pipe2", 2 }, + [332] = { "inotify_init1", 1 }, + [333] = { "preadv", 5 }, + [334] = { "pwritev", 5 }, + [335] = { "rt_tgsigqueueinfo", 4 }, + [336] = { "perf_event_open", 5 }, + [337] = { "recvmmsg", 5 }, + [338] = { "fanotify_init", 2 }, + [339] = { "fanotify_mark", 5 }, + [340] = { "prlimit64", 4 }, + [341] = { "name_to_handle_at", 5 }, + [342] = { "open_by_handle_at", 3 }, + [343] = { "clock_adjtime", 2 }, + [344] = { "syncfs", 1 }, + [345] = { "sendmmsg", 4 }, + [346] = { "setns", 2 }, + [347] = { "process_vm_readv", 6 }, + [348] = { "process_vm_writev", 6 }, + [349] = { "kcmp", 5 }, + [350] = { "finit_module", 3 }, + [351] = { "sched_setattr", 3 }, + [352] = { "sched_getattr", 4 }, + [353] = { "renameat2", 5 }, + [354] = { "seccomp", 3 }, + [355] = { "getrandom", 3 }, + [356] = { "memfd_create", 2 }, + [357] = { "bpf", 3 }, + [358] = { "execveat", 5 }, + [359] = { "socket", 3 }, + [360] = { "socketpair", 4 }, + [361] = { "bind", 3 }, + [362] = { "connect", 3 }, + [363] = { "listen", 2 }, + [364] = { "accept4", 4 }, + [365] = { "getsockopt", 5 }, + [366] = { "setsockopt", 5 }, + [367] = { "getsockname", 3 }, + [368] = { "getpeername", 3 }, + [369] = { "sendto", 6 }, + [370] = { "sendmsg", 3 }, + [371] = { "recvfrom", 6 }, + [372] = { "recvmsg", 3 }, + [373] = { "shutdown", 2 }, + [374] = { "userfaultfd", 1 }, + [375] = { "membarrier", 2 }, + [376] = { "mlock2", 3 }, + [377] = { "copy_file_range", 6 }, + [378] = { "preadv2", 6 }, + [379] = { "pwritev2", 6 }, + [380] = { "pkey_mprotect", 4 }, + [381] = { "pkey_alloc", 2 }, + [382] = { "pkey_free", 1 }, + [383] = { "statx", 5 }, + [384] = { "arch_prctl", 6 }, +}; + +const size_t g_syscalls_32_len = + sizeof(g_syscalls_64) / sizeof(g_syscalls_64[0]); diff --git a/libft/Makefile b/libft/Makefile new file mode 100755 index 0000000..d19126e --- /dev/null +++ b/libft/Makefile @@ -0,0 +1,79 @@ +CC = cc + +CFLAGS = -Wall -Wextra -Werror -O3 -g3 -fPIC + +SRCS = ./ft_isalnum.c ./ft_isalpha.c ./ft_isascii.c ./ft_isdigit.c \ + ./ft_isprint.c ./ft_memset.c ./ft_strlen.c ./ft_bzero.c ./ft_memcpy.c \ + ./ft_memmove.c ./ft_strlcpy.c ./ft_strlcat.c ./ft_toupper.c \ + ./ft_tolower.c ./ft_strchr.c ./ft_strrchr.c ./ft_strncmp.c \ + ./ft_memchr.c ./ft_memcmp.c ./ft_strnstr.c ./ft_atoi.c \ + ./ft_strdup.c ./ft_calloc.c ./ft_substr.c ./ft_strjoin.c \ + ./ft_strtrim.c ./ft_split.c ./ft_itoa.c ./ft_strmapi.c \ + ./ft_striteri.c ./ft_putchar_fd.c ./ft_putstr_fd.c \ + ./ft_putendl_fd.c ./ft_putnbr_fd.c ./ft_int_utils.c \ + ./ft_safe_int_math.c ./ft_split2.c ./ft_long_utils.c \ + ./ft_safe_long_math.c + +SRCSBONUS = ./ft_lstnew_bonus.c ./ft_lstadd_front_bonus.c ./ft_lstsize_bonus.c ./ft_lstlast_bonus.c ./ft_lstadd_back_bonus.c ./ft_lstdelone_bonus.c ./ft_lstclear_bonus.c ./ft_lstiter_bonus.c ./ft_lstmap_bonus.c ./ft_vector.c ./ft_itoa_base.c ./ft_addr_to_str.c ./ft_utoa.c ./ft_strnonchr.c ./ft_utoa_base.c ./ft_strcmp.c ./ft_vecint.c ./ft_power.c + +SRCS_GNL = ./get_next_line/get_next_line.c ./get_next_line/get_next_line_utils.c ./get_next_line/get_next_line_utils_two.c + +FT_PRINTF_PATH = ./ft_printf/ +SRC_PRINTF = ft_printf.c ft_cases_mandatory_one.c ft_cases_mandatory_two.c ft_printf_bonus.c ft_cases_easy_bonus.c ft_case_lowx_bonus.c ft_case_uppx_bonus.c ft_case_u_bonus.c ft_case_s_bonus.c ft_case_p_bonus.c ft_case_d_bonus.c ft_case_d_utils_bonus.c ft_arglist_bonus.c ft_padding_bonus.c +SRCS_PRINTF = $(addprefix $(FT_PRINTF_PATH), $(SRC_PRINTF)) + +FT_HASHMAP_PATH = ./ft_hashmap/ +SRC_HASHMAP = ft_hashmap.c ft_hashmap_utils.c ft_hashmap_utils_two.c ft_hashmap_basic_type_hash.c ft_hashmap_advanced_type_hash.c ft_hashmap_basic_cmp.c +SRCS_HASHMAP = $(addprefix $(FT_HASHMAP_PATH), $(SRC_HASHMAP)) + +FT_PQ_PATH = ./ft_priority_queue/ +SRC_PQ = ft_priority_queue.c ft_priority_queue_utils.c +SRCS_PQ = $(addprefix $(FT_PQ_PATH), $(SRC_PQ)) + +FT_SORTING_PATH = ./sorting/ +SRC_SORTING = ft_radixsort.c ft_sorting.c +SRCS_SORTING = $(addprefix $(FT_SORTING_PATH), $(SRC_SORTING)) + +OBJS = $(SRCS:.c=.o) + +OBJSBONUS = $(SRCSBONUS:.c=.o) + +OBJS_GNL = $(SRCS_GNL:.c=.o) + +OBJS_PRINTF = $(SRCS_PRINTF:.c=.o) + +OBJS_HASHMAP = $(SRCS_HASHMAP:.c=.o) + +OBJS_PQ = $(SRCS_PQ:.c=.o) + +OBJS_SORTING = $(SRCS_SORTING:.c=.o) + +NAME = libft.a + +RED := \033[0;31m +GREEN := \033[0;32m +YELLOW := \033[0;33m +BLUE := \033[0;34m +NC := \033[0m + + +all: $(NAME) + +$(NAME): $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @ar rcs $(NAME) $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @echo "$(GREEN)finished compiling $(NAME)!$(NC)" + +bonus: $(NAME) + +./%.o: ./%.c + @$(CC) $(CFLAGS) -c $< -o $@ + +clean: + @rm -f $(OBJS) $(OBJSBONUS) $(OBJS_GNL) $(OBJS_PRINTF) $(OBJS_HASHMAP) $(OBJS_PQ) $(OBJS_SORTING) + @echo "$(YELLOW)deleted object files from $(NAME)$(NC)" + +fclean: clean + @rm -f $(NAME) + @echo "$(YELLOW)deleted $(NAME)$(NC)" + +re: fclean all diff --git a/libft/ft_addr_to_str.c b/libft/ft_addr_to_str.c new file mode 100755 index 0000000..012271b --- /dev/null +++ b/libft/ft_addr_to_str.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_addr_to_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 16:54:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:02:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +void ft_convert_to_hexa(char c, char hex_buff[2]) +{ + hex_buff[1] = c & 0b00001111; + hex_buff[0] = (c >> 4) & 0b00001111; + if (hex_buff[0] <= 9) + hex_buff[0] += '0'; + else + hex_buff[0] += 'a' - 10; + if (hex_buff[1] <= 9) + hex_buff[1] += '0'; + else + hex_buff[1] += 'a' - 10; +} + +//convert the address addr in hexadecimal and returns a standard c string. +//returns NULL if the allocation fails +char *ft_addr_to_strhex(void *addr) +{ + char hex_buff[2]; + int i; + int j; + uintptr_t address; + char *ret; + + ret = malloc((sizeof(char) * sizeof(uintptr_t) * 2) + 1); + if (!ret) + return (NULL); + address = (uintptr_t)addr; + i = (sizeof(uintptr_t) * 8) - 8; + j = 0; + while (i >= 0) + { + ft_convert_to_hexa(((address >> i) & 0xFF), hex_buff); + ret[j++] = hex_buff[0]; + ret[j++] = hex_buff[1]; + i -= 8; + } + ret[j] = '\0'; + return (ret); +} diff --git a/libft/ft_addr_to_str.o b/libft/ft_addr_to_str.o new file mode 100644 index 0000000..e1e4027 Binary files /dev/null and b/libft/ft_addr_to_str.o differ diff --git a/libft/ft_atoi.c b/libft/ft_atoi.c new file mode 100755 index 0000000..ed894b7 --- /dev/null +++ b/libft/ft_atoi.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atoi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 18:37:49 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:02:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +static int ft_is_space(char c) +{ + if (c == '\t' || c == '\n' || c == '\v' + || c == '\f' || c == '\r' || c == ' ') + return (1); + else + return (0); +} + +static int ft_convert_to_int(const char *str, int sign, int *overflow_flag) +{ + int value; + + value = 0; + while (ft_isdigit(*str)) + { + if (sign == 1) + { + if (value > (INT_MAX - (*str - '0')) / 10) + if (overflow_flag) + *overflow_flag = 1; + value = value * 10 + (*str - '0'); + } + else + { + if (value < (INT_MIN + (*str - '0')) / 10) + if (overflow_flag) + *overflow_flag = 1; + value = value * 10 - (*str - '0'); + } + str++; + } + return (value); +} + +int ft_atoi(const char *nptr, int *overflow_flag) +{ + int sign; + + if (overflow_flag) + *overflow_flag = 0; + while ((*nptr != '\0') && ft_is_space(*nptr)) + { + nptr++; + } + sign = 1; + if ((*nptr != '\0') && (*nptr == '-' || *nptr == '+')) + { + if (*nptr == '-') + sign = -sign; + nptr++; + } + if (!ft_isdigit(*nptr)) + return (0); + return (ft_convert_to_int(nptr, sign, overflow_flag)); +} diff --git a/libft/ft_atoi.o b/libft/ft_atoi.o new file mode 100644 index 0000000..9bd9f17 Binary files /dev/null and b/libft/ft_atoi.o differ diff --git a/libft/ft_bzero.c b/libft/ft_bzero.c new file mode 100755 index 0000000..e1c46d7 --- /dev/null +++ b/libft/ft_bzero.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_bzero.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:50:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:30 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_bzero(void *s, size_t n) +{ + ft_memset(s, '\0', n); +} diff --git a/libft/ft_bzero.o b/libft/ft_bzero.o new file mode 100644 index 0000000..cea2d87 Binary files /dev/null and b/libft/ft_bzero.o differ diff --git a/libft/ft_calloc.c b/libft/ft_calloc.c new file mode 100755 index 0000000..4fb1e1f --- /dev/null +++ b/libft/ft_calloc.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_calloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 19:42:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:37 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_calloc(size_t nmemb, size_t size) +{ + void *ret; + + if ((size == 0) || (nmemb == 0)) + { + return (malloc(0)); + } + if (nmemb > __SIZE_MAX__ / size) + return (NULL); + ret = malloc(nmemb * size); + if (!ret) + return (NULL); + ft_bzero(ret, (nmemb * size)); + return (ret); +} diff --git a/libft/ft_calloc.o b/libft/ft_calloc.o new file mode 100644 index 0000000..6f8d661 Binary files /dev/null and b/libft/ft_calloc.o differ diff --git a/libft/ft_hashmap.h b/libft/ft_hashmap.h new file mode 100755 index 0000000..900598e --- /dev/null +++ b/libft/ft_hashmap.h @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:14:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:02 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_HASHMAP_H +# define FT_HASHMAP_H + +# include "libft.h" +# include "ft_vector.h" + +# define HASHMAP_FILL_PERCENT_MAX 200 +# define HASHMAP_RESIZE_FACTOR 2 +# define HASHMAP_MINIMUM_SIZE 16 +# define HASHMAP_FILL_PERCENT_BEFORE_SHRINK 50 +# define HASHMAP_SHRINK_FACTOR 2 + +typedef struct s_hashmap +{ + t_list **table; + size_t hashmap_size; + size_t nb_elems; + void (*free_key)(void *key); + void (*free_value)(void *value); + int (*cmp)(void *key, void *key_to_compare); +} t_hashmap; + +size_t ft_hash_int(int value); +size_t ft_hash_uint(unsigned int value); +size_t ft_hash_char(char value); +size_t ft_hash_string(const char *str); +size_t ft_hash_size_t(size_t value); +size_t ft_hash_address(const void *key); +size_t ft_hash_list(const t_list *list); +size_t ft_hash_hashmap(const t_hashmap *hashmap); +size_t ft_hash_vector(const t_vector *vec); +// Comparison function for integers +int int_cmp(void *key1, void *key2); +// Comparison function for strings +int cmp_str(void *key1, void *key2); +// Comparison function for unsigned chars +int cmp_uchar(void *key1, void *key2); +// Comparison function for unsigned integers +int uint_cmp(void *key1, void *key2); +// Comparison function for size_t +int sizet_cmp(void *key1, void *key2); + +//returns 0 without doing anything if the allocation of the new table fails +//in that case the old table is still valid! +//returns 1 if the resize is a success +int ft_resize_hashmap(t_hashmap *map); + +//returns 0 without doing anything if the allocation of the new table fails +//or if the table is too little in that case the old table is still valid! +//returns 1 if the shrink is a success +int ft_shrink_hashmap(t_hashmap *map); + +//applies functions free_key and free_value on the element if they are not NULL +//returns 1 if the element has been deleted +//returns 0 if the element has not been found +int ft_delete_hashmap_element(t_hashmap *map, void *key, size_t hash); + +//returns a pointer to the value of key, or a NULL pointer if not found +void *ft_lookup_hashmap_element(t_hashmap *map, void *key, size_t hash); + +//frees the entire hashmap and then returns NULL once done +void *ft_free_hashmap(t_hashmap *map); + +// Inserts a key-value pair into the hashmap, +//returns 0 for an error, 1 for remplaced value for a key and 2 for new key +int ft_hashmap_insert_element( + t_hashmap *map, + void *key, + void *value, + size_t hash); + +//allocates an array of initial_size, and sets nb_elems/hashmap_size to 0 +//cmp is a function that returns 0 if both keys are the same +//returns NULL if any allocation fails +t_hashmap *ft_create_hashmap( + size_t initial_size, + void (*free_key)(void *), + void (*free_value)(void *), + int (*cmp)(void *key, void *key_to_compare)); + +#endif diff --git a/libft/ft_hashmap/ft_hashmap.c b/libft/ft_hashmap/ft_hashmap.c new file mode 100755 index 0000000..46d451e --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap.c @@ -0,0 +1,156 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:14:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:34 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +//allocates an array of initial_size, and sets nb_elems/hashmap_size to 0 +//cmp is a function that returns 0 if both keys are the same +//returns NULL if any allocation fails +t_hashmap *ft_create_hashmap( +size_t initial_size, +void (*free_key)(void *), +void (*free_value)(void *), +int (*cmp)(void *key, void *key_to_compare)) +{ + t_hashmap *map; + + if (initial_size == 0) + return (NULL); + map = malloc(sizeof(t_hashmap)); + if (!map) + return (NULL); + map->nb_elems = 0; + map->hashmap_size = initial_size; + map->cmp = cmp; + map->free_key = free_key; + map->free_value = free_value; + map->table = ft_calloc((initial_size), sizeof(t_list *)); + if (!(map->table)) + return (free(map), NULL); + return (map); +} + +// Inserts a key-value pair into the hashmap, +//returns 0 for an error, 1 for remplaced value for a key and 2 for new key +int ft_hashmap_insert_element( +t_hashmap *map, +void *key, +void *value, +size_t hash) +{ + size_t index; + t_list *current; + t_hash_element *element; + + if (!map || !key) + return (0); + if ((map->nb_elems * 100) > map->hashmap_size * HASHMAP_FILL_PERCENT_MAX) + ft_resize_hashmap(map); + index = hash % map->hashmap_size; + current = map->table[index]; + while (current) + { + if (map->cmp(((t_hash_element *)(current->content))->key, key) == 0) + { + map->free_value(((t_hash_element *)(current->content))->value); + return (((t_hash_element *)(current->content))->value = value, 1); + } + current = current->next; + } + element = ft_create_hash_element(key, value, hash); + if (!element) + return (0); + if (!ft_add_hashmap_element(index, map, element)) + return (ft_free_hash_element(element, map), 0); + return (2); +} + +//returns 1 if the element has been deleted +//returns 0 if the element has not been found +int ft_delete_hashmap_element(t_hashmap *map, void *key, size_t hash) +{ + size_t index; + t_list *curr; + t_list *prev; + t_hash_element *elem; + + if (!map || !key || map->hashmap_size == 0) + return (0); + if (((map->nb_elems * 100) / map->hashmap_size) + <= HASHMAP_FILL_PERCENT_BEFORE_SHRINK) + ft_shrink_hashmap(map); + index = hash % map->hashmap_size; + curr = map->table[index]; + prev = NULL; + while (curr) + { + elem = (t_hash_element *)curr->content; + if (map->cmp(elem->key, key) == 0) + { + return (ft_delete_hashmap_list_node(curr, prev, index, map), 1); + } + prev = curr; + curr = curr->next; + } + return (0); +} + +//returns a pointer to the value of key, or a NULL pointer if not found +void *ft_lookup_hashmap_element(t_hashmap *map, void *key, size_t hash) +{ + size_t index; + t_list *curr; + t_hash_element *elem; + + if (!map || !key || map->hashmap_size == 0) + return (NULL); + index = hash % map->hashmap_size; + curr = map->table[index]; + while (curr) + { + elem = (t_hash_element *)curr->content; + if (map->cmp(elem->key, key) == 0) + return (elem->value); + curr = curr->next; + } + return (NULL); +} + +//frees the entire hashmap and then returns NULL once done +void *ft_free_hashmap(t_hashmap *map) +{ + size_t index; + t_list *curr; + t_list *next; + t_hash_element *elem; + + if (!map) + return (NULL); + if (!map->table) + return (free(map), NULL); + index = 0; + while (index < map->hashmap_size) + { + curr = map->table[index]; + while (curr) + { + next = curr->next; + elem = (t_hash_element *)curr->content; + ft_free_hash_element(elem, map); + free(curr); + curr = next; + } + index++; + } + free(map->table); + return (free(map), NULL); +} diff --git a/libft/ft_hashmap/ft_hashmap.o b/libft/ft_hashmap/ft_hashmap.o new file mode 100644 index 0000000..aa5e739 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap.o differ diff --git a/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c new file mode 100755 index 0000000..f93cb16 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_advanced_type_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:47:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:26 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" +#include + +//hash function for an address, returns a size_t between 0 and size_t max +size_t ft_hash_address(const void *key) +{ + uintptr_t address; + + address = (uintptr_t)key; + return ((size_t)address >> 3); +} + +// Hash function for a t_list, returns a size_t between 0 and size_t max +//takes the function to hash a single element +size_t ft_hash_list(const t_list *list) +{ + return (ft_hash_address(list)); +} + +// Hash function for a t_hashmap, returns a size_t between 0 and size_t max +size_t ft_hash_hashmap(const t_hashmap *hashmap) +{ + return (ft_hash_address(hashmap)); +} + +// Hash function for a t_vector, returns a size_t between 0 and size_t max +size_t ft_hash_vector(const t_vector *vec) +{ + size_t i; + int c; + size_t index; + size_t hash; + char *str; + + hash = 5381; + index = vec->index; + str = vec->buffer; + i = 0; + while (i < index) + { + c = str[i++]; + hash = ((hash << 5) + hash) + c; + } + return (hash); +} diff --git a/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o new file mode 100644 index 0000000..05dabc0 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_advanced_type_hash.o differ diff --git a/libft/ft_hashmap/ft_hashmap_basic_cmp.c b/libft/ft_hashmap/ft_hashmap_basic_cmp.c new file mode 100755 index 0000000..4ffb8db --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_basic_cmp.c @@ -0,0 +1,79 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_basic_cmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 13:18:52 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" +#include + +// Comparison function for integers +int int_cmp(void *key1, void *key2) +{ + int a; + int b; + + a = *(int *)key1; + b = *(int *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} + +// Comparison function for strings +int cmp_str(void *key1, void *key2) +{ + return (ft_strcmp((char *)key1, (char *)key2)); +} + +// Comparison function for unsigned chars +int cmp_uchar(void *key1, void *key2) +{ + unsigned char *c1; + unsigned char *c2; + + c1 = (unsigned char *)key1; + c2 = (unsigned char *)key2; + return (*c1 - *c2); +} + +// Comparison function for unsigned integers +int uint_cmp(void *key1, void *key2) +{ + unsigned int a; + unsigned int b; + + a = *(unsigned int *)key1; + b = *(unsigned int *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} + +// Comparison function for size_t +int sizet_cmp(void *key1, void *key2) +{ + size_t a; + size_t b; + + a = *(size_t *)key1; + b = *(size_t *)key2; + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); +} diff --git a/libft/ft_hashmap/ft_hashmap_basic_cmp.o b/libft/ft_hashmap/ft_hashmap_basic_cmp.o new file mode 100644 index 0000000..22b52da Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_basic_cmp.o differ diff --git a/libft/ft_hashmap/ft_hashmap_basic_type_hash.c b/libft/ft_hashmap/ft_hashmap_basic_type_hash.c new file mode 100755 index 0000000..2f58485 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_basic_type_hash.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_basic_type_hash.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 12:34:20 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:29 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +// Integer hash function, returns a size_t between 0 and size_t max +size_t ft_hash_int(int value) +{ + return ((size_t)(value * 2654435761u)); +} + +// Unsigned integer hash function, returns a size_t between 0 and size_t max +size_t ft_hash_uint(unsigned int value) +{ + return ((size_t)(value * 2654435761u)); +} + +// Character hash function, returns a size_t between 0 and size_t max +size_t ft_hash_char(char value) +{ + return ((size_t)(value * 31)); +} + +// String hash function (DJB2), returns a size_t between 0 and size_t max +size_t ft_hash_string(const char *str) +{ + int c; + size_t hash; + + hash = 5381; + while (*str) + { + c = *str++; + hash = ((hash << 5) + hash) + c; + } + return (hash); +} + +// size_t hash function, returns a size_t between 0 and size_t max +size_t ft_hash_size_t(size_t value) +{ + value ^= value >> 33; + value *= 0xff51afd7ed558ccd; + value ^= value >> 33; + value *= 0xc4ceb9fe1a85ec53; + value ^= value >> 33; + return (value); +} diff --git a/libft/ft_hashmap/ft_hashmap_basic_type_hash.o b/libft/ft_hashmap/ft_hashmap_basic_type_hash.o new file mode 100644 index 0000000..dbe41a4 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_basic_type_hash.o differ diff --git a/libft/ft_hashmap/ft_hashmap_private.h b/libft/ft_hashmap/ft_hashmap_private.h new file mode 100755 index 0000000..d61db25 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_private.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 13:49:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:30 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_HASHMAP_PRIVATE_H +# define FT_HASHMAP_PRIVATE_H + +# include "../ft_hashmap.h" + +typedef struct s_hash_element +{ + void *key; + void *value; + size_t hash; +} t_hash_element; + +t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash); +void ft_free_hash_element(t_hash_element *elem, t_hashmap *map); +int ft_add_hashmap_element( + size_t index, + t_hashmap *map, + t_hash_element *elem); +int ft_add_hashmap_element( + size_t index, + t_hashmap *map, + t_hash_element *elem); +void ft_copy_hashmap_table( + t_list **new_table, + t_list **old_table, + size_t new_size, + size_t old_size); +void ft_delete_hashmap_list_node( + t_list *curr, + t_list *prev, + size_t index, + t_hashmap *map); + +#endif \ No newline at end of file diff --git a/libft/ft_hashmap/ft_hashmap_utils.c b/libft/ft_hashmap/ft_hashmap_utils.c new file mode 100755 index 0000000..688e91c --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_utils.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 13:51:48 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:32 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +void ft_free_hash_element(t_hash_element *elem, t_hashmap *map) +{ + if (map->free_key) + map->free_key(elem->key); + if (map->free_value) + map->free_value(elem->value); + free(elem); +} + +// Helper function to create a new hash element +t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash) +{ + t_hash_element *new_element; + + new_element = malloc(sizeof(t_hash_element)); + if (!new_element) + return (NULL); + new_element->key = key; + new_element->value = value; + new_element->hash = hash; + return (new_element); +} + +//returns 0 for allocation fail without allocating or freeing anything +int ft_add_hashmap_element(size_t index, t_hashmap *map, t_hash_element *elem) +{ + t_list *new_node; + + new_node = malloc(sizeof(t_list)); + if (!new_node) + return (0); + new_node->content = elem; + new_node->next = map->table[index]; + map->table[index] = new_node; + map->nb_elems++; + return (1); +} + +//returns 0 without doing anything if the allocation of the new table fails +//in that case the old table is still valid! +//returns 1 if the resize is a success +int ft_resize_hashmap(t_hashmap *map) +{ + size_t new_size; + t_list **new_table; + + new_size = map->hashmap_size * HASHMAP_RESIZE_FACTOR; + new_table = ft_calloc(new_size, sizeof(t_list *)); + if (!new_table) + return (0); + ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size); + free(map->table); + map->table = new_table; + map->hashmap_size = new_size; + return (1); +} diff --git a/libft/ft_hashmap/ft_hashmap_utils.o b/libft/ft_hashmap/ft_hashmap_utils.o new file mode 100644 index 0000000..949f506 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_utils.o differ diff --git a/libft/ft_hashmap/ft_hashmap_utils_two.c b/libft/ft_hashmap/ft_hashmap_utils_two.c new file mode 100755 index 0000000..2a37c43 --- /dev/null +++ b/libft/ft_hashmap/ft_hashmap_utils_two.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_hashmap_utils_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/07 16:04:36 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:31 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_hashmap_private.h" + +//doesn't allocate anything no error possible +void ft_copy_hashmap_table( +t_list **new_table, +t_list **old_table, +size_t new_size, +size_t old_size) +{ + t_list *curr; + t_list *next; + t_hash_element *elem; + size_t i; + size_t new_index; + + i = 0; + while (i < old_size) + { + curr = old_table[i]; + while (curr) + { + next = curr->next; + elem = (t_hash_element *)curr->content; + new_index = elem->hash % new_size; + curr->next = new_table[new_index]; + new_table[new_index] = curr; + curr = next; + } + i++; + } +} + +//helper function for delete_hashmap_element to delete the node once found +void ft_delete_hashmap_list_node( +t_list *curr, +t_list *prev, +size_t index, +t_hashmap *map) +{ + t_hash_element *elem; + + elem = (t_hash_element *)curr->content; + if (prev) + prev->next = curr->next; + else + map->table[index] = curr->next; + ft_free_hash_element(elem, map); + free(curr); + map->nb_elems--; +} + +//returns 0 without doing anything if the allocation of the new table fails +//or if the table is too little in that case the old table is still valid! +//returns 1 if the shrink is a success +int ft_shrink_hashmap(t_hashmap *map) +{ + size_t new_size; + t_list **new_table; + + if (map->hashmap_size == HASHMAP_MINIMUM_SIZE) + return (0); + new_size = map->hashmap_size / HASHMAP_SHRINK_FACTOR; + if (new_size < HASHMAP_MINIMUM_SIZE) + new_size = HASHMAP_MINIMUM_SIZE; + new_table = ft_calloc(new_size, sizeof(t_list *)); + if (!new_table) + return (0); + ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size); + free(map->table); + map->table = new_table; + map->hashmap_size = new_size; + return (1); +} diff --git a/libft/ft_hashmap/ft_hashmap_utils_two.o b/libft/ft_hashmap/ft_hashmap_utils_two.o new file mode 100644 index 0000000..3107c37 Binary files /dev/null and b/libft/ft_hashmap/ft_hashmap_utils_two.o differ diff --git a/libft/ft_int_utils.c b/libft/ft_int_utils.c new file mode 100644 index 0000000..605d680 --- /dev/null +++ b/libft/ft_int_utils.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_int_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/30 10:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:03:36 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "libft.h" + +size_t i_drep_len(int n) +{ + size_t len; + + len = 0; + if (n < 0) + len++; + while (1) + { + len++; + n /= 10; + if (n == 0) + break ; + } + return (len); +} + +/* + * Reimplementation of libc atoi() but sets `errno` to `ERANGE` if an + * domain error is encountered (overflow, underflow) or `EINVAL` if + * no digits characters or invalid characters at end). + */ +int ft_atoie(const char *nptr) +{ + int n; + int mult; + + n = 0; + mult = -1; + while (ft_isspace(*nptr)) + nptr++; + if (*nptr == '+' || *nptr == '-') + { + if (*nptr == '-') + mult = 1; + nptr++; + } + if (!ft_isdigit(*nptr)) + errno = EINVAL; + while (ft_isdigit(*nptr)) + { + n = safe_int_sub(safe_int_mul(n, 10), *nptr - '0'); + nptr++; + } + if (*nptr != '\0') + errno = EINVAL; + return (safe_int_mul(n, mult)); +} + +unsigned int ft_max_uint(size_t len, unsigned int a[len]) +{ + size_t i; + unsigned int max; + + i = 0; + max = 0; + while (i < len) + { + if (a[i] > max) + max = a[i]; + i++; + } + return (max); +} diff --git a/libft/ft_int_utils.o b/libft/ft_int_utils.o new file mode 100644 index 0000000..304e914 Binary files /dev/null and b/libft/ft_int_utils.o differ diff --git a/libft/ft_isalnum.c b/libft/ft_isalnum.c new file mode 100755 index 0000000..f3c9bec --- /dev/null +++ b/libft/ft_isalnum.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalnum.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:44:53 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:40 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_isalnum(int c) +{ + if (ft_isalpha(c) | ft_isdigit(c)) + return (1); + return (0); +} diff --git a/libft/ft_isalnum.o b/libft/ft_isalnum.o new file mode 100644 index 0000000..e30ee80 Binary files /dev/null and b/libft/ft_isalnum.o differ diff --git a/libft/ft_isalpha.c b/libft/ft_isalpha.c new file mode 100755 index 0000000..bee9f1e --- /dev/null +++ b/libft/ft_isalpha.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalpha.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/06 12:44:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isalpha(int c) +{ + if (c < 65 || c > 122 || (c > 90 && c < 97)) + return (0); + else + return (1); +} + +int ft_isspace(char c) +{ + return (c == ' ' || c == '\f' || c == '\n' || c == '\r' + || c == '\t' || c == '\v'); +} + +int ft_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + ('a' - 'A')); + return (c); +} + +int ft_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return (c - ('a' - 'A')); + return (c); +} diff --git a/libft/ft_isalpha.o b/libft/ft_isalpha.o new file mode 100644 index 0000000..cde61af Binary files /dev/null and b/libft/ft_isalpha.o differ diff --git a/libft/ft_isascii.c b/libft/ft_isascii.c new file mode 100755 index 0000000..f02c1b6 --- /dev/null +++ b/libft/ft_isascii.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isascii.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:10:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:43 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isascii(int c) +{ + if (c >= 0 && c < 128) + return (1); + return (0); +} diff --git a/libft/ft_isascii.o b/libft/ft_isascii.o new file mode 100644 index 0000000..f46cba9 Binary files /dev/null and b/libft/ft_isascii.o differ diff --git a/libft/ft_isdigit.c b/libft/ft_isdigit.c new file mode 100755 index 0000000..e47bbd5 --- /dev/null +++ b/libft/ft_isdigit.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isdigit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/08 12:57:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isdigit(int c) +{ + if (c < '0' || c > '9') + return (0); + return (1); +} diff --git a/libft/ft_isdigit.o b/libft/ft_isdigit.o new file mode 100644 index 0000000..8d56b1a Binary files /dev/null and b/libft/ft_isdigit.o differ diff --git a/libft/ft_isprint.c b/libft/ft_isprint.c new file mode 100755 index 0000000..383b8c1 --- /dev/null +++ b/libft/ft_isprint.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:14:35 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_isprint(int c) +{ + if (c < 32 || c > 126) + return (0); + return (1); +} diff --git a/libft/ft_isprint.o b/libft/ft_isprint.o new file mode 100644 index 0000000..a471713 Binary files /dev/null and b/libft/ft_isprint.o differ diff --git a/libft/ft_itoa.c b/libft/ft_itoa.c new file mode 100755 index 0000000..7ec2d70 --- /dev/null +++ b/libft/ft_itoa.c @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 15:29:15 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:49 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void ft_swap(char *a, char *b) +{ + char c; + + c = *a; + *a = *b; + *b = c; +} + +static void ft_reverse_buff(char buff[11], size_t(len)) +{ + size_t index; + + if (buff[0] == '-') + { + index = 1; + while ((len / 2) >= index) + { + ft_swap(&buff[index], &buff[len - index]); + index++; + } + } + else + { + index = 0; + while (((len - 1) / 2) >= index) + { + ft_swap(&buff[index], &buff[len - index - 1]); + index++; + } + } +} + +static char *subfunction(char *ret, char buff[11], size_t buff_len) +{ + ft_reverse_buff(buff, buff_len); + ft_memcpy(ret, (const void *)buff, buff_len); + ret[buff_len] = '\0'; + return (ret); +} + +//only works if an int is 32 bits, I'll maybe change it later for the bonuses +char *ft_itoa(int n) +{ + char *ret; + char buff[11]; + size_t buff_len; + + if (n <= -2147483648) + return (ft_strdup("-2147483648")); + if (n == 0) + return (ft_strdup("0")); + buff_len = 0; + if (n < 0) + { + buff[0] = '-'; + buff_len++; + n *= -1; + } + while (n > 0) + { + buff[buff_len++] = (n % 10) + '0'; + n /= 10; + } + ret = malloc(sizeof(char) * (buff_len) + 1); + if (!ret) + return (NULL); + return (subfunction(ret, buff, buff_len)); +} diff --git a/libft/ft_itoa.o b/libft/ft_itoa.o new file mode 100644 index 0000000..5c95f3a Binary files /dev/null and b/libft/ft_itoa.o differ diff --git a/libft/ft_itoa_base.c b/libft/ft_itoa_base.c new file mode 100755 index 0000000..18fe48e --- /dev/null +++ b/libft/ft_itoa_base.c @@ -0,0 +1,120 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_itoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/09/11 11:50:53 by thrieg #+# #+# */ +/* Updated: 2025/11/17 17:14:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "ft_vector.h" + +static int ft_is_sign(char c) +{ + if (c == '-' || c == '+') + return (1); + else + return (0); +} + +//converts nbr into a known to be valid base, then append it to vec +//returns 0 if the concatenation fails, or 1 if everything goes well +static int ft_put_ok_base( +unsigned int nbr, +char *base, +size_t base_lenght, +t_vector *vec) +{ + char buffer[32]; + int i; + + i = 31; + if (nbr == 0) + if (!ft_vector_pushback(vec, base[0])) + return (0); + while (nbr > 0) + { + buffer[i] = base[nbr % base_lenght]; + nbr /= base_lenght; + i--; + } + if (!ft_vector_concat(vec, (buffer + i + 1), (31 - i))) + return (0); + return (1); +} + +//converts nbr into an unsigned int, +//append a minus sign in vec if nbr is negative +//sets flag_pushback_failed to 1 if ft_vector_pushback returns NULL +static unsigned int ft_transform_int_to_unsigned( +int nbr, +t_vector *vec, +int *flag_pushback_failed) +{ + if (nbr < 0) + { + if (!ft_vector_pushback(vec, '-')) + *flag_pushback_failed = 1; + if (nbr == -2147483648) + return (2147483648); + else + return ((unsigned int) -nbr); + } + else + return ((unsigned int) nbr); +} + +//returns 1 if the base is valid, and 0 if it's not +static int ft_is_ok_base(char *base) +{ + char used_characters[128]; + size_t i; + + i = 0; + ft_bzero(used_characters, 128); + while (base[i] != '\0') + { + if (used_characters[(int) base[i]] == 0) + used_characters[(int) base[i]]++; + else + return (0); + if (ft_is_sign(base[i])) + return (0); + i++; + } + if (i < 2) + return (0); + return (1); +} + +//returns a standard C string of nbr converted in the "base" base +//base have to only cointain ascii characters +//returns NULL if the base is invalid or if an allocation failed +char *ft_itoa_base(int nbr, char *base) +{ + unsigned int unsigned_nbr; + t_vector *ret; + char *ret_str; + int flag; + + ret = ft_create_vector(2); + if (!ret) + return (NULL); + flag = 0; + if (!ft_is_ok_base(base)) + return (ft_free_vector(&ret), NULL); + unsigned_nbr = ft_transform_int_to_unsigned(nbr, ret, &flag); + if (flag) + return (ft_free_vector(&ret), NULL); + if (!ft_put_ok_base(unsigned_nbr, base, ft_strlen(base), ret)) + return (ft_free_vector(&ret), NULL); + ret_str = ft_vtoc(ret); + ft_free_vector(&ret); + if (!ret_str) + return (NULL); + return (ret_str); +} diff --git a/libft/ft_itoa_base.o b/libft/ft_itoa_base.o new file mode 100644 index 0000000..27d95a3 Binary files /dev/null and b/libft/ft_itoa_base.o differ diff --git a/libft/ft_long_utils.c b/libft/ft_long_utils.c new file mode 100644 index 0000000..fadbdf1 --- /dev/null +++ b/libft/ft_long_utils.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_long_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/30 10:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:03:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include "libft.h" + +/* + * Reimplementation of libc atol() but sets `errno` to `ERANGE` if an + * domain error is encountered (overflow, underflow) or `EINVAL` if + * no digits characters or invalid characters at end). + */ +long ft_atole(const char *nptr) +{ + long n; + long mult; + + n = 0; + mult = -1; + while (ft_isspace(*nptr)) + nptr++; + if (*nptr == '+' || *nptr == '-') + { + if (*nptr == '-') + mult = 1; + nptr++; + } + if (!ft_isdigit(*nptr)) + errno = EINVAL; + while (ft_isdigit(*nptr)) + { + n = safe_long_sub(safe_long_mul(n, 10), *nptr - '0'); + nptr++; + } + if (*nptr != '\0') + errno = EINVAL; + return (safe_long_mul(n, mult)); +} diff --git a/libft/ft_long_utils.o b/libft/ft_long_utils.o new file mode 100644 index 0000000..0941cf3 Binary files /dev/null and b/libft/ft_long_utils.o differ diff --git a/libft/ft_lstadd_back_bonus.c b/libft/ft_lstadd_back_bonus.c new file mode 100755 index 0000000..91de5f3 --- /dev/null +++ b/libft/ft_lstadd_back_bonus.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd_back_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:41:51 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new is NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstadd_back(t_list **lst, t_list *new) +{ + if (!lst || !new) + return ; + if (*lst == NULL) + *lst = new; + else + ft_lstlast(*lst)->next = new; +} diff --git a/libft/ft_lstadd_back_bonus.o b/libft/ft_lstadd_back_bonus.o new file mode 100644 index 0000000..c3a3342 Binary files /dev/null and b/libft/ft_lstadd_back_bonus.o differ diff --git a/libft/ft_lstadd_front_bonus.c b/libft/ft_lstadd_front_bonus.c new file mode 100755 index 0000000..3f2c52b --- /dev/null +++ b/libft/ft_lstadd_front_bonus.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd_front_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:04:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstadd_front(t_list **lst, t_list *new) +{ + if (!new || !lst) + return ; + new->next = *lst; + *lst = new; +} diff --git a/libft/ft_lstadd_front_bonus.o b/libft/ft_lstadd_front_bonus.o new file mode 100644 index 0000000..17a67ea Binary files /dev/null and b/libft/ft_lstadd_front_bonus.o differ diff --git a/libft/ft_lstclear_bonus.c b/libft/ft_lstclear_bonus.c new file mode 100755 index 0000000..db7312c --- /dev/null +++ b/libft/ft_lstclear_bonus.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstclear_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:00:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:54 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or del are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstclear(t_list **lst, void (*del)(void *)) +{ + t_list *next; + + if (!lst || !del) + return ; + while (*lst) + { + next = (*lst)->next; + del((*lst)->content); + free(*lst); + *lst = next; + } +} diff --git a/libft/ft_lstclear_bonus.o b/libft/ft_lstclear_bonus.o new file mode 100644 index 0000000..2272b84 Binary files /dev/null and b/libft/ft_lstclear_bonus.o differ diff --git a/libft/ft_lstdelone_bonus.c b/libft/ft_lstdelone_bonus.c new file mode 100755 index 0000000..f611101 --- /dev/null +++ b/libft/ft_lstdelone_bonus.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstdelone_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:53:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or del are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstdelone(t_list *lst, void (*del)(void *)) +{ + if (!lst || !del) + return ; + del(lst->content); + free(lst); +} diff --git a/libft/ft_lstdelone_bonus.o b/libft/ft_lstdelone_bonus.o new file mode 100644 index 0000000..6fbd1c9 Binary files /dev/null and b/libft/ft_lstdelone_bonus.o differ diff --git a/libft/ft_lstiter_bonus.c b/libft/ft_lstiter_bonus.c new file mode 100755 index 0000000..bdd0af4 --- /dev/null +++ b/libft/ft_lstiter_bonus.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstiter_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:11:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:03:57 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or f are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_lstiter(t_list *lst, void (*f)(void *)) +{ + if (!lst || !f) + return ; + while (lst->next) + { + f(lst->content); + lst = lst->next; + } + f(lst->content); +} diff --git a/libft/ft_lstiter_bonus.o b/libft/ft_lstiter_bonus.o new file mode 100644 index 0000000..a59f960 Binary files /dev/null and b/libft/ft_lstiter_bonus.o differ diff --git a/libft/ft_lstlast_bonus.c b/libft/ft_lstlast_bonus.c new file mode 100755 index 0000000..5c1ecf3 --- /dev/null +++ b/libft/ft_lstlast_bonus.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstlast_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:21:13 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:00 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if lst is NULL +t_list *ft_lstlast(t_list *lst) +{ + if (!lst) + return (NULL); + while (lst->next) + lst = lst->next; + return (lst); +} + +/* + * @return the element of `lst` at position `i`, NULL if doesn't exist. + * `ft_lstat(lst, 0)` returns `lst`. + */ +t_list *ft_lstat(t_list *lst, size_t i) +{ + size_t j; + + if (lst == NULL) + return (lst); + j = 0; + while (lst->next != NULL && j < i) + { + lst = lst->next; + j++; + } + if (j != i) + return (NULL); + return (lst); +} diff --git a/libft/ft_lstlast_bonus.o b/libft/ft_lstlast_bonus.o new file mode 100644 index 0000000..bd40def Binary files /dev/null and b/libft/ft_lstlast_bonus.o differ diff --git a/libft/ft_lstmap_bonus.c b/libft/ft_lstmap_bonus.c new file mode 100755 index 0000000..4cdb53d --- /dev/null +++ b/libft/ft_lstmap_bonus.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstmap_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 13:22:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static t_list *ft_safe_create( +void *(*f)(void *), +void (*del)(void *), +void *content) +{ + void *temp; + t_list *ret; + + temp = f(content); + if (!temp) + return (NULL); + ret = ft_lstnew(temp); + if (!ret) + { + del(temp); + return (NULL); + } + return (ret); +} + +//returns NULL without doing anything else if any argument is NULL +//returns NULL if any allocation fails +t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) +{ + t_list *new_list; + t_list *new_node; + t_list *temp; + + if (!lst || !f || !del) + return (NULL); + new_node = ft_safe_create(f, del, lst->content); + if (!new_node) + return (NULL); + new_list = new_node; + lst = lst->next; + while (lst) + { + temp = ft_safe_create(f, del, lst->content); + if (!temp) + { + ft_lstclear(&new_list, del); + return (NULL); + } + new_node->next = temp; + new_node = new_node->next; + lst = lst->next; + } + return (new_list); +} diff --git a/libft/ft_lstmap_bonus.o b/libft/ft_lstmap_bonus.o new file mode 100644 index 0000000..d222af9 Binary files /dev/null and b/libft/ft_lstmap_bonus.o differ diff --git a/libft/ft_lstnew_bonus.c b/libft/ft_lstnew_bonus.c new file mode 100755 index 0000000..d06f4b6 --- /dev/null +++ b/libft/ft_lstnew_bonus.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnew_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 11:54:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:02 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if any allocation fails +t_list *ft_lstnew(void *content) +{ + t_list *ret; + + ret = malloc(sizeof(t_list)); + if (!ret) + return (NULL); + ret->content = content; + ret->next = NULL; + return (ret); +} diff --git a/libft/ft_lstnew_bonus.o b/libft/ft_lstnew_bonus.o new file mode 100644 index 0000000..ed5ebb8 Binary files /dev/null and b/libft/ft_lstnew_bonus.o differ diff --git a/libft/ft_lstsize_bonus.c b/libft/ft_lstsize_bonus.c new file mode 100755 index 0000000..b680bd9 --- /dev/null +++ b/libft/ft_lstsize_bonus.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstsize_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/16 12:13:44 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:03 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns 0 if lst is NULL +int ft_lstsize(t_list *lst) +{ + int i; + + if (!lst) + return (0); + i = 1; + while (lst->next) + { + i++; + lst = lst->next; + } + return (i); +} diff --git a/libft/ft_lstsize_bonus.o b/libft/ft_lstsize_bonus.o new file mode 100644 index 0000000..e2d3c29 Binary files /dev/null and b/libft/ft_lstsize_bonus.o differ diff --git a/libft/ft_memchr.c b/libft/ft_memchr.c new file mode 100755 index 0000000..e2afec0 --- /dev/null +++ b/libft/ft_memchr.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:19:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:05 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memchr(const void *s, int c, size_t n) +{ + const char *str; + + str = (const char *)s; + while (n--) + { + if (*str == (char)c) + return ((void *)str); + str++; + } + return (NULL); +} diff --git a/libft/ft_memchr.o b/libft/ft_memchr.o new file mode 100644 index 0000000..413b55f Binary files /dev/null and b/libft/ft_memchr.o differ diff --git a/libft/ft_memcmp.c b/libft/ft_memcmp.c new file mode 100755 index 0000000..5c63833 --- /dev/null +++ b/libft/ft_memcmp.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:39:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:06 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *st1; + const unsigned char *st2; + + st1 = (const unsigned char *)s1; + st2 = (const unsigned char *)s2; + while (n && (*st1 == *st2)) + { + st1++; + st2++; + n--; + } + if (n == 0) + return (0); + return (*st1 - *st2); +} diff --git a/libft/ft_memcmp.o b/libft/ft_memcmp.o new file mode 100644 index 0000000..b53a705 Binary files /dev/null and b/libft/ft_memcmp.o differ diff --git a/libft/ft_memcpy.c b/libft/ft_memcpy.c new file mode 100755 index 0000000..41f71dc --- /dev/null +++ b/libft/ft_memcpy.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:52:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:07 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memcpy(void *dest, const void *src, size_t n) +{ + char *str; + unsigned long long *str_packed; + char *str_src; + unsigned long long *str_src_packed; + + str_packed = (unsigned long long *)dest; + str_src_packed = (unsigned long long *)src; + while (n >= sizeof(unsigned long long)) + { + *str_packed++ = *str_src_packed++; + n -= sizeof(unsigned long long); + } + str = (char *)str_packed; + str_src = (char *)str_src_packed; + while (n > 0) + { + *str++ = *str_src++; + n--; + } + return (dest); +} diff --git a/libft/ft_memcpy.o b/libft/ft_memcpy.o new file mode 100644 index 0000000..64422b3 Binary files /dev/null and b/libft/ft_memcpy.o differ diff --git a/libft/ft_memmove.c b/libft/ft_memmove.c new file mode 100755 index 0000000..a2b7492 --- /dev/null +++ b/libft/ft_memmove.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memmove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:00:16 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:08 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void *ft_optimised_revcpy(void *dest, const void *src, size_t n) +{ + char *str; + unsigned long long *str_packed; + char *str_src; + unsigned long long *str_src_packed; + + str = (char *)dest; + str_src = (char *)src; + while (n % sizeof(unsigned long long)) + { + n--; + str[n] = str_src[n]; + } + n /= sizeof(unsigned long long); + str_packed = (unsigned long long *)dest; + str_src_packed = (unsigned long long *)src; + while (n > 0) + { + n--; + str_packed[n] = str_src_packed[n]; + } + return (dest); +} + +void *ft_memmove(void *dest, const void *src, size_t n) +{ + char *str; + const char *str_src; + + if (!dest && !src) + return (NULL); + str = (char *)dest; + str_src = (const char *)src; + if (str > str_src) + { + if ((str + sizeof(unsigned long long)) > str_src) + return (ft_optimised_revcpy(dest, src, n)); + while (n-- > 0) + str[n] = str_src[n]; + } + else + { + ft_memcpy(dest, src, n); + } + return (dest); +} diff --git a/libft/ft_memmove.o b/libft/ft_memmove.o new file mode 100644 index 0000000..289a103 Binary files /dev/null and b/libft/ft_memmove.o differ diff --git a/libft/ft_memset.c b/libft/ft_memset.c new file mode 100755 index 0000000..e181a44 --- /dev/null +++ b/libft/ft_memset.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:40:57 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:13 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void *ft_memset(void *s, int c, size_t n) +{ + char *str; + unsigned long long *str_packed; + unsigned long long cccccccc; + size_t i; + + str = (char *)s; + while (n % sizeof(unsigned long long)) + { + *str++ = (unsigned char)c; + n--; + } + str_packed = (unsigned long long *)str; + cccccccc = 0; + i = 0; + while (i < sizeof(unsigned long long)) + { + cccccccc |= ((unsigned long long)(unsigned char)c) << (i * 8); + i++; + } + while (n >= sizeof(unsigned long long)) + { + *str_packed++ = cccccccc; + n -= sizeof(unsigned long long); + } + return (s); +} diff --git a/libft/ft_memset.o b/libft/ft_memset.o new file mode 100644 index 0000000..cab969d Binary files /dev/null and b/libft/ft_memset.o differ diff --git a/libft/ft_power.c b/libft/ft_power.c new file mode 100644 index 0000000..a3c7e2a --- /dev/null +++ b/libft/ft_power.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_power.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/07 14:57:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:15 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +ssize_t ft_power(ssize_t nb, ssize_t power) +{ + ssize_t answer; + ssize_t i; + + if (power < 0) + return (0); + if (power == 0) + return (1); + if (power % 2 == 0) + return (ft_power(nb * nb, power / 2)); + answer = nb; + i = 1; + while (i < power) + { + if ((power - i) % 2 == 0) + { + return (answer * ft_power(nb, (power - i))); + } + answer *= nb; + i++; + } + return (answer); +} diff --git a/libft/ft_power.o b/libft/ft_power.o new file mode 100644 index 0000000..598efe2 Binary files /dev/null and b/libft/ft_power.o differ diff --git a/libft/ft_printf/ft_arglist_bonus.c b/libft/ft_printf/ft_arglist_bonus.c new file mode 100755 index 0000000..c5b95a7 --- /dev/null +++ b/libft/ft_printf/ft_arglist_bonus.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_arglist_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 17:04:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:39 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +static void ft_set_default_flag_values(t_arglist *arglist) +{ + arglist->width_mini = 0; + arglist->precision = -1; + arglist->flag_hashtag = 0; + arglist->flag_zero = 0; + arglist->flag_justified_left = 0; + arglist->flag_space = 0; + arglist->flag_plus = 0; +} + +static void ft_handle_overriding_arguments(t_arglist *arglist) +{ + if ((arglist->precision >= 0) || arglist->flag_justified_left) + arglist->flag_zero = 0; + if (arglist->flag_plus) + arglist->flag_space = 0; +} + +static void ft_handle_width_precision( +t_arglist *arglist, +int *i, +const char *str, +va_list *args) +{ + if (ft_isdigit(str[*i])) + { + arglist->width_mini = ft_atoi(&str[*i], NULL); + while (ft_isdigit(str[*i])) + (*i)++; + } + else if (str[*i] == '*') + { + arglist->width_mini = va_arg(*args, int); + (*i)++; + } + if (str[*i] == '.') + { + (*i)++; + if (str[*i] == '*') + { + arglist->precision = va_arg(*args, int); + (*i)++; + } + else + arglist->precision = ft_atoi(&str[*i], NULL); + while (ft_isdigit(str[*i])) + (*i)++; + } +} + +static void ft_handle_flags(t_arglist *arglist, int *i, const char *str) +{ + while (str[*i] == '#' || str[*i] == '0' || str[*i] == '-' + || str[*i] == ' ' || str[*i] == '+') + { + if (str[*i] == '#') + arglist->flag_hashtag = 1; + if (str[*i] == '0') + arglist->flag_zero = 1; + if (str[*i] == '-') + arglist->flag_justified_left = 1; + if (str[*i] == ' ') + arglist->flag_space = 1; + if (str[*i] == '+') + arglist->flag_plus = 1; + (*i)++; + } +} + +t_arglist *ft_create_arglist(const char *str, va_list *args) +{ + t_arglist *arglist; + int i; + + arglist = malloc(sizeof(t_arglist)); + if (!arglist) + return (NULL); + ft_set_default_flag_values(arglist); + i = 0; + if (str[i] == '%') + i++; + ft_handle_flags(arglist, &i, str); + ft_handle_width_precision(arglist, &i, str, args); + arglist->size_of_argument_string = i; + ft_handle_overriding_arguments(arglist); + return (arglist); +} diff --git a/libft/ft_printf/ft_arglist_bonus.o b/libft/ft_printf/ft_arglist_bonus.o new file mode 100644 index 0000000..30bab43 Binary files /dev/null and b/libft/ft_printf/ft_arglist_bonus.o differ diff --git a/libft/ft_printf/ft_case_d_bonus.c b/libft/ft_printf/ft_case_d_bonus.c new file mode 100755 index 0000000..2f20550 --- /dev/null +++ b/libft/ft_printf/ft_case_d_bonus.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_d_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:12:38 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:44 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +char *init_str_to_cat(t_arglist *arglist, unsigned int nbr); +void convert_precision_if_flag_zero(t_arglist *arglist, int nbr); +int ft_handle_if_precision( + t_arglist *arglist, + int nbr, + t_vector *vec, + int *size); +int ft_handle_if_not_precision( + t_arglist *arglist, + int nbr, + t_vector *vec, + int *size); +int ft_handle_concat_and_padding( + t_arglist *arglist, + char *str_to_cat, + t_vector *vec, + int size); + +//flags to handle: zero, space, plus, precision, justified left... hard mode +//flag zero padding without precision behaves just like a precision +//(zeroes after the sign) and when it's spaces they're before the sign +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + int nbr; + int size; + + nbr = va_arg(*args, int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + convert_precision_if_flag_zero(arglist, nbr); + size = (int)ft_strlen(str_to_cat); + if (nbr < 0) + size--; + if ((size < arglist->precision) && (arglist->precision >= 0)) + { + if (!ft_handle_if_precision(arglist, nbr, vec, &size)) + return (free(str_to_cat), 0); + } + else + { + if (!ft_handle_if_not_precision(arglist, nbr, vec, &size)) + return (free(str_to_cat), 0); + } + if (!ft_handle_concat_and_padding(arglist, str_to_cat, vec, size)) + return (free(str_to_cat), 0); + return (free(str_to_cat), 1); +} diff --git a/libft/ft_printf/ft_case_d_bonus.o b/libft/ft_printf/ft_case_d_bonus.o new file mode 100644 index 0000000..6279b0e Binary files /dev/null and b/libft/ft_printf/ft_case_d_bonus.o differ diff --git a/libft/ft_printf/ft_case_d_utils_bonus.c b/libft/ft_printf/ft_case_d_utils_bonus.c new file mode 100755 index 0000000..2183a54 --- /dev/null +++ b/libft/ft_printf/ft_case_d_utils_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_d_utils_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 15:59:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_itoa(nbr)); +} + +void convert_precision_if_flag_zero(t_arglist *arglist, int nbr) +{ + if ((arglist->precision < 0) && !(arglist->flag_justified_left) + && arglist->flag_zero) + { + arglist->precision = arglist->width_mini; + arglist->width_mini = 0; + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + arglist->precision--; + } +} + +int ft_handle_if_precision( +t_arglist *arglist, +int nbr, +t_vector *vec, +int *size) +{ + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + { + if (padding_if_needed_before(arglist, 'd', + arglist->precision + 1, vec) < 0) + return (0); + } + else + if (padding_if_needed_before(arglist, 'd', arglist->precision, vec) < 0) + return (0); + if (arglist->flag_plus && (nbr >= 0) && !ft_vector_pushback(vec, '+')) + return (0); + if (arglist->flag_space && (nbr >= 0) && !(arglist->flag_plus) && nbr >= 0) + if (!ft_vector_pushback(vec, ' ')) + return (0); + if (nbr < 0 && !ft_vector_pushback(vec, '-')) + return (0); + while ((*size) < arglist->precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + (*size)++; + } + if (nbr < 0 || arglist->flag_plus || arglist->flag_space) + (*size)++; + return (1); +} + +int ft_handle_if_not_precision( +t_arglist *arglist, +int nbr, +t_vector *vec, +int *size) +{ + if (nbr < 0 || arglist->flag_space || arglist->flag_plus) + (*size)++; + if (padding_if_needed_before(arglist, 'd', (*size), vec) < 0) + return (0); + if (arglist->flag_plus && (nbr >= 0)) + if (!ft_vector_pushback(vec, '+')) + return (0); + if (arglist->flag_space && (nbr >= 0) && !(arglist->flag_plus)) + if (nbr >= 0) + if (!ft_vector_pushback(vec, ' ')) + return (0); + if (nbr < 0) + if (!ft_vector_pushback(vec, '-')) + return (0); + return (1); +} + +int ft_handle_concat_and_padding( +t_arglist *arglist, +char *str_to_cat, +t_vector *vec, +int size) +{ + if (!ft_vector_concat(vec, str_to_cat + ft_strnonchr(str_to_cat, '-'), + ft_strlen(str_to_cat) - ft_strnonchr(str_to_cat, '-'))) + return (0); + if (padding_if_needed_after(arglist, 'd', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_d_utils_bonus.o b/libft/ft_printf/ft_case_d_utils_bonus.o new file mode 100644 index 0000000..3d2509a Binary files /dev/null and b/libft/ft_printf/ft_case_d_utils_bonus.o differ diff --git a/libft/ft_printf/ft_case_lowx_bonus.c b/libft/ft_printf/ft_case_lowx_bonus.c new file mode 100644 index 0000000..319b480 --- /dev/null +++ b/libft/ft_printf/ft_case_lowx_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_lowx_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:09:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:46 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int handle_hashtag_prefix( +t_vector *vec, +t_arglist *arglist, +unsigned int nbr, +int flag_zero) +{ + if (arglist->flag_hashtag && !flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + } + return (1); +} + +static int apply_precision_padding(t_vector *vec, size_t *size, int precision) +{ + while ((int)(*size)++ < precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + (*size)--; + return (1); +} + +static char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_utoa_base(nbr, "0123456789abcdef")); +} + +static int handle_padding_and_prefix( +t_vector *vec, +t_arglist *arglist, +size_t size, +unsigned int nbr) +{ + if (arglist->flag_hashtag && arglist->flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + } + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (padding_if_needed_before(arglist, 'x', arglist->precision + + (arglist->flag_hashtag * 2 * (nbr != 0)), vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + else + { + if (arglist->flag_hashtag && nbr != 0) + size += 2; + if (padding_if_needed_before(arglist, 'x', size, vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + return (1); +} + +int ft_case_x_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + size_t size; + unsigned int nbr; + + nbr = va_arg(*args, unsigned int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + size = ft_strlen(str_to_cat); + if (!handle_padding_and_prefix(vec, arglist, size, nbr)) + return (free(str_to_cat), 0); + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (!apply_precision_padding(vec, &size, arglist->precision)) + return (free(str_to_cat), 0); + } + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + if (padding_if_needed_after(arglist, 'x', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_lowx_bonus.o b/libft/ft_printf/ft_case_lowx_bonus.o new file mode 100644 index 0000000..da2334a Binary files /dev/null and b/libft/ft_printf/ft_case_lowx_bonus.o differ diff --git a/libft/ft_printf/ft_case_p_bonus.c b/libft/ft_printf/ft_case_p_bonus.c new file mode 100755 index 0000000..65beaeb --- /dev/null +++ b/libft/ft_printf/ft_case_p_bonus.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_p_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 16:22:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +//zero and precision flags have undefined behavior here +int ft_case_p_bonus_utils(t_vector *vec, char *str_to_cat, t_arglist *arglist) +{ + size_t index; + size_t size; + + index = ft_strnonchr(str_to_cat, '0'); + size = ft_strlen(str_to_cat + index); + if (padding_if_needed_before(arglist, 'p', (size + 2), vec) < 0) + return (0); + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + if (!ft_vector_concat(vec, (str_to_cat + index), size)) + return (0); + if (padding_if_needed_after(arglist, 'p', (size + 2), vec) < 0) + return (0); + return (1); +} + +//zero and precision flags have undefined behavior here +int ft_case_p_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + void *arg; + int ret; + + arg = va_arg(*args, void *); + if (!arg) + { + if (padding_if_needed_before(arglist, 'p', 5, vec) < 0) + return (0); + if (!ft_vector_concat(vec, "(nil)", 5)) + return (0); + if (padding_if_needed_after(arglist, 'p', 5, vec) < 0) + return (0); + return (1); + } + str_to_cat = ft_addr_to_strhex(arg); + if (!str_to_cat) + return (0); + ret = ft_case_p_bonus_utils(vec, str_to_cat, arglist); + return (free(str_to_cat), ret); +} diff --git a/libft/ft_printf/ft_case_p_bonus.o b/libft/ft_printf/ft_case_p_bonus.o new file mode 100644 index 0000000..eac4b27 Binary files /dev/null and b/libft/ft_printf/ft_case_p_bonus.o differ diff --git a/libft/ft_printf/ft_case_s_bonus.c b/libft/ft_printf/ft_case_s_bonus.c new file mode 100755 index 0000000..964a6a0 --- /dev/null +++ b/libft/ft_printf/ft_case_s_bonus.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_s_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:03:40 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int ft_s_sub_bonus(t_vector *vec, char *str_to_cat, t_arglist *arglist) +{ + size_t size; + + if (!str_to_cat) + { + size = 6; + if ((int)size > arglist->precision && (arglist->precision >= 0)) + size = 0; + if (padding_if_needed_before(arglist, 's', size, vec) < 0) + return (0); + if (!ft_vector_concat(vec, "(null)", size)) + return (0); + } + else + { + size = ft_strlen(str_to_cat); + if ((int)size > arglist->precision && (arglist->precision >= 0)) + size = arglist->precision; + if (padding_if_needed_before(arglist, 's', size, vec) < 0) + return (0); + if (!ft_vector_concat(vec, str_to_cat, size)) + return (0); + } + if (padding_if_needed_after(arglist, 's', size, vec) < 0) + return (0); + return (1); +} + +//flag 0 has undefined behavior with c so the minimum width has to be spaces +int ft_case_s_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + + str_to_cat = va_arg(*args, char *); + return (ft_s_sub_bonus(vec, str_to_cat, arglist)); +} diff --git a/libft/ft_printf/ft_case_s_bonus.o b/libft/ft_printf/ft_case_s_bonus.o new file mode 100644 index 0000000..e230e83 Binary files /dev/null and b/libft/ft_printf/ft_case_s_bonus.o differ diff --git a/libft/ft_printf/ft_case_u_bonus.c b/libft/ft_printf/ft_case_u_bonus.c new file mode 100755 index 0000000..2e6ce15 --- /dev/null +++ b/libft/ft_printf/ft_case_u_bonus.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_u_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:07:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:49 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int ft_handle_padding_precision_bonus( +t_vector *vec, +size_t size, +t_arglist *arglist, +int padding_length) +{ + if (padding_if_needed_before(arglist, 'u', padding_length, vec) < 0) + return (0); + while ((int)size++ < arglist->precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + size--; + return (1); +} + +// Plus and space flags have undefined behavior here +int ft_case_u_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + int size; + unsigned int nbr; + int padding_length; + + nbr = va_arg(*args, unsigned int); + if (nbr == 0 && arglist->precision == 0) + str_to_cat = ft_strdup(""); + else + str_to_cat = ft_utoa(nbr); + if (!str_to_cat) + return (0); + size = (int)ft_strlen(str_to_cat); + if (size < arglist->precision) + padding_length = arglist->precision; + else + padding_length = size; + if (!ft_handle_padding_precision_bonus(vec, size, arglist, padding_length)) + return (free(str_to_cat), 0); + if (!ft_vector_concat(vec, str_to_cat, size)) + return (free(str_to_cat), 0); + if (padding_if_needed_after(arglist, 'u', padding_length, vec) < 0) + return (free(str_to_cat), 0); + return (free(str_to_cat), 1); +} diff --git a/libft/ft_printf/ft_case_u_bonus.o b/libft/ft_printf/ft_case_u_bonus.o new file mode 100644 index 0000000..b252478 Binary files /dev/null and b/libft/ft_printf/ft_case_u_bonus.o differ diff --git a/libft/ft_printf/ft_case_uppx_bonus.c b/libft/ft_printf/ft_case_uppx_bonus.c new file mode 100644 index 0000000..51f1101 --- /dev/null +++ b/libft/ft_printf/ft_case_uppx_bonus.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_case_uppx_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/25 17:11:07 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +static int handle_hashtag_prefix( +t_vector *vec, +t_arglist *arglist, +unsigned int nbr, +int flag_zero) +{ + if (arglist->flag_hashtag && !flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0X", 2)) + return (0); + } + return (1); +} + +static int apply_precision_padding(t_vector *vec, size_t *size, int precision) +{ + while ((int)(*size)++ < precision) + { + if (!ft_vector_pushback(vec, '0')) + return (0); + } + (*size)--; + return (1); +} + +static char *init_str_to_cat(t_arglist *arglist, unsigned int nbr) +{ + if (nbr == 0 && arglist->precision == 0) + return (ft_strdup("")); + return (ft_utoa_base(nbr, "0123456789ABCDEF")); +} + +static int handle_padding_and_prefix( +t_vector *vec, +t_arglist *arglist, +size_t size, +unsigned int nbr) +{ + if (arglist->flag_hashtag && arglist->flag_zero && nbr != 0) + { + if (!ft_vector_concat(vec, "0X", 2)) + return (0); + } + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (padding_if_needed_before(arglist, 'X', arglist->precision + + (arglist->flag_hashtag * 2 * (nbr != 0)), vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + else + { + if (arglist->flag_hashtag && nbr != 0) + size += 2; + if (padding_if_needed_before(arglist, 'X', size, vec) < 0) + return (0); + if (!handle_hashtag_prefix(vec, arglist, nbr, arglist->flag_zero)) + return (0); + } + return (1); +} + +int ft_case_upperx_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + char *str_to_cat; + size_t size; + unsigned int nbr; + + nbr = va_arg(*args, unsigned int); + str_to_cat = init_str_to_cat(arglist, nbr); + if (!str_to_cat) + return (0); + size = ft_strlen(str_to_cat); + if (!handle_padding_and_prefix(vec, arglist, size, nbr)) + return (free(str_to_cat), 0); + if (((int)size < arglist->precision) && (arglist->precision >= 0)) + { + if (!apply_precision_padding(vec, &size, arglist->precision)) + return (free(str_to_cat), 0); + } + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + if (padding_if_needed_after(arglist, 'X', size, vec) < 0) + return (0); + return (1); +} diff --git a/libft/ft_printf/ft_case_uppx_bonus.o b/libft/ft_printf/ft_case_uppx_bonus.o new file mode 100644 index 0000000..db516be Binary files /dev/null and b/libft/ft_printf/ft_case_uppx_bonus.o differ diff --git a/libft/ft_printf/ft_cases_easy_bonus.c b/libft/ft_printf/ft_cases_easy_bonus.c new file mode 100755 index 0000000..aa05aa1 --- /dev/null +++ b/libft/ft_printf/ft_cases_easy_bonus.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_easy_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:03:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int padding_if_needed_before( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); +int padding_if_needed_after( + t_arglist *arglist, + char caller, + size_t len, + t_vector *vec); + +//flag 0 has undefined behavior with c so the minimum width has to be spaces +int ft_case_c_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + if (padding_if_needed_before(arglist, 'c', 1, vec) < 0) + return (0); + if (!ft_vector_pushback(vec, (char)va_arg(*args, int))) + return (0); + if (padding_if_needed_after(arglist, 'c', 1, vec) < 0) + return (0); + return (1); +} + +int ft_case_percent_bonus(t_vector *vec) +{ + if (!ft_vector_pushback(vec, '%')) + return (0); + return (1); +} + +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist); + +int ft_case_i_bonus(t_vector *vec, va_list *args, t_arglist *arglist) +{ + return (ft_case_d_bonus(vec, args, arglist)); +} diff --git a/libft/ft_printf/ft_cases_easy_bonus.o b/libft/ft_printf/ft_cases_easy_bonus.o new file mode 100644 index 0000000..0e1b92a Binary files /dev/null and b/libft/ft_printf/ft_cases_easy_bonus.o differ diff --git a/libft/ft_printf/ft_cases_mandatory_one.c b/libft/ft_printf/ft_cases_mandatory_one.c new file mode 100755 index 0000000..ec16fb3 --- /dev/null +++ b/libft/ft_printf/ft_cases_mandatory_one.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_mandatory_one.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:52:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_c(t_vector *vec, va_list *args) +{ + if (!ft_vector_pushback(vec, (char)va_arg(*args, int))) + return (0); + return (1); +} + +int ft_case_percent(t_vector *vec) +{ + if (!ft_vector_pushback(vec, '%')) + return (0); + return (1); +} + +int ft_case_s(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = va_arg(*args, char *); + if (!str_to_cat) + { + if (!ft_vector_concat(vec, "(null)", 6)) + return (free(str_to_cat), 0); + } + else + { + str_to_cat = ft_strdup(str_to_cat); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + } + return (1); +} + +int ft_case_p(t_vector *vec, va_list *args) +{ + char *str_to_cat; + void *arg; + size_t index; + + arg = va_arg(*args, void *); + if (!arg) + { + if (!ft_vector_concat(vec, "(nil)", 5)) + return (0); + return (1); + } + if (!ft_vector_concat(vec, "0x", 2)) + return (0); + str_to_cat = ft_addr_to_strhex(arg); + if (!str_to_cat) + return (0); + index = ft_strnonchr(str_to_cat, '0'); + if (!ft_vector_concat(vec, str_to_cat + index, + ft_strlen(str_to_cat) - index)) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_u(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa(va_arg(*args, unsigned int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} diff --git a/libft/ft_printf/ft_cases_mandatory_one.o b/libft/ft_printf/ft_cases_mandatory_one.o new file mode 100644 index 0000000..ce42158 Binary files /dev/null and b/libft/ft_printf/ft_cases_mandatory_one.o differ diff --git a/libft/ft_printf/ft_cases_mandatory_two.c b/libft/ft_printf/ft_cases_mandatory_two.c new file mode 100755 index 0000000..927e96d --- /dev/null +++ b/libft/ft_printf/ft_cases_mandatory_two.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_cases_mandatory_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:52:33 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_x(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa_base(va_arg(*args, unsigned int), "0123456789abcdef"); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_upperx(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_utoa_base(va_arg(*args, unsigned int), "0123456789ABCDEF"); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_d(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_itoa(va_arg(*args, int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} + +int ft_case_i(t_vector *vec, va_list *args) +{ + char *str_to_cat; + + str_to_cat = ft_itoa(va_arg(*args, int)); + if (!ft_vector_concat(vec, str_to_cat, ft_strlen(str_to_cat))) + return (free(str_to_cat), 0); + free(str_to_cat); + return (1); +} diff --git a/libft/ft_printf/ft_cases_mandatory_two.o b/libft/ft_printf/ft_cases_mandatory_two.o new file mode 100644 index 0000000..a99c873 Binary files /dev/null and b/libft/ft_printf/ft_cases_mandatory_two.o differ diff --git a/libft/ft_printf/ft_padding_bonus.c b/libft/ft_printf/ft_padding_bonus.c new file mode 100755 index 0000000..073593b --- /dev/null +++ b/libft/ft_printf/ft_padding_bonus.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_padding_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/27 16:54:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:59 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +//len is the len of what's already printed +//returns the number of characters writen or -1 if an error occurs. +int padding_if_needed_before(t_arglist *arglist, +char caller, +size_t len, +t_vector *vec) +{ + char padding_char; + int i; + int padding_len; + + padding_len = arglist->width_mini - (int)len; + if (padding_len <= 0) + return (0); + if (arglist->flag_justified_left) + return (0); + if ((arglist->flag_zero == 1) && caller != 'c' && caller != 's' + && caller != 'p' && (arglist->precision < 0)) + padding_char = '0'; + else + padding_char = ' '; + i = 0; + while (i++ < padding_len) + if (!ft_vector_pushback(vec, padding_char)) + return (-1); + return (padding_len); +} + +//len is the len of what's already printed +//returns the number of characters writen or -1 if an error occurs. +int padding_if_needed_after(t_arglist *arglist, +char caller, +size_t len, +t_vector *vec) +{ + int i; + int padding_len; + + (void)caller; + padding_len = arglist->width_mini - (int)len; + if (padding_len <= 0) + return (0); + if (!(arglist->flag_justified_left)) + return (0); + i = 0; + while (i++ < padding_len) + if (!ft_vector_pushback(vec, ' ')) + return (-1); + return (padding_len); +} diff --git a/libft/ft_printf/ft_padding_bonus.o b/libft/ft_printf/ft_padding_bonus.o new file mode 100644 index 0000000..aa133a1 Binary files /dev/null and b/libft/ft_printf/ft_padding_bonus.o differ diff --git a/libft/ft_printf/ft_printf.c b/libft/ft_printf/ft_printf.c new file mode 100755 index 0000000..f7dc765 --- /dev/null +++ b/libft/ft_printf/ft_printf.c @@ -0,0 +1,126 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 18:24:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:03 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" + +int ft_case_c(t_vector *vec, va_list *args); +int ft_case_percent(t_vector *vec); +int ft_case_s(t_vector *vec, va_list *args); +int ft_case_p(t_vector *vec, va_list *args); +int ft_case_u(t_vector *vec, va_list *args); +int ft_case_x(t_vector *vec, va_list *args); +int ft_case_upperx(t_vector *vec, va_list *args); +int ft_case_d(t_vector *vec, va_list *args); +int ft_case_i(t_vector *vec, va_list *args); +int handle_percent_bonus(const char *str, t_vector *vec, va_list *args); + +//properly frees the vector and return string +void ft_cleanup(t_vector **vec, va_list *args) +{ + ft_free_vector(vec); + va_end(*args); +} + +//returns the number of characters to skip after the % sign +//or 0 if something goes wrong +int handle_percent(const char *str, t_vector *vec, va_list *args) +{ + if (str[0] == '%' && str[1] == 'c') + return (ft_case_c(vec, args)); + if (str[0] == '%' && str[1] == '%') + return (ft_case_percent(vec)); + if (str[0] == '%' && str[1] == 's') + return (ft_case_s(vec, args)); + if (str[0] == '%' && str[1] == 'p') + return (ft_case_p(vec, args)); + if (str[0] == '%' && str[1] == 'u') + return (ft_case_u(vec, args)); + if (str[0] == '%' && str[1] == 'x') + return (ft_case_x(vec, args)); + if (str[0] == '%' && str[1] == 'X') + return (ft_case_upperx(vec, args)); + if (str[0] == '%' && (str[1] == 'd')) + return (ft_case_d(vec, args)); + if (str[0] == '%' && (str[1] == 'i')) + return (ft_case_i(vec, args)); + return (handle_percent_bonus(str, vec, args)); +} + +static int ft_parsing_loop( +t_vector *return_vector, +const char *str, +va_list *args +) +{ + char *next_percent; + int nb_character; + + while (*str) + { + next_percent = ft_strchr(str, '%'); + if (!next_percent) + { + next_percent = ft_strchr(str, '\0'); + if (!ft_vector_concat(return_vector, str, (next_percent - str))) + return (0); + return (1); + } + if (!ft_vector_concat(return_vector, str, (next_percent - str))) + return (0); + str = next_percent; + nb_character = handle_percent(str, return_vector, args); + if (!nb_character) + return (0); + str += nb_character; + str++; + } + return (1); +} + +//returns the number of characters written or -1 on errors +int ft_printf(const char *str, ...) +{ + int nb_character; + t_vector *return_vector; + va_list args; + + if (!str) + return (-1); + va_start(args, str); + return_vector = ft_create_vector(2); + if (!return_vector) + return (-1); + if (!ft_parsing_loop(return_vector, str, &args)) + return (ft_cleanup(&return_vector, &args), -1); + nb_character = write(1, return_vector->buffer, return_vector->index); + return (ft_cleanup(&return_vector, &args), nb_character); +} + +//returns the number of characters written or -1 on errors +int ft_dprintf(int fd, const char *str, ...) +{ + int nb_character; + t_vector *return_vector; + va_list args; + + if (!str) + return (-1); + va_start(args, str); + return_vector = ft_create_vector(2); + if (!return_vector) + return (-1); + if (!ft_parsing_loop(return_vector, str, &args)) + return (ft_cleanup(&return_vector, &args), -1); + nb_character = write(fd, return_vector->buffer, return_vector->index); + return (ft_cleanup(&return_vector, &args), nb_character); +} diff --git a/libft/ft_printf/ft_printf.h b/libft/ft_printf/ft_printf.h new file mode 100755 index 0000000..9928f16 --- /dev/null +++ b/libft/ft_printf/ft_printf.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:20 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_H +# define FT_PRINTF_H + +# include +# include "../ft_vector.h" + +int ft_printf(const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); + +#endif diff --git a/libft/ft_printf/ft_printf.o b/libft/ft_printf/ft_printf.o new file mode 100644 index 0000000..0bb0fea Binary files /dev/null and b/libft/ft_printf/ft_printf.o differ diff --git a/libft/ft_printf/ft_printf_bonus.c b/libft/ft_printf/ft_printf_bonus.c new file mode 100755 index 0000000..f48dee4 --- /dev/null +++ b/libft/ft_printf/ft_printf_bonus.c @@ -0,0 +1,139 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 12:55:41 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:00 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../libft.h" +#include "ft_printf.h" +#include "ft_printf_bonus.h" + +int ft_case_c_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_percent_bonus(t_vector *vec); +int ft_case_s_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_p_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_u_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_x_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_upperx_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_d_bonus(t_vector *vec, va_list *args, t_arglist *arglist); +int ft_case_i_bonus(t_vector *vec, va_list *args, t_arglist *arglist); + +static int ft_handle_percent_bonus_i( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 'i') + { + if (ft_case_i_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (free(arglist), 0); +} + +static int ft_handle_percent_bonus_xd( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 'x') + { + if (ft_case_x_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'X') + { + if (ft_case_upperx_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'd') + { + if (ft_case_d_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_i(str, vec, args, arglist)); +} + +static int ft_handle_percent_bonus_spu( +const char *str, +t_vector *vec, +va_list *args, +t_arglist *arglist) +{ + int offset; + + offset = arglist->size_of_argument_string; + if (str[0] == 's') + { + if (ft_case_s_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'p') + { + if (ft_case_p_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == 'u') + { + if (ft_case_u_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_xd(str, vec, args, arglist)); +} + +//returns the number of characters to skip after the % sign +//or 0 if something goes wrong +int handle_percent_bonus(const char *str, t_vector *vec, va_list *args) +{ + t_arglist *arglist; + int offset; + + arglist = ft_create_arglist(str, args); + if (!arglist) + return (0); + offset = arglist->size_of_argument_string; + str += offset; + if (str[0] == 'c') + { + if (ft_case_c_bonus(vec, args, arglist)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + if (str[0] == '%') + { + if (ft_case_percent_bonus(vec)) + return (free(arglist), offset); + else + return (free(arglist), 0); + } + return (ft_handle_percent_bonus_spu(str, vec, args, arglist)); +} diff --git a/libft/ft_printf/ft_printf_bonus.h b/libft/ft_printf/ft_printf_bonus.h new file mode 100755 index 0000000..a041aec --- /dev/null +++ b/libft/ft_printf/ft_printf_bonus.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf_bonus.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:04:14 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRINTF_BONUS_H +# define FT_PRINTF_BONUS_H + +typedef struct s_arglist +{ + int width_mini; + int precision; + int flag_hashtag; + int flag_zero; + int flag_justified_left; + int flag_space; + int flag_plus; + int size_of_argument_string; +} t_arglist; + +t_arglist *ft_create_arglist(const char *str, va_list *args); + +#endif \ No newline at end of file diff --git a/libft/ft_printf/ft_printf_bonus.o b/libft/ft_printf/ft_printf_bonus.o new file mode 100644 index 0000000..35668a3 Binary files /dev/null and b/libft/ft_printf/ft_printf_bonus.o differ diff --git a/libft/ft_printf/libft.h b/libft/ft_printf/libft.h new file mode 100755 index 0000000..7805aa4 --- /dev/null +++ b/libft/ft_printf/libft.h @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:08:22 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIBFT_H +# define LIBFT_H + +# include +# include +# include + +int ft_isalpha(int c); +int ft_isdigit(int c); +int ft_isalnum(int c); +int ft_isascii(int c); +int ft_isprint(int c); +size_t ft_strlen(const char *s); +void *ft_memset(void *s, int c, size_t n); +void ft_bzero(void *s, size_t n); +void *ft_memcpy(void *dest, const void *src, size_t n); +void *ft_memmove(void *dest, const void *src, size_t n); +size_t ft_strlcpy(char *dst, const char *src, size_t size); +size_t ft_strlcat(char *dst, const char *src, size_t size); +int ft_toupper(int c); +int ft_tolower(int c); +char *ft_strchr(const char *s, int c); +char *ft_strrchr(const char *s, int c); +int ft_strncmp(const char *s1, const char *s2, size_t n); +void *ft_memchr(const void *s, int c, size_t n); +int ft_memcmp(const void *s1, const void *s2, size_t n); +char *ft_strnstr(const char *big, const char *little, size_t len); +int ft_atoi(const char *nptr); +char *ft_strdup(const char *s); +char *ft_itoa(int n); +char *ft_itoa_base(int nbr, char *base); +char *ft_addr_to_strhex(void *addr); +char *ft_utoa(unsigned int n); +char *ft_utoa_base(unsigned int nbr, char *base); +size_t ft_strnonchr(char *str, char c); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue.h b/libft/ft_priority_queue.h new file mode 100755 index 0000000..9b7047b --- /dev/null +++ b/libft/ft_priority_queue.h @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 14:51:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRIORITY_QUEUE_H +# define FT_PRIORITY_QUEUE_H + +# include "libft.h" + +typedef struct s_priority_queue_node +{ + void *data; + size_t priority; +} t_priority_queue_node; + +typedef struct s_priority_queue +{ + t_priority_queue_node *nodes; + size_t size; + size_t capacity; + int (*compare)(void *, void *); +} t_priority_queue; + +void ft_insert_pq( + t_priority_queue *pq, + void *data, + size_t priority); + +t_priority_queue *create_priority_queue( + int capacity, + int (*compare)(void *, void *)); + +void *peek(t_priority_queue *pq); + +void *dequeue(t_priority_queue *pq); + +void free_pq(t_priority_queue *pq); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue/ft_priority_queue.c b/libft/ft_priority_queue/ft_priority_queue.c new file mode 100755 index 0000000..97b2f54 --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 14:51:23 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:06 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_priority_queue_private.h" + +void ft_insert_pq(t_priority_queue *pq, void *data, size_t priority) +{ + t_priority_queue_node new_node; + + if (pq->size >= pq->capacity) + ft_resize_pq(pq); + new_node.data = data; + new_node.priority = priority; + pq->nodes[pq->size] = new_node; + pq->size++; + heapify_up(pq, pq->size - 1); +} + +t_priority_queue *create_priority_queue( +int capacity, +int (*compare)(void *, void *)) +{ + t_priority_queue *pq; + + pq = malloc(sizeof(t_priority_queue)); + if (!pq) + return (NULL); + pq->nodes = malloc(capacity * sizeof(t_priority_queue_node)); + if (!pq->nodes) + return (free(pq), NULL); + pq->size = 0; + pq->capacity = capacity; + pq->compare = compare; + return (pq); +} + +void *peek(t_priority_queue *pq) +{ + if (pq->size == 0) + return (NULL); + return (pq->nodes[0].data); +} + +void *dequeue(t_priority_queue *pq) +{ + void *ret; + + if (pq->size == 0) + return (NULL); + ret = pq->nodes[0].data; + pq->nodes[0] = pq->nodes[pq->size - 1]; + pq->size--; + heapify_down(pq, 0); + ft_shrink_pq(pq); + return (ret); +} + +void free_pq(t_priority_queue *pq) +{ + free(pq->nodes); + free(pq); +} diff --git a/libft/ft_priority_queue/ft_priority_queue.o b/libft/ft_priority_queue/ft_priority_queue.o new file mode 100644 index 0000000..70459b3 Binary files /dev/null and b/libft/ft_priority_queue/ft_priority_queue.o differ diff --git a/libft/ft_priority_queue/ft_priority_queue_private.h b/libft/ft_priority_queue/ft_priority_queue_private.h new file mode 100755 index 0000000..122495e --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue_private.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 16:41:11 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:08 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_PRIORITY_QUEUE_PRIVATE_H +# define FT_PRIORITY_QUEUE_PRIVATE_H + +# include "../ft_priority_queue.h" + +void heapify_up(t_priority_queue *pq, size_t index); + +void heapify_down(t_priority_queue *pq, size_t index); + +void ft_resize_pq(t_priority_queue *pq); + +void ft_shrink_pq(t_priority_queue *pq); + +#endif \ No newline at end of file diff --git a/libft/ft_priority_queue/ft_priority_queue_utils.c b/libft/ft_priority_queue/ft_priority_queue_utils.c new file mode 100755 index 0000000..c51e00f --- /dev/null +++ b/libft/ft_priority_queue/ft_priority_queue_utils.c @@ -0,0 +1,118 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_priority_queue_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/19 16:00:58 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:07:01 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_priority_queue_private.h" +#include "../ft_printf/ft_printf.h" + +static inline void pq_swap(t_priority_queue_node *a, t_priority_queue_node *b) +{ + t_priority_queue_node temp; + + temp = *a; + *a = *b; + *b = temp; +} + +void heapify_up(t_priority_queue *pq, size_t index) +{ + size_t parent; + + while (index > 0) + { + parent = (index - 1) / 2; + if (pq->nodes[index].priority < pq->nodes[parent].priority) + { + pq_swap(&pq->nodes[index], &pq->nodes[parent]); + index = parent; + } + else if (pq->nodes[index].priority == pq->nodes[parent].priority + && pq->compare(pq->nodes[index].data, pq->nodes[parent].data) < 0) + { + pq_swap(&pq->nodes[index], &pq->nodes[parent]); + index = parent; + } + else + { + break ; + } + } +} + +void heapify_down(t_priority_queue *pq, size_t index) +{ + size_t smallest; + size_t left; + size_t right; + + smallest = index; + left = 2 * index + 1; + right = 2 * index + 2; + if (left < pq->size + && ((pq->nodes[left].priority < pq->nodes[smallest].priority) + || (pq->compare(pq->nodes[left].data, + pq->nodes[smallest].data) < 0))) + smallest = left; + if (right < pq->size + && ((pq->nodes[right].priority < pq->nodes[smallest].priority) + || (pq->compare(pq->nodes[right].data, + pq->nodes[smallest].data) < 0))) + smallest = right; + if (smallest != index) + { + pq_swap(&pq->nodes[index], &pq->nodes[smallest]); + heapify_down(pq, smallest); + } +} + +void ft_resize_pq(t_priority_queue *pq) +{ + size_t new_capacity; + t_priority_queue_node *new_nodes; + size_t i; + + new_capacity = pq->capacity * 2; + new_nodes = malloc(new_capacity * sizeof(t_priority_queue_node)); + if (!new_nodes) + return ; + i = 0; + while (i < pq->size) + { + new_nodes[i] = pq->nodes[i]; + i++; + } + free(pq->nodes); + pq->nodes = new_nodes; + pq->capacity = new_capacity; +} + +void ft_shrink_pq(t_priority_queue *pq) +{ + size_t new_capacity; + t_priority_queue_node *new_nodes; + size_t i; + + if (pq->size >= pq->capacity / 4 || pq->capacity <= 4) + return ; + new_capacity = pq->capacity / 2; + new_nodes = malloc(new_capacity * sizeof(t_priority_queue_node)); + if (!new_nodes) + return ; + i = 0; + while (i < pq->size) + { + new_nodes[i] = pq->nodes[i]; + i++; + } + free(pq->nodes); + pq->nodes = new_nodes; + pq->capacity = new_capacity; +} diff --git a/libft/ft_priority_queue/ft_priority_queue_utils.o b/libft/ft_priority_queue/ft_priority_queue_utils.o new file mode 100644 index 0000000..83c5873 Binary files /dev/null and b/libft/ft_priority_queue/ft_priority_queue_utils.o differ diff --git a/libft/ft_putchar_fd.c b/libft/ft_putchar_fd.c new file mode 100755 index 0000000..7f3b443 --- /dev/null +++ b/libft/ft_putchar_fd.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putchar_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:16:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:19 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putchar_fd(char c, int fd) +{ + write(fd, &c, 1); +} diff --git a/libft/ft_putchar_fd.o b/libft/ft_putchar_fd.o new file mode 100644 index 0000000..edd96ee Binary files /dev/null and b/libft/ft_putchar_fd.o differ diff --git a/libft/ft_putendl_fd.c b/libft/ft_putendl_fd.c new file mode 100755 index 0000000..a7cf3d6 --- /dev/null +++ b/libft/ft_putendl_fd.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putendl_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:37:39 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:21 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +void ft_putendl_fd(char *s, int fd) +{ + ft_putstr_fd(s, fd); + ft_putchar_fd('\n', fd); +} diff --git a/libft/ft_putendl_fd.o b/libft/ft_putendl_fd.o new file mode 100644 index 0000000..16f11c2 Binary files /dev/null and b/libft/ft_putendl_fd.o differ diff --git a/libft/ft_putnbr_fd.c b/libft/ft_putnbr_fd.c new file mode 100755 index 0000000..1e843ef --- /dev/null +++ b/libft/ft_putnbr_fd.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putnbr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:44:20 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:23 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static unsigned int ft_abs(int a) +{ + if (a < 0) + return (-a); + return (a); +} + +void ft_putnbr_fd(int n, int fd) +{ + if (n < 0) + ft_putchar_fd('-', fd); + if (ft_abs(n) < 10) + ft_putchar_fd(ft_abs(n) + '0', fd); + else + { + ft_putnbr_fd(ft_abs(n / 10), fd); + ft_putnbr_fd(ft_abs(n % 10), fd); + } +} diff --git a/libft/ft_putnbr_fd.o b/libft/ft_putnbr_fd.o new file mode 100644 index 0000000..281fc02 Binary files /dev/null and b/libft/ft_putnbr_fd.o differ diff --git a/libft/ft_putstr_fd.c b/libft/ft_putstr_fd.c new file mode 100755 index 0000000..b2861d5 --- /dev/null +++ b/libft/ft_putstr_fd.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putstr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 17:31:53 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:24 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if lst or new are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_putstr_fd(char *s, int fd) +{ + size_t len; + + if (!s) + return ; + len = ft_strlen(s); + write(fd, s, len); +} diff --git a/libft/ft_putstr_fd.o b/libft/ft_putstr_fd.o new file mode 100644 index 0000000..bdf05a9 Binary files /dev/null and b/libft/ft_putstr_fd.o differ diff --git a/libft/ft_safe_int_math.c b/libft/ft_safe_int_math.c new file mode 100644 index 0000000..454bb63 --- /dev/null +++ b/libft/ft_safe_int_math.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_safe_int_math.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 11:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:25 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_add(int a, int b) +{ + if (b >= 0 && a > INT_MAX - b) + { + errno = ERANGE; + return (INT_MAX); + } + else if (b < 0 && a < INT_MIN - b) + { + errno = ERANGE; + return (INT_MIN); + } + return (a + b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_sub(int a, int b) +{ + if (b >= 0 && a < INT_MIN + b) + { + errno = ERANGE; + return (INT_MIN); + } + else if (b < 0 && a > INT_MAX + b) + { + errno = ERANGE; + return (INT_MAX); + } + return (a - b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +int safe_int_mul(int a, int b) +{ + if (b > 0) + { + if (a > 0 && a > INT_MAX / b) + return (errno = ERANGE, INT_MAX); + else if (a < 0 && a < INT_MIN / b) + return (errno = ERANGE, INT_MIN); + } + else if (b < 0) + { + if (a < 0 && a < INT_MAX / b) + return (errno = ERANGE, INT_MAX); + else if ((-INT_MAX > INT_MIN && b < -1) && a > INT_MIN / b) + return (errno = ERANGE, INT_MIN); + } + return (a * b); +} diff --git a/libft/ft_safe_int_math.o b/libft/ft_safe_int_math.o new file mode 100644 index 0000000..f048b1e Binary files /dev/null and b/libft/ft_safe_int_math.o differ diff --git a/libft/ft_safe_long_math.c b/libft/ft_safe_long_math.c new file mode 100644 index 0000000..159085f --- /dev/null +++ b/libft/ft_safe_long_math.c @@ -0,0 +1,80 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_safe_long_math.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 11:11:17 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:26 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_add(long a, long b) +{ + if (b >= 0 && a > LONG_MAX - b) + { + errno = ERANGE; + return (LONG_MAX); + } + else if (b < 0 && a < LONG_MIN - b) + { + errno = ERANGE; + return (LONG_MIN); + } + return (a + b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_sub(long a, long b) +{ + if (b >= 0 && a < LONG_MIN + b) + { + errno = ERANGE; + return (LONG_MIN); + } + else if (b < 0 && a > LONG_MAX + b) + { + errno = ERANGE; + return (LONG_MAX); + } + return (a - b); +} + +/* + * Does saturate and never overflows/underflows. + * Sets `errno` to `ERANGE` if the operation would + * have caused an overflow/underflow. + */ +long safe_long_mul(long a, long b) +{ + if (b > 0) + { + if (a > 0 && a > LONG_MAX / b) + return (errno = ERANGE, LONG_MAX); + else if (a < 0 && a < LONG_MIN / b) + return (errno = ERANGE, LONG_MIN); + } + else if (b < 0) + { + if (a < 0 && a < LONG_MAX / b) + return (errno = ERANGE, LONG_MAX); + else if ((-LONG_MAX > LONG_MIN && b < -1) && a > LONG_MIN / b) + return (errno = ERANGE, LONG_MIN); + } + return (a * b); +} diff --git a/libft/ft_safe_long_math.o b/libft/ft_safe_long_math.o new file mode 100644 index 0000000..56f2f9a Binary files /dev/null and b/libft/ft_safe_long_math.o differ diff --git a/libft/ft_split.c b/libft/ft_split.c new file mode 100755 index 0000000..e8316f9 --- /dev/null +++ b/libft/ft_split.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 14:22:44 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static int free_if_failed(char **split, int index) +{ + int i; + + if (index < 0) + return (0); + if (!split) + return (1); + if (split[index]) + return (0); + i = 0; + while (split[i]) + { + free(split[i]); + i++; + } + free(split); + return (1); +} + +static int ft_count_str(const char *str, char c) +{ + int count; + int i; + int sub_str_start; + + i = 0; + count = 0; + sub_str_start = 0; + while (str[i]) + { + while (str[i] && (str[i] == c)) + i++; + sub_str_start = i; + while (str[i] && (str[i] != c)) + i++; + if (sub_str_start < i) + count++; + } + return (count); +} + +static char *ft_str_dup_range(const char *str, int start_index, int end_index) +{ + char *dup; + int i; + + dup = malloc(sizeof(char) * (end_index - start_index + 1)); + if (!dup) + return (0); + i = 0; + while (i < (end_index - start_index)) + { + dup[i] = str[start_index + i]; + i++; + } + dup[i] = '\0'; + return (dup); +} + +static void init_to_zero(int *sub_str_start, int *index_str, int *i) +{ + *sub_str_start = 0; + *index_str = 0; + *i = 0; +} + +//returns NULL if s is NULL or if any allocation fails +char **ft_split(char const *s, char c) +{ + char **tab; + int sub_str_start; + int index_str; + int i; + + if (!s) + return (NULL); + init_to_zero(&sub_str_start, &index_str, &i); + tab = malloc(sizeof(char *) * (ft_count_str(s, c) + 1)); + if (!tab) + return (NULL); + while (s[i]) + { + while (s[i] && (s[i] == c)) + i++; + sub_str_start = i; + while (s[i] && (s[i] != c)) + i++; + if (sub_str_start < i) + tab[index_str++] = ft_str_dup_range(s, sub_str_start, i); + if (free_if_failed(tab, index_str - 1)) + return (NULL); + } + tab[index_str] = 0; + return (tab); +} diff --git a/libft/ft_split.o b/libft/ft_split.o new file mode 100644 index 0000000..e00d8d3 Binary files /dev/null and b/libft/ft_split.o differ diff --git a/libft/ft_split2.c b/libft/ft_split2.c new file mode 100644 index 0000000..be33c1f --- /dev/null +++ b/libft/ft_split2.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/09 15:37:07 by alier #+# #+# */ +/* Updated: 2025/02/16 19:04:33 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include + +/* + * Free all strings duplicated by split and the pointer array itself. + * Does nothing if strs is NULL. + */ +void ft_free_split(char **strs) +{ + size_t i; + + if (strs == NULL) + return ; + i = 0; + while (strs[i] != NULL) + { + free(strs[i]); + i++; + } + free(strs); +} + +size_t ft_split_size(char **strs) +{ + size_t i; + + i = 0; + while (strs[i] != NULL) + i++; + return (i); +} diff --git a/libft/ft_split2.o b/libft/ft_split2.o new file mode 100644 index 0000000..e7b1b09 Binary files /dev/null and b/libft/ft_split2.o differ diff --git a/libft/ft_strchr.c b/libft/ft_strchr.c new file mode 100755 index 0000000..1ef18dd --- /dev/null +++ b/libft/ft_strchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:59:05 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:40 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns the index of the first character c of the string +// /!\SEGFAULT if str is NULL +//returns ft_strlen(s) if c is \0 +char *ft_strchr(const char *s, int c) +{ + if ((char)c == '\0') + return ((char *)(s + ft_strlen(s))); + while (*s) + { + if (*s == (char)c) + return ((char *) s); + s++; + } + return (NULL); +} diff --git a/libft/ft_strchr.o b/libft/ft_strchr.o new file mode 100644 index 0000000..62bcf86 Binary files /dev/null and b/libft/ft_strchr.o differ diff --git a/libft/ft_strcmp.c b/libft/ft_strcmp.c new file mode 100755 index 0000000..52be37f --- /dev/null +++ b/libft/ft_strcmp.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strcmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/08 13:50:48 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strcmp(const char *s1, const char *s2) +{ + while (*s1 && (*s1 == *s2)) + { + s1++; + s2++; + } + return ((const unsigned char)*s1 - (const unsigned char)*s2); +} diff --git a/libft/ft_strcmp.o b/libft/ft_strcmp.o new file mode 100644 index 0000000..cfa16fe Binary files /dev/null and b/libft/ft_strcmp.o differ diff --git a/libft/ft_strdup.c b/libft/ft_strdup.c new file mode 100755 index 0000000..cac2557 --- /dev/null +++ b/libft/ft_strdup.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 18:57:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:44 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strdup(const char *s) +{ + char *dup_str; + size_t size; + + if (!s) + return (NULL); + size = (ft_strlen(s) + 1); + dup_str = malloc(sizeof(char) * size); + if (!dup_str) + return (0); + return (ft_memcpy(dup_str, s, size)); +} diff --git a/libft/ft_strdup.o b/libft/ft_strdup.o new file mode 100644 index 0000000..86dc742 Binary files /dev/null and b/libft/ft_strdup.o differ diff --git a/libft/ft_striteri.c b/libft/ft_striteri.c new file mode 100755 index 0000000..73ca44b --- /dev/null +++ b/libft/ft_striteri.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_striteri.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 16:56:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns without doing anything if s or f are NULL, this is dumb because we +//can't report the error given the prototyping but I'm not taking any risk for +//my 3th retry... +void ft_striteri(char *s, void (*f)(unsigned int, char*)) +{ + unsigned int i; + + if (!s || !f) + return ; + i = 0; + while (s[i]) + { + f(i, &s[i]); + i++; + } +} diff --git a/libft/ft_striteri.o b/libft/ft_striteri.o new file mode 100644 index 0000000..c655f4a Binary files /dev/null and b/libft/ft_striteri.o differ diff --git a/libft/ft_strjoin.c b/libft/ft_strjoin.c new file mode 100755 index 0000000..972f6f2 --- /dev/null +++ b/libft/ft_strjoin.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strjoin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 12:14:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:47 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns NULL if any argument is null or if an allocation fails +char *ft_strjoin(char const *s1, char const *s2) +{ + char *ret; + int i; + int j; + + if (!s1 || !s2) + return (NULL); + ret = malloc(sizeof(char) * (ft_strlen(s1) + ft_strlen(s2) + 1)); + if (!ret) + return (NULL); + i = 0; + while (s1[i]) + { + ret[i] = s1[i]; + i++; + } + j = 0; + while (s2[j]) + { + ret[i] = s2[j]; + i++; + j++; + } + ret[i] = '\0'; + return (ret); +} diff --git a/libft/ft_strjoin.o b/libft/ft_strjoin.o new file mode 100644 index 0000000..1cf0d49 Binary files /dev/null and b/libft/ft_strjoin.o differ diff --git a/libft/ft_strlcat.c b/libft/ft_strlcat.c new file mode 100755 index 0000000..908e023 --- /dev/null +++ b/libft/ft_strlcat.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcat.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:24:30 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlcat(char *dst, const char *src, size_t size) +{ + size_t dest_len; + size_t src_len; + + dest_len = ft_strlen(dst); + src_len = ft_strlen(src); + if (size <= dest_len) + return (size + src_len); + ft_strlcpy(&dst[dest_len], src, (size - dest_len)); + return (dest_len + src_len); +} diff --git a/libft/ft_strlcat.o b/libft/ft_strlcat.o new file mode 100644 index 0000000..786f445 Binary files /dev/null and b/libft/ft_strlcat.o differ diff --git a/libft/ft_strlcpy.c b/libft/ft_strlcpy.c new file mode 100755 index 0000000..ab4245f --- /dev/null +++ b/libft/ft_strlcpy.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:13:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:51 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlcpy(char *dst, const char *src, size_t size) +{ + size_t i; + + i = 0; + if (size == 0) + return (ft_strlen(src)); + while ((*src != '\0') && (i < size - 1)) + { + *dst = *src; + i++; + dst++; + src++; + } + while (*src != '\0') + { + i++; + src++; + } + *dst = '\0'; + return (i); +} diff --git a/libft/ft_strlcpy.o b/libft/ft_strlcpy.o new file mode 100644 index 0000000..736adb1 Binary files /dev/null and b/libft/ft_strlcpy.o differ diff --git a/libft/ft_strlen.c b/libft/ft_strlen.c new file mode 100755 index 0000000..36ca40d --- /dev/null +++ b/libft/ft_strlen.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 15:19:29 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +size_t ft_strlen(const char *s) +{ + size_t i; + + i = 0; + while (s[i]) + i++; + return (i); +} diff --git a/libft/ft_strlen.o b/libft/ft_strlen.o new file mode 100644 index 0000000..98d6ae7 Binary files /dev/null and b/libft/ft_strlen.o differ diff --git a/libft/ft_strmapi.c b/libft/ft_strmapi.c new file mode 100755 index 0000000..36bb825 --- /dev/null +++ b/libft/ft_strmapi.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strmapi.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 16:38:47 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:54 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//I don't know if I have to apply the function to the ending null char... +//return NULL if any argument is NULL or if any allocation fails +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) +{ + char *ret; + unsigned int i; + + if (!s || !f) + return (NULL); + ret = malloc(sizeof(char) * (ft_strlen(s) + 1)); + if (!ret) + return (NULL); + i = 0; + while (s[i]) + { + ret[i] = f(i, s[i]); + i++; + } + ret[i] = '\0'; + return (ret); +} diff --git a/libft/ft_strmapi.o b/libft/ft_strmapi.o new file mode 100644 index 0000000..80589be Binary files /dev/null and b/libft/ft_strmapi.o differ diff --git a/libft/ft_strncmp.c b/libft/ft_strncmp.c new file mode 100755 index 0000000..9ffd1b4 --- /dev/null +++ b/libft/ft_strncmp.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strncmp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:12:52 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +int ft_strncmp(const char *s1, const char *s2, size_t n) +{ + while (n && *s1 && (*s1 == *s2)) + { + s1++; + s2++; + n--; + } + if (n == 0) + return (0); + return ((const unsigned char)*s1 - (const unsigned char)*s2); +} diff --git a/libft/ft_strncmp.o b/libft/ft_strncmp.o new file mode 100644 index 0000000..c9425c1 Binary files /dev/null and b/libft/ft_strncmp.o differ diff --git a/libft/ft_strnonchr.c b/libft/ft_strnonchr.c new file mode 100755 index 0000000..9c9abdb --- /dev/null +++ b/libft/ft_strnonchr.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnonchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 18:39:17 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:04:56 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +//returns the index of the first character that ISN'T c +// /!\SEGFAULT if str is NULL +//returns 0 if c is \0 +size_t ft_strnonchr(char *str, char c) +{ + size_t i; + + i = 0; + if (c == '\0') + return (0); + while (str[i] == c) + i++; + return (i); +} diff --git a/libft/ft_strnonchr.o b/libft/ft_strnonchr.o new file mode 100644 index 0000000..dcc7f19 Binary files /dev/null and b/libft/ft_strnonchr.o differ diff --git a/libft/ft_strnstr.c b/libft/ft_strnstr.c new file mode 100755 index 0000000..50bc7ec --- /dev/null +++ b/libft/ft_strnstr.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strnstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:50:28 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:13 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strnstr(const char *big, const char *little, size_t len) +{ + size_t i; + size_t j; + + if (*little == '\0') + return ((char *)big); + i = 0; + while (big[i] != '\0' && i < len) + { + j = 0; + while (little[j] != '\0' && big[i + j] == little[j] && (i + j) < len) + j++; + if (little[j] == '\0') + return ((char *)big + i); + i++; + } + return (NULL); +} + +int ft_strhassuffix(const char *s, const char *suffix) +{ + size_t i; + size_t j; + + i = ft_strlen(s); + j = ft_strlen(suffix); + if (i == 0 || j == 0) + return (0); + i--; + j--; + while (i > 0 && j > 0) + { + if (s[i] != suffix[j]) + return (0); + i--; + j--; + } + return (1); +} + +/* + * Same as ft_strcmp() but ignores eventual `\n` in the + * comparison. + */ +int ft_linecmp(const char *s1, const char *s2) +{ + size_t i; + const unsigned char *a; + const unsigned char *b; + + i = 0; + a = (const unsigned char *) s1; + b = (const unsigned char *) s2; + while (1) + { + if ((a[i] == '\n' && b[i] == '\0') + || (a[i] == '\0' && b[i] == '\n')) + break ; + if (a[i] != b[i]) + return (a[i] - b[i]); + if (a[i] == '\0') + break ; + i++; + } + return (0); +} + +size_t ft_linelen(const char *line) +{ + size_t i; + + i = 0; + while (line[i] != '\0' && line[i] != '\n') + i++; + return (i); +} diff --git a/libft/ft_strnstr.o b/libft/ft_strnstr.o new file mode 100644 index 0000000..04f86ac Binary files /dev/null and b/libft/ft_strnstr.o differ diff --git a/libft/ft_strrchr.c b/libft/ft_strrchr.c new file mode 100755 index 0000000..9c293ad --- /dev/null +++ b/libft/ft_strrchr.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strrchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 17:05:03 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:17 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +char *ft_strrchr(const char *s, int c) +{ + char *last_occurence; + + if ((char)c == '\0') + return ((char *)(s + ft_strlen(s))); + last_occurence = NULL; + while (*s) + { + if (*s == (char)c) + last_occurence = (char *)s; + s++; + } + return (last_occurence); +} diff --git a/libft/ft_strrchr.o b/libft/ft_strrchr.o new file mode 100644 index 0000000..55f1f2a Binary files /dev/null and b/libft/ft_strrchr.o differ diff --git a/libft/ft_strtrim.c b/libft/ft_strtrim.c new file mode 100755 index 0000000..31d5002 --- /dev/null +++ b/libft/ft_strtrim.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strtrim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 12:44:26 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:20 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t ft_str_size(char const *s1, char usedchar[256]) +{ + size_t size; + size_t index; + + size = 0; + index = 0; + while (*s1) + { + while (usedchar[((int)*s1) + 128]) + { + s1++; + index++; + } + if (*s1) + { + s1++; + index++; + size = index; + } + } + return (size); +} + +//returns NULL if any argument is null or if an allocation fails +char *ft_strtrim(char const *s1, char const *set) +{ + char *ret; + char usedchar[256]; + int start_index; + size_t size; + + if (!set || !s1) + return (NULL); + if (!*set) + return (ft_strdup(s1)); + ft_bzero(usedchar, 256); + while (*set) + usedchar[((int)*set++) + 128] = 1; + start_index = 0; + while (usedchar[((int)s1[start_index]) + 128]) + start_index++; + if (!s1[start_index]) + return (ft_strdup("")); + size = ft_str_size(&s1[start_index], usedchar); + ret = malloc(sizeof(char) * (size + 1)); + if (!ret) + return (NULL); + ft_strlcpy(ret, &s1[start_index], (size + 1)); + return (ret); +} diff --git a/libft/ft_strtrim.o b/libft/ft_strtrim.o new file mode 100644 index 0000000..358ff60 Binary files /dev/null and b/libft/ft_strtrim.o differ diff --git a/libft/ft_substr.c b/libft/ft_substr.c new file mode 100755 index 0000000..acb9dd3 --- /dev/null +++ b/libft/ft_substr.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_substr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/15 11:27:50 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:22 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static void ft_memcpy_with_nullchar(char *substring, char const *s, size_t len) +{ + ft_memcpy(substring, s, len); + substring[len] = '\0'; +} + +//check for out of bound access and return NULL if s is NULL or allocation fails +//len 0 or out of bound start just returns a null character +char *ft_substr(char const *s, unsigned int start, size_t len) +{ + char *substring; + size_t slen; + + if (!s) + return (NULL); + slen = ft_strlen(s); + if (slen <= start) + return (ft_strdup("")); + s = &s[start]; + slen -= start; + if (slen > len) + substring = malloc(sizeof(char) * (len + 1)); + else + substring = malloc(sizeof(char) * (slen + 1)); + if (!substring) + return (NULL); + if (slen > len) + ft_memcpy_with_nullchar(substring, s, len); + else + ft_memcpy_with_nullchar(substring, s, slen); + return (substring); +} diff --git a/libft/ft_substr.o b/libft/ft_substr.o new file mode 100644 index 0000000..1a9ddf8 Binary files /dev/null and b/libft/ft_substr.o differ diff --git a/libft/ft_tolower.c b/libft/ft_tolower.c new file mode 100755 index 0000000..1958947 --- /dev/null +++ b/libft/ft_tolower.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_tolower.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:44:42 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:25 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + return (c + 32); + return (c); +} diff --git a/libft/ft_tolower.o b/libft/ft_tolower.o new file mode 100644 index 0000000..7563ae8 Binary files /dev/null and b/libft/ft_tolower.o differ diff --git a/libft/ft_toupper.c b/libft/ft_toupper.c new file mode 100755 index 0000000..a1417dd --- /dev/null +++ b/libft/ft_toupper.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_toupper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 16:43:04 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:27 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +int ft_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + return (c - 32); + return (c); +} diff --git a/libft/ft_toupper.o b/libft/ft_toupper.o new file mode 100644 index 0000000..fde53a1 Binary files /dev/null and b/libft/ft_toupper.o differ diff --git a/libft/ft_utoa.c b/libft/ft_utoa.c new file mode 100755 index 0000000..83397b5 --- /dev/null +++ b/libft/ft_utoa.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_utoa.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/22 17:36:09 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:38 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +static size_t nb_digits(unsigned int n) +{ + size_t i; + + i = 0; + while (n > 0) + { + i++; + n /= 10; + } + return (i); +} + +static void recursive_utoa(unsigned int n, char *ret, size_t *index) +{ + if (n > 9) + recursive_utoa(n / 10, ret, index); + ret[(*index)++] = (n % 10) + '0'; +} + +//converts an unsigned int to a string, returns NULL if an allocation fails +//works for any size of unsigned int (future-proof) +char *ft_utoa(unsigned int n) +{ + char *ret; + size_t index; + + if (n == 0) + return (ft_strdup("0")); + ret = malloc(sizeof(char) * (nb_digits(n) + 1)); + if (!ret) + return (NULL); + index = 0; + recursive_utoa(n, ret, &index); + ret[index] = '\0'; + return (ret); +} diff --git a/libft/ft_utoa.o b/libft/ft_utoa.o new file mode 100644 index 0000000..17d5fd6 Binary files /dev/null and b/libft/ft_utoa.o differ diff --git a/libft/ft_utoa_base.c b/libft/ft_utoa_base.c new file mode 100755 index 0000000..def8dd4 --- /dev/null +++ b/libft/ft_utoa_base.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_utoa_base.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/23 13:59:32 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:36 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "ft_vector.h" + +static int ft_is_sign(char c) +{ + if (c == '-' || c == '+') + return (1); + else + return (0); +} + +//converts nbr into a known to be valid base, then append it to vec +//returns 0 if the concatenation fails, or 1 if everything goes well +static int ft_put_ok_base( +unsigned int nbr, +char *base, +size_t base_lenght, +t_vector *vec) +{ + char buffer[32]; + int i; + + i = 31; + if (nbr == 0) + if (!ft_vector_pushback(vec, base[0])) + return (0); + while (nbr > 0) + { + buffer[i] = base[nbr % base_lenght]; + nbr /= base_lenght; + i--; + } + if (!ft_vector_concat(vec, (buffer + i + 1), (31 - i))) + return (0); + return (1); +} + +//returns 1 if the base is valid, and 0 if it's not +static int ft_is_ok_base(char *base) +{ + char used_characters[128]; + size_t i; + + i = 0; + ft_bzero(used_characters, 128); + while (base[i] != '\0') + { + if (used_characters[(int) base[i]] == 0) + used_characters[(int) base[i]]++; + else + return (0); + if (ft_is_sign(base[i])) + return (0); + i++; + } + if (i < 2) + return (0); + return (1); +} + +//returns a standard C string of nbr converted in the "base" base +//base have to only cointain ascii characters +//returns NULL if the base is invalid or if an allocation failed +char *ft_utoa_base(unsigned int unsigned_nbr, char *base) +{ + t_vector *ret; + char *ret_str; + + ret = ft_create_vector(2); + if (!ret) + return (NULL); + if (!ft_is_ok_base(base)) + return (ft_free_vector(&ret), NULL); + if (!ft_put_ok_base(unsigned_nbr, base, ft_strlen(base), ret)) + return (ft_free_vector(&ret), NULL); + ret_str = ft_vtoc(ret); + ft_free_vector(&ret); + if (!ret_str) + return (NULL); + return (ret_str); +} diff --git a/libft/ft_utoa_base.o b/libft/ft_utoa_base.o new file mode 100644 index 0000000..5d43c5d Binary files /dev/null and b/libft/ft_utoa_base.o differ diff --git a/libft/ft_vecint.c b/libft/ft_vecint.c new file mode 100755 index 0000000..53c0df5 --- /dev/null +++ b/libft/ft_vecint.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vecint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 11:14:16 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:45 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_vecint.h" +#include "libft.h" + +//creates a vector of initial size size +//returns its address, or NULL if any allocations fails +t_vecint *ft_create_vecint(size_t size) +{ + t_vecint *ret; + + ret = malloc(sizeof(t_vecint)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(int) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append c to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +t_vecint *ft_vecint_pushback(t_vecint *dest, int c) +{ + int *buff; + + if (dest->index >= dest->size) + { + buff = malloc(sizeof(int) * ((dest->size + 1) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, (dest->index * sizeof(int))); + dest->size = (dest->size + 1) * 2; + free(dest->buffer); + dest->buffer = buff; + } + dest->buffer[dest->index] = c; + dest->index++; + return (dest); +} + +//append size ints (NOT BYTES) at src to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +//returns NULL if dest or src is NULL without doing anything +t_vecint *ft_vecint_concat(t_vecint *dest, const void *src, size_t size) +{ + int *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(int) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, (dest->index * sizeof(int))); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, (size * sizeof(int))); + dest->index += size; + return (dest); +} + +//frees vec and all its members, sets vec to NULL and returns NULL +void ft_free_vecint(t_vecint **vec) +{ + if (!vec) + return ; + if (!(*vec)) + return ; + if ((*vec)->buffer) + free((*vec)->buffer); + free(*vec); + *vec = NULL; +} diff --git a/libft/ft_vecint.h b/libft/ft_vecint.h new file mode 100755 index 0000000..6873dde --- /dev/null +++ b/libft/ft_vecint.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vecint.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 11:12:31 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:48 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_VECINT_H +# define FT_VECINT_H + +# include + +typedef struct s_vecint +{ + int *buffer; + size_t index; + size_t size; + char finished; +} t_vecint; + +t_vecint *ft_vecint_concat(t_vecint *dest, const void *src, size_t size); +t_vecint *ft_create_vecint(size_t size); +void ft_free_vecint(t_vecint **vec); +t_vecint *ft_vecint_pushback(t_vecint *dest, int c); + +#endif \ No newline at end of file diff --git a/libft/ft_vecint.o b/libft/ft_vecint.o new file mode 100644 index 0000000..313f19b Binary files /dev/null and b/libft/ft_vecint.o differ diff --git a/libft/ft_vector.c b/libft/ft_vector.c new file mode 100755 index 0000000..a6a9ef1 --- /dev/null +++ b/libft/ft_vector.c @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vector.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 17:45:12 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_vector.h" +#include "libft.h" + +//creates a vector of initial size size +//returns its address, or NULL if any allocations fails +t_vector *ft_create_vector(size_t size) +{ + t_vector *ret; + + ret = malloc(sizeof(t_vector)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(char) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append c to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +t_vector *ft_vector_pushback(t_vector *dest, char c) +{ + char *buff; + + if (dest->index >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + 1) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + 1) * 2; + free(dest->buffer); + dest->buffer = buff; + } + dest->buffer[dest->index] = c; + dest->index++; + return (dest); +} + +//append size bytes at src to the vector dest +//returns NULL if the allocation fail and the adress of dest if all goes well +//returns NULL if dest or src is NULL without doing anything +t_vector *ft_vector_concat(t_vector *dest, const void *src, size_t size) +{ + char *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, size); + dest->index += size; + return (dest); +} + +//duplicates the content of a vector into an appropriately sized string +//returns NULL if allocation fails or if vec or vec->buffer is NULL +char *ft_vtoc(t_vector *vec) +{ + char *ret; + + if (!vec) + return (NULL); + if (!vec->buffer) + return (NULL); + ret = malloc(sizeof(char) * (vec->index + 1)); + if (!ret) + return (NULL); + ft_memcpy(ret, vec->buffer, vec->index); + ret[vec->index] = '\0'; + return (ret); +} + +//frees vec and all its members, sets vec to NULL and returns NULL +void ft_free_vector(t_vector **vec) +{ + if (!vec) + return ; + if (!(*vec)) + return ; + if ((*vec)->buffer) + free((*vec)->buffer); + free(*vec); + *vec = NULL; +} diff --git a/libft/ft_vector.h b/libft/ft_vector.h new file mode 100755 index 0000000..142d684 --- /dev/null +++ b/libft/ft_vector.h @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_vector.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/21 17:45:45 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:50 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_VECTOR_H +# define FT_VECTOR_H + +# include + +typedef struct s_vector +{ + char *buffer; + size_t index; + size_t size; + char finished; +} t_vector; + +t_vector *ft_vector_concat(t_vector *dest, const void *src, size_t size); +char *ft_vtoc(t_vector *vec); +t_vector *ft_create_vector(size_t size); +void ft_free_vector(t_vector **vec); +t_vector *ft_vector_pushback(t_vector *dest, char c); + +#endif diff --git a/libft/ft_vector.o b/libft/ft_vector.o new file mode 100644 index 0000000..7dd3788 Binary files /dev/null and b/libft/ft_vector.o differ diff --git a/libft/get_next_line/get_next_line.c b/libft/get_next_line/get_next_line.c new file mode 100755 index 0000000..e65b9e6 --- /dev/null +++ b/libft/get_next_line/get_next_line.c @@ -0,0 +1,186 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:41 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:56 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +char *ft_read( + int fd, + t_gnl_list *node, + t_gnl_vector *vec, + t_gnl_list **node_before); +t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret); +char *ft_read_return( + t_gnl_vector *vec, + t_gnl_list *node_to_free, + t_gnl_list **node_before, + int return_null_flag); +t_gnl_list *ft_gnl_create_bufflist(int fd); +void *ft_gnl_free_list(t_gnl_list **buff_list); +t_gnl_vector *ft_gnl_create_vector(size_t size); +char *ft_gnl_vtoc(t_gnl_vector *vec); +t_gnl_vector *ft_gnl_vector_concat( + t_gnl_vector *dest, + void *src, + size_t size); + +t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret) +{ + t_gnl_vector *temp; + size_t initial_index; + + if (!ret) + ret = ft_gnl_create_vector(2); + if (!ret) + return (NULL); + initial_index = node->index; + while ((node->index < (size_t)node->nb_chars) + && (node->buffer[node->index] != '\n')) + node->index++; + if (node->index < (size_t)node->nb_chars) + { + node->index++; + ret->finished = 1; + } + temp = ft_gnl_vector_concat(ret, &node->buffer[initial_index], + (node->index - initial_index)); + if (!temp) + { + if (ret->buffer) + free(ret->buffer); + free(ret); + } + return (temp); +} + +char *ft_read_return( +t_gnl_vector *vec, +t_gnl_list *node_to_free, +t_gnl_list **node_before, +int return_null_flag) +{ + char *ret; + t_gnl_list *next_node; + + ret = NULL; + if (!return_null_flag) + ret = ft_gnl_vtoc(vec); + if (vec) + { + if (vec->buffer) + free(vec->buffer); + free(vec); + } + if (node_to_free) + { + next_node = node_to_free->next; + if (*node_before != node_to_free) + (*node_before)->next = next_node; + if (node_to_free->buffer) + free(node_to_free->buffer); + free(node_to_free); + if (*node_before == node_to_free) + *node_before = next_node; + } + return (ret); +} + +//vec must be initialized to NULL or it will cause a segfault +char *ft_read( +int fd, +t_gnl_list *node, +t_gnl_vector *vec, +t_gnl_list **node_before) +{ + if (node->index < (size_t)node->nb_chars) + { + vec = ft_read_buffer(node, vec); + if (!vec) + return (ft_read_return(vec, node, node_before, 1)); + if (vec->finished == 1) + return (ft_read_return(vec, NULL, NULL, 0)); + } + while (node->index >= (size_t)node->nb_chars) + { + node->index = 0; + node->nb_chars = read(fd, node->buffer, BUFFER_SIZE); + if (node->nb_chars == 0) + return (ft_read_return(vec, node, node_before, 0)); + if (node->nb_chars < 0) + return (ft_read_return(vec, node, node_before, 1)); + vec = ft_read_buffer(node, vec); + if (!vec) + return (ft_read_return(vec, node, node_before, 1)); + if (vec->finished == 1) + return (ft_read_return(vec, NULL, NULL, 0)); + } + return (ft_read_return(vec, NULL, NULL, 0)); +} + +//returns the node having fd as its fd member +//node_before set to the previous node +//if no node is found, the last node is returned +//if we return the first node, flag is set and node_before = current_node +t_gnl_list *ft_get_current_node( +t_gnl_list *start_node, +int fd, +int *first_node_flag, +t_gnl_list **node_before) +{ + t_gnl_list *current_node; + + current_node = start_node; + *first_node_flag = 1; + *node_before = current_node; + while (current_node->next) + { + if (current_node->fd == fd) + break ; + *first_node_flag = 0; + *node_before = current_node; + current_node = current_node->next; + } + if (current_node->fd != fd) + { + current_node->next = ft_gnl_create_bufflist(fd); + if (!(current_node->next)) + return (NULL); + *first_node_flag = 0; + *node_before = current_node; + current_node = current_node->next; + } + return (current_node); +} + +char *get_next_line(int fd) +{ + static t_gnl_list *buff_list = NULL; + t_gnl_list *current_node; + t_gnl_list *previous_node; + t_gnl_vector *vec; + int flag; + + if (fd < 0) + return (NULL); + if (!buff_list) + buff_list = ft_gnl_create_bufflist(fd); + if (!buff_list) + return (NULL); + flag = 0; + current_node = ft_get_current_node(buff_list, fd, &flag, &previous_node); + if (!current_node) + return (NULL); + vec = NULL; + if (flag) + return (ft_read(fd, current_node, vec, &buff_list)); + else + return (ft_read(fd, current_node, vec, &previous_node)); +} diff --git a/libft/get_next_line/get_next_line.h b/libft/get_next_line/get_next_line.h new file mode 100755 index 0000000..8029200 --- /dev/null +++ b/libft/get_next_line/get_next_line.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:34 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:58 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 512 +# endif + +# include +# include + +typedef struct s_gnl_list +{ + char *buffer; + size_t index; + ssize_t nb_chars; + int fd; + struct s_gnl_list *next; +} t_gnl_list; + +typedef struct s_gnl_vector +{ + char *buffer; + size_t index; + size_t size; + char finished; +} t_gnl_vector; + +char *get_next_line(int fd); +void gnl_cleanup_fd(int fd); + +#endif diff --git a/libft/get_next_line/get_next_line.o b/libft/get_next_line/get_next_line.o new file mode 100644 index 0000000..d082d41 Binary files /dev/null and b/libft/get_next_line/get_next_line.o differ diff --git a/libft/get_next_line/get_next_line_utils.c b/libft/get_next_line/get_next_line_utils.c new file mode 100755 index 0000000..c5d934f --- /dev/null +++ b/libft/get_next_line/get_next_line_utils.c @@ -0,0 +1,97 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/17 16:43:37 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:55 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" +#include "../libft.h" + +//allocates and returns a new t_list node, setting next as NULL, allocates +//BUFFER_SIZE bytes for the buffer. returns NULL if any allocation fails +//index is set to BUFFER_SIZE and nb_chars to 0 +t_gnl_list *ft_gnl_create_bufflist(int fd) +{ + t_gnl_list *list; + + list = malloc(sizeof(t_gnl_list)); + if (!list) + return (NULL); + list->buffer = malloc(sizeof(char) * BUFFER_SIZE); + if (!list->buffer) + return (free(list), NULL); + list->fd = fd; + list->index = BUFFER_SIZE; + list->nb_chars = 0; + list->next = NULL; + return (list); +} + +t_gnl_vector *ft_gnl_create_vector(size_t size) +{ + t_gnl_vector *ret; + + ret = malloc(sizeof(t_gnl_vector)); + if (!ret) + return (NULL); + ret->buffer = malloc(sizeof(char) * size); + if (!ret->buffer) + { + free(ret); + return (NULL); + } + ret->index = 0; + ret->size = size; + ret->finished = 0; + return (ret); +} + +//append size bytes at src to the vector dest +//returns NULL if the allocation fail or dest otherwise +t_gnl_vector *ft_gnl_vector_concat( +t_gnl_vector *dest, +void *src, +size_t size) +{ + char *buff; + + if (!dest || !src) + return (NULL); + if ((dest->index + size) >= dest->size) + { + buff = malloc(sizeof(char) * ((dest->size + size) * 2)); + if (!buff) + return (NULL); + ft_memcpy(buff, dest->buffer, dest->index); + dest->size = (dest->size + size) * 2; + free(dest->buffer); + dest->buffer = buff; + } + ft_memcpy(dest->buffer + dest->index, src, size); + dest->index += size; + return (dest); +} + +//duplicates the content of a vector into an appropriately sized string +//returns NULL if allocation fails or vec is NULL, or vec->buffer is NULL +char *ft_gnl_vtoc(t_gnl_vector *vec) +{ + char *ret; + + if (!vec) + return (NULL); + if (!vec->buffer) + return (NULL); + ret = malloc(sizeof(char) * (vec->index + 1)); + if (!ret) + return (NULL); + ft_memcpy(ret, vec->buffer, vec->index); + ret[vec->index] = '\0'; + return (ret); +} diff --git a/libft/get_next_line/get_next_line_utils.o b/libft/get_next_line/get_next_line_utils.o new file mode 100644 index 0000000..4867aa1 Binary files /dev/null and b/libft/get_next_line/get_next_line_utils.o differ diff --git a/libft/get_next_line/get_next_line_utils_two.c b/libft/get_next_line/get_next_line_utils_two.c new file mode 100644 index 0000000..8d21018 --- /dev/null +++ b/libft/get_next_line/get_next_line_utils_two.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils_two.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/05 13:19:35 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:06:52 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +void gnl_cleanup_fd(int fd) +{ + char *wtf; + + close(fd); + wtf = get_next_line(fd); + while (wtf) + { + free(wtf); + wtf = get_next_line(fd); + } +} diff --git a/libft/get_next_line/get_next_line_utils_two.o b/libft/get_next_line/get_next_line_utils_two.o new file mode 100644 index 0000000..24e5570 Binary files /dev/null and b/libft/get_next_line/get_next_line_utils_two.o differ diff --git a/libft/libft.a b/libft/libft.a new file mode 100644 index 0000000..bcbe298 Binary files /dev/null and b/libft/libft.a differ diff --git a/libft/libft.h b/libft/libft.h new file mode 100755 index 0000000..3ccf46e --- /dev/null +++ b/libft/libft.h @@ -0,0 +1,108 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/14 12:38:59 by thrieg #+# #+# */ +/* Updated: 2025/02/16 19:05:53 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIBFT_H +# define LIBFT_H + +# include +# include +# include + +int ft_isalpha(int c); +int ft_isdigit(int c); +int ft_isalnum(int c); +int ft_isascii(int c); +int ft_isprint(int c); +size_t ft_strlen(const char *s); +void *ft_memset(void *s, int c, size_t n); +void ft_bzero(void *s, size_t n); +void *ft_memcpy(void *dest, const void *src, size_t n); +void *ft_memmove(void *dest, const void *src, size_t n); +size_t ft_strlcpy(char *dst, const char *src, size_t size); +size_t ft_strlcat(char *dst, const char *src, size_t size); +int ft_toupper(int c); +int ft_tolower(int c); +char *ft_strchr(const char *s, int c); +char *ft_strrchr(const char *s, int c); +int ft_strncmp(const char *s1, const char *s2, size_t n); +void *ft_memchr(const void *s, int c, size_t n); +int ft_memcmp(const void *s1, const void *s2, size_t n); +char *ft_strnstr(const char *big, const char *little, size_t len); +//sets the flag_overflow flag if an overflow happened +//acts just like atoi otherwise (put NULL to ignore the flag) +int ft_atoi(const char *nptr, int *flag_overflow); +char *ft_strdup(const char *s); +void *ft_calloc(size_t nmemb, size_t size); +char *ft_substr(char const *s, unsigned int start, size_t len); +char *ft_strjoin(char const *s1, char const *s2); +char *ft_strtrim(char const *s1, char const *set); + +char **ft_split(char const *s, char c); +void ft_free_split(char **strs); +size_t ft_split_size(char **strs); + +char *ft_itoa(int n); +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); +void ft_striteri(char *s, void (*f)(unsigned int, char*)); +void ft_putchar_fd(char c, int fd); +void ft_putstr_fd(char *s, int fd); +void ft_putendl_fd(char *s, int fd); +void ft_putnbr_fd(int n, int fd); +char *ft_itoa_base(int nbr, char *base); +char *ft_addr_to_strhex(void *addr); +char *ft_utoa(unsigned int n); +char *ft_utoa_base(unsigned int nbr, char *base); +size_t ft_strnonchr(char *str, char c); +int ft_strcmp(const char *s1, const char *s2); + +typedef struct s_list +{ + void *content; + struct s_list *next; +} t_list; + +t_list *ft_lstnew(void *content); +void ft_lstadd_front(t_list **lst, t_list *new); +int ft_lstsize(t_list *lst); +t_list *ft_lstlast(t_list *lst); +void ft_lstadd_back(t_list **lst, t_list *new); +void ft_lstdelone(t_list *lst, void (*del)(void *)); +void ft_lstclear(t_list **lst, void (*del)(void *)); +void ft_lstiter(t_list *lst, void (*f)(void *)); +t_list *ft_lstmap( + t_list *lst, + void *(*f)(void *), + void (*del)(void *)); + +int ft_isspace(char c); +int ft_toupper(int c); +int ft_tolower(int c); +int ft_atoie(const char *nptr); +long ft_atole(const char *nptr); +size_t i_drep_len(int n); +unsigned int ft_max_uint(size_t len, unsigned int a[len]); +t_list *ft_lstat(t_list *lst, size_t i); + +int safe_int_add(int a, int b); +int safe_int_sub(int a, int b); +int safe_int_mul(int a, int b); +ssize_t ft_power(ssize_t nb, ssize_t power); + +long safe_long_add(long a, long b); +long safe_long_sub(long a, long b); +long safe_long_mul(long a, long b); + +int ft_strhassuffix(const char *s, const char *suffix); +int ft_linecmp(const char *s1, const char *s2); +size_t ft_linelen(const char *line); + +#endif diff --git a/libft/sorting/ft_radixsort.c b/libft/sorting/ft_radixsort.c new file mode 100644 index 0000000..f9e33e7 --- /dev/null +++ b/libft/sorting/ft_radixsort.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_radixsort.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/18 14:18:55 by alier #+# #+# */ +/* Updated: 2025/02/16 19:06:42 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "ft_sorting.h" + +static void ft_naive_countsort2(struct s_countsort cs) +{ + size_t i; + + i = cs.size - 1; + while (true) + { + cs.tmp[cs.count[(cs.a[i] / cs.exp) % 10] - 1] = cs.a[i]; + cs.count[(cs.a[i] / cs.exp) % 10]--; + if (i == 0) + break ; + i--; + } + ft_memcpy(cs.a, cs.tmp, cs.size * sizeof(*cs.a)); +} + +/* + * used by `ft_naive_radixsort` + */ +static void ft_naive_countsort(size_t size, unsigned int a[size], + unsigned int exp) +{ + unsigned int *tmp; + unsigned int count[10]; + size_t i; + + tmp = malloc(size * sizeof(unsigned int)); + ft_bzero(count, 10 * sizeof(unsigned int)); + i = 0; + while (i < size) + { + count[(a[i] / exp) % 10]++; + i++; + } + i = 1; + while (i < 10) + { + count[i] += count[i - 1]; + i++; + } + ft_naive_countsort2((struct s_countsort){size, a, exp, tmp, count}); + free(tmp); +} + +/* + * Worst-case performance: O(size * max_digits) + * Worst-case space complexity: O(size + max_digits) + */ +void ft_naive_radixsort(size_t size, unsigned int a[size]) +{ + unsigned int m; + unsigned int exp; + + m = ft_max_uint(size, a); + exp = 1; + while (m / exp > 0) + { + ft_naive_countsort(size, a, exp); + exp *= 10; + } +} diff --git a/libft/sorting/ft_radixsort.o b/libft/sorting/ft_radixsort.o new file mode 100644 index 0000000..8edf1ef Binary files /dev/null and b/libft/sorting/ft_radixsort.o differ diff --git a/libft/sorting/ft_sorting.c b/libft/sorting/ft_sorting.c new file mode 100644 index 0000000..3773a9f --- /dev/null +++ b/libft/sorting/ft_sorting.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sorting.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/31 09:34:43 by alier #+# #+# */ +/* Updated: 2025/01/17 11:07:04 by alier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include +#include +#include "ft_sorting.h" + +static void ft_swap_bytes(void *a, void *b, size_t count) +{ + uint8_t *x; + uint8_t *y; + uint8_t t; + size_t i; + + x = (uint8_t *) a; + y = (uint8_t *) b; + i = 0; + while (i < count) + { + t = x[i]; + x[i] = y[i]; + y[i] = t; + i++; + } +} + +/* + * Worst-case performance: O(n^2) comparisons, O(n^2) swaps + * Worst-case space complexity: O(n) total, O(1) auxiliary + */ +void ft_naive_bubblesort(void *base, size_t nmemb, size_t size, + t_compar compar) +{ + bool swapped; + size_t i; + + if (nmemb == 0) + return ; + swapped = true; + while (swapped) + { + swapped = false; + i = 0; + while (i < nmemb * size - size) + { + if (compar(base + i, base + i + size) > 0) + { + ft_swap_bytes(base + i, base + i + size, size); + swapped = true; + } + i += size; + } + } +} + +static int compare_ints_asc(const void *a, const void *b) +{ + if (*(int *) a > *(int *)b) + return (1); + else + return (-1); +} + +int compare_strs_ptrs_asc(const void *a, const void *b) +{ + const char *left; + const char *right; + + left = *(const char **)a; + right = *(const char **)b; + return (ft_strcmp(left, right)); +} + +/* + * Worst-case performance: O(n^2) comparisons, O(n^2) swaps + * Worst-case space complexity: O(n) total, O(1) auxiliary + */ +void ft_naive_bubblesort_int_asc(int *base, size_t size) +{ + ft_naive_bubblesort(base, size, sizeof(int), compare_ints_asc); +} diff --git a/libft/sorting/ft_sorting.h b/libft/sorting/ft_sorting.h new file mode 100644 index 0000000..723167a --- /dev/null +++ b/libft/sorting/ft_sorting.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_sorting.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/11/04 16:45:04 by alier #+# #+# */ +/* Updated: 2025/01/17 11:07:18 by alier ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_SORTING_H +# define FT_SORTING_H +# include +# include "../libft.h" + +struct s_countsort +{ + size_t size; + unsigned int *a; + unsigned int exp; + unsigned int *tmp; + unsigned int *count; +}; + +typedef int (*t_compar)(const void *, const void *); + +int compare_strs_ptrs_asc(const void *a, const void *b); +void ft_naive_radixsort(size_t size, unsigned int a[size]); +void ft_naive_bubblesort_int_asc(int *base, size_t size); +void ft_naive_bubblesort(void *base, size_t nmemb, size_t size, + t_compar compar); + +#endif \ No newline at end of file diff --git a/libft/sorting/ft_sorting.o b/libft/sorting/ft_sorting.o new file mode 100644 index 0000000..512d470 Binary files /dev/null and b/libft/sorting/ft_sorting.o differ diff --git a/srcs/main.c b/srcs/main.c new file mode 100644 index 0000000..2729023 --- /dev/null +++ b/srcs/main.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/12/11 04:07:30 by thrieg #+# #+# */ +/* Updated: 2025/12/11 04:59:32 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_strace.h" + +int main_loop(size_t binary_type) +{ + int in_syscall = 0; + while (1) { + // Ask kernel to run until next syscall or signal + if (ptrace(PTRACE_SYSCALL, pid, 0, 0) == -1) break; + + int status; + if (waitpid(pid, &status, 0) == -1) break; + + if (WIFEXITED(status)) { + // child exited normally + printf("+++ exited with %d +++\n", WEXITSTATUS(status)); + break; + } + if (WIFSIGNALED(status)) { + // killed by a signal + printf("+++ killed by %s +++\n", strsignal(WTERMSIG(status))); + break; + } + if (!WIFSTOPPED(status)) + continue; + + int sig = WSTOPSIG(status); + + if (sig == (SIGTRAP | 0x80)) { + // syscall-enter or syscall-exit + if (!in_syscall) { + // ENTRY + read_regs_and_print_entry(pid); + in_syscall = 1; + } else { + // EXIT + read_regs_and_print_exit(pid); + in_syscall = 0; + } + } else { + // A real signal: print it, then let it continue + print_signal(pid, sig); + // pass down the signal to the actual program + if (ptrace(PTRACE_SYSCALL, pid, 0, sig) == -1) break; + waitpid(pid, &status, 0); + } + } +} + +int main(int argc, char **argv) +{ + if (argc < 2) + { + dprintf(2, "usage: %s ...\n", argv[0]); + return (EXIT_FAILURE); + } + + //determine if this file is an executable, and if so, 64 or 32 bits + ssize_t binary_bits = binary_type(argv[1]); + if (binary_bits < 0) + { + if (binary_bits == -1) + { + dprintf(2, "couldn't read that file, make sure you have the read and execute permissions on %s\n", argv[1]); + } + else if (binary_bits == -2) + { + dprintf(2, "%s is not a supported binary\n", argv[1]); + } + return (EXIT_FAILURE); + } + + pid_t pid = fork(); + + if (pid == 0) { + execvp(argv[1], argv + 1); + perror("execvp"); + return (EXIT_FAILURE); + } + else { + // 1) Seize the child + if (ptrace(PTRACE_SEIZE, pid, 0, 0) == -1) perror("PTRACE_SEIZE"); + + // 2) Interrupt it to force a stop + if (ptrace(PTRACE_INTERRUPT, pid, 0, 0) == -1) perror("PTRACE_INTERRUPT"); + + // 3) Wait for it to stop + int status; + waitpid(pid, &status, 0); + + // 4) Set options + long opts = PTRACE_O_TRACESYSGOOD; + ptrace(PTRACE_SETOPTIONS, pid, 0, opts); + + // 5) Enter main trace loop + return (main_loop((size_t)binary_bits)); + } + return (EXIT_SUCCESS); +} \ No newline at end of file diff --git a/srcs/utils.c b/srcs/utils.c new file mode 100644 index 0000000..3587560 --- /dev/null +++ b/srcs/utils.c @@ -0,0 +1,121 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: thrieg +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/12/11 04:31:15 by thrieg #+# #+# */ +/* Updated: 2025/12/11 06:14:12 by thrieg ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/ft_strace.h" +#include "../includes/syscalls_x86.h" +#include "../includes/syscalls_x64.h" +#include // for EI_NIDENT, EI_CLASS, ELFCLASS32, ELFCLASS64 +#include // for open +#include +#include // for user_regs_struct + +//returns 64 for x86_64, or 32 for 32 bits, -1 for open/read error, -2 for unrecognised file type +ssize_t binary_type(char *path_to_binary) +{ + int fd; + unsigned char ident[EI_NIDENT]; + ssize_t ret; + + fd = open(path_to_binary, O_RDONLY); + if (fd == -1) + return (-1); + ret = read(fd, ident, EI_NIDENT); + close(fd); + if (ret == -1) + return (-1); + if (ret != EI_NIDENT) + return (-2); + + /* Check this is an ELF file (binary) */ + if (ident[0] != 0x7f || ident[1] != 'E' + || ident[2] != 'L' || ident[3] != 'F') + return (-2); + + if (ident[EI_CLASS] == ELFCLASS64) + return (64); + if (ident[EI_CLASS] == ELFCLASS32) + return (32); + return (-2); //don't know wtf this file is at this point +} + +static void read_regs(pid_t pid, struct user_regs_struct *regs) +{ + struct iovec io; + io.iov_base = regs; + io.iov_len = sizeof(*regs); + + if (ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &io) == -1) + { + fprintf(stderr, "PTRACE_GETREGSET failed: %s\n", strerror(errno)); + return; + } +} + +void read_regs_and_print_entry(pid_t pid, size_t binary_type) +{ + struct user_regs_struct regs; + read_regs(pid, ®s); + if (binary_type == 64) + { + if (regs.orig_rax >= g_syscalls_64_len) + { + printf("unknown syscall(%ld, %lld, %lld, %lld, %lld, %lld, %lld)\n", + (long long)regs.orig_rax, + (long long)regs.rdi, + (long long)regs.rsi, + (long long)regs.rdx, + (long long)regs.r10, + (long long)regs.r8, + (long long)regs.r9); + } + else + { + const char *syscall_name = g_syscalls_64[regs.orig_rax]->name; + int argc = g_syscalls_64[regs.orig_rax]->argc; + printf("%s(%ld, %lld, %lld, %lld, %lld, %lld, %lld)\n", + syscall, + (long long)regs.rdi, + (long long)regs.rsi, + (long long)regs.rdx, + (long long)regs.r10, + (long long)regs.r8, + (long long)regs.r9); + } + } + else if (binary_type == 32) + { + if (regs.orig_eax >= g_syscalls_86_len) + { + printf("unknown syscall(%ld, %lld, %lld, %lld, %lld, %lld, %lld)\n", + (long)regs.orig_eax, + (long)regs.ebx, + (long)regs.ecx, + (long)regs.edx, + (long)regs.esi, + (long)regs.edi, + (long)regs.ebp); + } + else + { + const char *syscall_name = g_syscalls_86[regs.orig_eax]->name; + int argc = g_syscalls_64[regs.orig_eax]->argc; + printf("%s(%lld, %lld, %lld, %lld, %lld, %lld)\n", + syscall_name, + (long)regs.ebx, + (long)regs.ecx, + (long)regs.edx, + (long)regs.esi, + (long)regs.edi, + (long)regs.ebp); + } + } +} \ No newline at end of file