# **************************************************************************** #
#                                                                              #
#                                                         :::      ::::::::    #
#    Makefile                                           :+:      :+:    :+:    #
#                                                     +:+ +:+         +:+      #
#    By: jayang <[email protected]>                      +#+  +:+       +#+         #
#                                                 +#+#+#+#+#+   +#+            #
#    Created: 2022/02/20 15:14:13 by jayang            #+#    #+#              #
#    Updated: 2022/02/20 20:57:59 by jayang           ###   ########.fr        #
#                                                                              #
# **************************************************************************** #

CC = gcc
CHLAGS = -Wall -Wextra -Werror

TARGET = ft_hexdump
SRCS = srcs/main.c srcs/string.c srcs/print_hex_n.c srcs/print_hex_o.c
OBJS = ${SRCS:.c=.o}
HEADER = includes

%.o : %.c
	${CC} ${CHLAGS} -I ${HEADER} -c $< -o $@

${TARGET} : ${OBJS}
	${CC} ${CHLAGS} $^ -o $@

all : ${TARGET}

clean:
	rm -rf ${OBJS}

fclean: clean
	rm -rf ${TARGET}

re: fclean all
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_hexdump.h                                       :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/20 17:36:55 by jayang            #+#    #+#             */
/*   Updated: 2022/02/20 21:55:58 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#ifndef FT_HEXDUMP_H
# define FT_HEXDUMP_H

# include <unistd.h>
# include <errno.h>
# include <libgen.h>
# include <string.h>
# include <fcntl.h>

void    ft_putchar(char c);
void    ft_putstr(char *str);
unsigned char   *ft_strncpy(unsigned char *dest, unsigned char *src, unsigned int n);
unsigned int    ft_strncmp(unsigned char *s1, unsigned char *s2, unsigned int n);

void    ft_print_hex(char *str, unsigned int size);
void    ft_print_hex_option(char *str, unsigned int size);

char                    *g_path;
unsigned char           g_pre[16];
unsigned long long      g_addr;
int                     flag;

#endif
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   main.c                                             :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/20 15:19:31 by jayang            #+#    #+#             */
/*   Updated: 2022/02/21 19:44:40 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "ft_hexdump.h"
void print_hex_addr(void);
void print_hex_addr2(void);

void	vacate_buffer(int option)
{
	if (option == 0)
	{
		ft_print_hex(g_file, g_idx);
		g_addr += (unsigned long long)g_idx;
		print_hex_addr();
		ft_putchar('\\n');
	}
	else
	{
		ft_print_hex_option(g_file, g_idx);
		g_addr += (unsigned long long)g_idx;
		print_hex_addr2();
		ft_putchar('\\n');
	}
}

void	ft_read_file(int is_end, int fd, int option)
{
	int	byte;

	g_flag = 0;
	while (1)
	{
		byte = read(fd, g_file + g_idx, 1);
		if (byte <= 0)
			break ;
		if (option == 0 && g_idx == 15)
			ft_print_hex(g_file, 16);
		else if (option == 1 && g_idx == 15)
			ft_print_hex_option(g_file, 16);
		g_idx = (g_idx + 1) % 16;
		if (g_idx == 0)
			g_addr += 16;
	}
	if (is_end)
		vacate_buffer(option);
}

void	ft_open_file(int is_end, char *argv, int option)
{
	int	fd;

	fd = open(argv, O_RDONLY);
	if (fd < 0)
	{
		ft_print_errno(argv, errno);
		if (is_end && g_err == 0)
			bad_type_err(argv);
		return ;
	}
	g_err = 1;
	ft_read_file(is_end, fd, option);
	close(fd);
}

void	handle_option(int argc, char *argv[], int param)
{
	if (argc == 2)
		ft_read_file(1, 0, 1);
	while (param < argc)
	{
		ft_open_file(param == argc - 1, argv[param], 1);
		param++;
	}
}

int	main(int argc, char *argv[])
{
	int	param;

	g_path = argv[0];
	g_flag = 0;
	g_err = 0;
	g_idx = 0;
	param = 1;
	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'C')
		handle_option(argc, argv, param + 1);
	else
	{
		if (argc == 1)
			ft_read_file(1, 0, 0);
		while (param < argc)
		{
			ft_open_file(param == argc - 1, argv[param], 0);
			param++;
		}
	}
	return (0);
}
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   print_hex_n.c                                      :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/20 19:08:30 by jayang            #+#    #+#             */
/*   Updated: 2022/02/20 21:52:31 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "ft_hexdump.h"

void    print_hex_element(unsigned char c)
{
        char    *c_hex;

        c_hex = "0123456789abcdef";
        ft_putchar(c_hex[c / 16]);
        ft_putchar(c_hex[c % 16]);
}

void    print_hex_addr(void)
{
        unsigned long long      c_addr;
        unsigned char           sub[7];
        int                                     i;

        c_addr = g_addr;
        i = 0;
        while (c_addr > 0)
        {
                sub[6 - i] = "0123456789abcdef"[c_addr % 16];
                c_addr /= 16;
                i++;
        }
        while (i < 7)
        {
                sub[6 - i] = '0';
                i++;
        }
        write(1, sub, 7);
}

void    print_line(unsigned char *str, unsigned int size)
{
        unsigned int    idx;

        idx = 0;
        while (idx < size)
        {
                print_hex_element(str[idx]);
                if (idx != 15)
                        ft_putchar(' ');
                idx++;
        }
        while (idx < 16)
        {
                ft_putstr("  ");
                if (idx != 15)
                        ft_putchar(' ');
                idx++;
        }
}

void    ft_print_hex(char *str, unsigned int size)
{
        unsigned char   *sub;

        sub = (unsigned char *)str;
        if (ft_strncmp(sub, g_pre, 16) != 0)
        {
                flag = 0;
                ft_strncpy(g_pre, sub, 16);
                print_hex_addr();
                ft_putchar(' ');
                print_line(sub, size);
                ft_putchar('\\n');
        }
        else if (flag == 0)
        {
                ft_putstr("*\\n");
                flag = 1;
        }
}
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   print_hex_o.c                                      :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/20 19:06:50 by jayang            #+#    #+#             */
/*   Updated: 2022/02/20 21:52:28 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "ft_hexdump.h"

void    print_hex_element2(unsigned char c)
{
        char    *c_hex;

        c_hex = "0123456789abcdef";
        ft_putchar(c_hex[c / 16]);
        ft_putchar(c_hex[c % 16]);
}

void    print_hex_addr2(void)
{
        unsigned long long      c_addr;
        unsigned char           sub[8];
        int                                     i;

        c_addr = g_addr;
        i = 0;
        while (c_addr > 0)
        {
                sub[7 - i] = "0123456789abcdef"[c_addr % 16];
                c_addr /= 16;
                i++;
        }
        while (i < 8)
        {
                sub[7 - i] = '0';
                i++;
        }
        write(1, sub, 8);
}

void    print_original_line(unsigned char *str, unsigned int size)
{
        unsigned int    idx;

        idx = 0;
        ft_putchar('|');
        while (idx < size)
        {
                if (' ' <= str[idx] && str[idx] <= '~')
                        write(1, str + idx, 1);
                else
                        ft_putchar('.');
                idx++;
        }
        ft_putchar('|');
}

void    print_line2(unsigned char *str, unsigned int size)
{
        unsigned int    idx;

        idx = 0;
        while (idx < size)
        {
                print_hex_element2(str[idx]);
                if (idx == 7 || idx == 15)
                        ft_putstr("  ");
                else
                        ft_putchar(' ');
                idx++;
        }
        while (idx < 16)
        {
                ft_putstr("  ");
                if (idx == 7 || idx == 15)
                        ft_putstr("  ");
                else
                        ft_putchar(' ');
                idx++;
        }
        print_original_line(str, size);
}

void    ft_print_hex_option(char *str, unsigned int size)
{
        unsigned char   *sub;

        sub = (unsigned char *)str;
        if (ft_strncmp(sub, g_pre, 16) != 0)
        {
                flag = 0;
                ft_strncpy(g_pre, sub, 16);
                print_hex_addr2();
                ft_putstr("  ");
                print_line2(sub, size);
                ft_putchar('\\n');
        }
        else if (flag == 0)
        {
                flag = 1;
                ft_putstr("*\\n");
        }
}
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   string.c                                           :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/19 18:57:21 by jayang            #+#    #+#             */
/*   Updated: 2022/02/20 21:18:43 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include <unistd.h>

void	ft_putchar(char c)
{
	write(1, &c, 1);
}

void	ft_putstr(char *str)
{
	while (*str)
	{
		ft_putchar(*str);
		str++;
	}
}

unsigned char	*ft_strncpy(unsigned char *dest, unsigned char *src, unsigned int n)
{
	unsigned int	i;

	i = 0;
	while ((i < n) && (src[i]))
	{
		dest[i] = src[i];
		i++;
	}
	while (i < n)
	{
		dest[i] = '\\0';
		i++;
	}
	return (dest);
}

unsigned int	ft_strncmp(unsigned char *s1, unsigned char *s2, unsigned int n)
{
	unsigned int	i;

	if (n == 0)
		return (0);
	i = 0;
	while (s1[i] && (s1[i] == s2[i]) && (i < n - 1))
		i++;
	return ((unsigned int)s1[i] - (unsigned int)s2[i]);
}
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_error_ctrl.c                                    :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: jayang <[email protected]>                      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/02/21 20:56:04 by jayang            #+#    #+#             */
/*   Updated: 2022/02/21 20:57:02 by jayang           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "ft_hexdump.h"

void	ft_print_errno(char *param_str, int err)
{
	ft_putstr(basename(g_path));
	ft_putstr(": ");
	ft_putstr(param_str);
	ft_putstr(": ");
	ft_putstr(strerror(err));
	ft_putchar('\\n');
}

void	bad_type_err(char *str)
{
	ft_putstr(basename(g_path));
	ft_putstr(": ");
	ft_putstr(str);
	ft_putstr(": ");
	ft_putstr("Bad file descriptor");
	ft_putchar('\\n');
}

Makefile

ft_hexdump.h

main.c

string.c

print_hex_o.c

print_hex_n.c

ft_error_ctrl.c