SOURCES := main.c \
scene.c \
manipulation.c \
+ tokenize.c \
parsing.c \
+ parse_rt.c \
+ parse_small.c \
+ parse_elements.c \
vec3.c \
SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/01/13 19:51:09 by ljiriste #+# #+# */
-/* Updated: 2025/01/13 19:54:00 by ljiriste ### ########.fr */
+/* Updated: 2025/01/14 15:13:53 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
double distance;
} t_obstruction;
+void free_token(void *token);
+int tokenize(const char *filename, t_vec *tokens);
+
+double node_to_double(const t_parse_tree_node *double_node);
+t_color node_to_linear_rgb(const t_parse_tree_node *rgb_node);
+t_vec3 node_to_vec3(const t_parse_tree_node *vec3_node);
+
+int add_light(const t_parse_tree_node *light_node, t_vec *lights);
+int add_camera(
+ const t_parse_tree_node *camera_node, t_vec *cameras);
+int add_plane(const t_parse_tree_node *plane_node, t_vec *objects);
+int add_sphere(
+ const t_parse_tree_node *sphere_node, t_vec *objects);
+int add_cylinder(
+ const t_parse_tree_node *cylinder_node, t_vec *objects);
+
+int parse_rt_file(const char *filename, t_scene *scene);
+
t_color trace_ray(const t_ray *ray, t_scene *scene);
t_color color_srgb_to_lin(t_color_srgb srgb);
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parse_elements.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/01/14 14:59:40 by ljiriste #+# #+# */
+/* Updated: 2025/01/14 15:12:32 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif // M_PI
+
+int add_light(const t_parse_tree_node *light_node, t_vec *lights)
+{
+ t_element element;
+ t_light *light;
+
+ element.type = LIGHT;
+ light = &element.object.light;
+ light->brightness = node_to_double(
+ ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
+ light->position = node_to_vec3(ft_cget_node_child(
+ ft_cget_node_child(light_node, 1), 0));
+ if (light_node->children.size == 4)
+ light->color = node_to_linear_rgb(ft_cget_node_child(light_node, 3));
+ else
+ light->color = (t_color){.x = 1, .y = 1, .z = 1};
+ return (ft_vec_append(lights, &element) != success);
+}
+
+int add_camera(const t_parse_tree_node *camera_node, t_vec *cameras)
+{
+ t_element element;
+ t_camera *camera;
+
+ element.type = CAMERA;
+ camera = &element.object.camera;
+ camera->position = node_to_vec3(ft_cget_node_child(
+ ft_cget_node_child(camera_node, 1), 0));
+ camera->orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
+ camera->orientation = vec_normalize(camera->orientation);
+ camera->up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
+ camera->up_direction = vec_vec_mul(
+ camera->orientation, camera->up_direction);
+ if (vec_norm(camera->up_direction) < 1e-3)
+ camera->up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
+ camera->up_direction = vec_vec_mul(
+ camera->up_direction, camera->orientation);
+ camera->up_direction = vec_normalize(camera->up_direction);
+ camera->field_of_view = node_to_double(ft_cget_node_child(
+ ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
+ return (ft_vec_append(cameras, &element) != success);
+}
+
+int add_plane(const t_parse_tree_node *plane_node, t_vec *objects)
+{
+ t_object object;
+ t_plane *plane;
+
+ object.type = PLANE;
+ plane = &object.object.plane;
+ plane->point = node_to_vec3(
+ ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
+ plane->normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
+ plane->color = node_to_linear_rgb(ft_cget_node_child(plane_node, 3));
+ plane->normal = vec_normalize(plane->normal);
+ return (ft_vec_append(objects, &object) != success);
+}
+
+int add_sphere(const t_parse_tree_node *sphere_node, t_vec *objects)
+{
+ t_object object;
+ t_sphere *sphere;
+
+ object.type = SPHERE;
+ sphere = &object.object.sphere;
+ sphere->center = node_to_vec3(
+ ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
+ sphere->radius = node_to_double(
+ ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
+ sphere->color = node_to_linear_rgb(ft_cget_node_child(sphere_node, 3));
+ return (ft_vec_append(objects, &object) != success);
+}
+
+int add_cylinder(const t_parse_tree_node *cylinder_node, t_vec *objects)
+{
+ t_object object;
+ t_cylinder *cylinder;
+
+ object.type = CYLINDER;
+ cylinder = &object.object.cylinder;
+ cylinder->center = node_to_vec3(
+ ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
+ cylinder->rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
+ cylinder->rot_axis = vec_normalize(cylinder->rot_axis);
+ cylinder->color = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
+ cylinder->radius = node_to_double(
+ ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
+ cylinder->height = node_to_double(
+ ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
+ object.object.sphere.color
+ = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
+ return (ft_vec_append(objects, &object) != success);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parse_rt.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/01/14 15:09:41 by ljiriste #+# #+# */
+/* Updated: 2025/01/14 15:12:52 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "parsing_info.h"
+#include "miniRT.h"
+#include "libft.h"
+#include <stdlib.h>
+
+void free_token(void *v_token)
+{
+ t_token *token;
+
+ token = v_token;
+ free(token->str);
+ return ;
+}
+
+static void set_ambient_light(
+ const t_parse_tree_node *ambient_node, t_ambient_light *ambient)
+{
+ const t_parse_tree_node *intensity_node;
+ const t_parse_tree_node *rgb_node;
+
+ intensity_node = ft_cget_node_child(ambient_node, 1);
+ rgb_node = ft_cget_node_child(ambient_node, 2);
+ ambient->brightness = node_to_double(ft_cget_node_child(intensity_node, 0));
+ ambient->color = node_to_linear_rgb(rgb_node);
+ return ;
+}
+
+static int add_element_to_scene(
+ const t_parse_tree_node *element, t_scene *scene)
+{
+ const char *type;
+ const t_parse_tree_node *specific_element;
+
+ specific_element = ft_cget_node_child(element, 0);
+ type = specific_element->token.type;
+ if (!ft_strcmp(type, "ambient_light"))
+ set_ambient_light(specific_element, &scene->ambient_light);
+ else if (!ft_strcmp(type, "light")
+ && add_light(specific_element, &scene->lights))
+ return (1);
+ else if (!ft_strcmp(type, "camera")
+ && add_camera(specific_element, &scene->cameras))
+ return (1);
+ else if (!ft_strcmp(type, "sphere")
+ && add_sphere(specific_element, &scene->objects))
+ return (1);
+ else if (!ft_strcmp(type, "plane")
+ && add_plane(specific_element, &scene->objects))
+ return (1);
+ else if (!ft_strcmp(type, "cylinder")
+ && add_cylinder(specific_element, &scene->objects))
+ return (1);
+ return (0);
+}
+
+static int parse_tree_to_scene(const t_parse_tree_node *tree, t_scene *scene)
+{
+ if (tree->children.size == 2)
+ {
+ if (parse_tree_to_scene(ft_cget_node_child(tree, 0), scene))
+ return (1);
+ if (add_element_to_scene(ft_cget_node_child(tree, 1), scene))
+ return (1);
+ }
+ return (0);
+}
+
+int parse_rt_file(const char *filename, t_scene *scene)
+{
+ int res;
+ t_vec tokens;
+ t_parsing_table parsing_table;
+ t_parse_tree_node *parse_tree;
+
+ res = 1;
+ ft_vec_init(&tokens, sizeof(t_token));
+ if (!tokenize(filename, &tokens))
+ {
+ if (ft_parsing_table_init(&parsing_table) == success
+ && ft_parsing_table_load_str
+ (&parsing_table, g_parsing_table, g_grammar) == success)
+ {
+ parse_tree = ft_parse(&tokens, &parsing_table);
+ if (parse_tree && !parse_tree_to_scene(parse_tree, scene)
+ && scene->cameras.size > 0)
+ res = 0;
+ ft_parse_tree_free(parse_tree);
+ }
+ ft_parsing_table_free(&parsing_table);
+ }
+ ft_vec_free(&tokens, free_token);
+ return (res);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parse_small.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/01/14 15:04:18 by ljiriste #+# #+# */
+/* Updated: 2025/01/14 15:13:05 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+
+static int node_to_int(const t_parse_tree_node *int_node)
+{
+ return (ft_atoi(int_node->token.str));
+}
+
+double node_to_double(const t_parse_tree_node *double_node)
+{
+ int whole;
+ int sign;
+ double decimal;
+ const char *str;
+
+ if (double_node->children.size == 1)
+ return (node_to_int(ft_cget_node_child(double_node, 0)));
+ str = ft_cget_node_child(double_node, 0)->token.str;
+ sign = 1;
+ if (str[0] == '-')
+ {
+ sign = -1;
+ ++str;
+ }
+ whole = ft_atoi(str);
+ str = ft_cget_node_child(double_node, 2)->token.str;
+ decimal = ft_atoi(str);
+ while (*str)
+ {
+ decimal /= 10;
+ ++str;
+ }
+ return (sign * (whole + decimal));
+}
+
+t_color node_to_linear_rgb(const t_parse_tree_node *rgb_node)
+{
+ const t_parse_tree_node *int_node;
+ t_color_srgb color;
+
+ int_node = ft_cget_node_child(rgb_node, 0);
+ color.r = node_to_int(int_node);
+ int_node = ft_cget_node_child(rgb_node, 2);
+ color.g = node_to_int(int_node);
+ int_node = ft_cget_node_child(rgb_node, 4);
+ color.b = node_to_int(int_node);
+ return (color_srgb_to_lin(color));
+}
+
+t_vec3 node_to_vec3(const t_parse_tree_node *vec3_node)
+{
+ const t_parse_tree_node *double_node;
+ t_vec3 res;
+
+ double_node = ft_cget_node_child(vec3_node, 0);
+ res.x = node_to_double(double_node);
+ double_node = ft_cget_node_child(vec3_node, 2);
+ res.y = node_to_double(double_node);
+ double_node = ft_cget_node_child(vec3_node, 4);
+ res.z = node_to_double(double_node);
+ return (res);
+}
/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/28 12:34:20 by ljiriste #+# #+# */
-/* Updated: 2025/01/13 19:54:25 by ljiriste ### ########.fr */
+/* Updated: 2025/01/14 15:10:27 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
-#include "parsing_info.h"
#include "miniRT.h"
#include "libft.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif // M_PI
-
-const char *extract_keyword(const char *line, size_t *i)
-{
- if (line[*i + 1] == '\0' || ft_isspace(line[*i + 1]))
- {
- if (line[*i] == 'A')
- return ("A");
- if (line[*i] == 'C')
- return ("C");
- if (line[*i] == 'L')
- return ("L");
- }
- else if (line[*i + 2] == '\0' || ft_isspace(line[*i + 2]))
- {
- ++*i;
- if (!ft_strncmp(line + *i - 1, "cy", 2))
- return ("CY");
- if (!ft_strncmp(line + *i - 1, "pl", 2))
- return ("PL");
- if (!ft_strncmp(line + *i - 1, "sp", 2))
- return ("SP");
- }
- return (NULL);
-}
-
-char *extract_int(const char *line, size_t *i)
-{
- size_t j;
-
- j = *i;
- while (ft_isdigit(line[*i]) || line[*i] == '-')
- ++*i;
- return (ft_strndup(line + j, ((*i)--) - j));
-}
-
-void free_token(void *v_token)
-{
- t_token *token;
-
- token = v_token;
- free(token->str);
- return ;
-}
-
-int tokenize_line(const char *line, t_vec *tokens)
-{
- size_t i;
- t_token token;
-
- i = 0;
- while (line[i])
- {
- token.str = NULL;
- while (ft_isspace(line[i]))
- ++i;
- if (!line[i])
- break ;
- if (line[i] == '.')
- token.type = "DOT";
- else if (line[i] == ',')
- token.type = "COMMA";
- else if (ft_isdigit(line[i]) || line[i] == '-')
- {
- token.type = "INT";
- token.str = extract_int(line, &i);
- if (!token.str)
- return (1);
- }
- else
- {
- token.type = (char *)extract_keyword(line, &i);
- if (!token.type)
- return (1);
- }
- if (ft_vec_append(tokens, &token) != success)
- {
- free_token(&token);
- return (1);
- }
- ++i;
- }
- return (0);
-}
-
-int tokenize(const char *filename, t_vec *tokens)
-{
- int fd;
- char *line;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- return (1);
- line = get_next_line(fd);
- while (line)
- {
- if (ft_strncmp(line, "//", 2) && tokenize_line(line, tokens))
- {
- free(line);
- get_next_line(-1);
- close(fd);
- return (1);
- }
- free(line);
- line = get_next_line(fd);
- }
- close(fd);
- return (0);
-}
-
-int node_to_int(const t_parse_tree_node *int_node)
-{
- return (ft_atoi(int_node->token.str));
-}
-
-double node_to_double(const t_parse_tree_node *double_node)
-{
- int whole;
- int sign;
- double decimal;
- const char *str;
-
- if (double_node->children.size == 1)
- return (node_to_int(ft_cget_node_child(double_node, 0)));
- str = ft_cget_node_child(double_node, 0)->token.str;
- sign = 1;
- if (str[0] == '-')
- {
- sign = -1;
- ++str;
- }
- whole = ft_atoi(str);
- str = ft_cget_node_child(double_node, 2)->token.str;
- decimal = ft_atoi(str);
- while (*str)
- {
- decimal /= 10;
- ++str;
- }
- return (sign * (whole + decimal));
-}
-
-t_color node_to_linear_rgb(const t_parse_tree_node *rgb_node)
-{
- const t_parse_tree_node *int_node;
- t_color_srgb color;
-
- int_node = ft_cget_node_child(rgb_node, 0);
- color.r = node_to_int(int_node);
- int_node = ft_cget_node_child(rgb_node, 2);
- color.g = node_to_int(int_node);
- int_node = ft_cget_node_child(rgb_node, 4);
- color.b = node_to_int(int_node);
- return (color_srgb_to_lin(color));
-}
-
-t_vec3 node_to_vec3(const t_parse_tree_node *vec3_node)
-{
- const t_parse_tree_node *double_node;
- t_vec3 res;
-
- double_node = ft_cget_node_child(vec3_node, 0);
- res.x = node_to_double(double_node);
- double_node = ft_cget_node_child(vec3_node, 2);
- res.y = node_to_double(double_node);
- double_node = ft_cget_node_child(vec3_node, 4);
- res.z = node_to_double(double_node);
- return (res);
-}
-
-void set_ambient_light(
- const t_parse_tree_node *ambient_node, t_ambient_light *ambient)
-{
- const t_parse_tree_node *intensity_node;
- const t_parse_tree_node *rgb_node;
-
- intensity_node = ft_cget_node_child(ambient_node, 1);
- rgb_node = ft_cget_node_child(ambient_node, 2);
- ambient->brightness = node_to_double(ft_cget_node_child(intensity_node, 0));
- ambient->color = node_to_linear_rgb(rgb_node);
- return ;
-}
-
-int add_light(const t_parse_tree_node *light_node, t_vec *lights)
-{
- t_element element;
- t_light *light;
-
- element.type = LIGHT;
- light = &element.object.light;
- light->brightness = node_to_double(
- ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
- light->position = node_to_vec3(ft_cget_node_child(
- ft_cget_node_child(light_node, 1), 0));
- if (light_node->children.size == 4)
- light->color = node_to_linear_rgb(ft_cget_node_child(light_node, 3));
- else
- light->color = (t_color){.x = 1, .y = 1, .z = 1};
- return (ft_vec_append(lights, &element) != success);
-}
-
-int add_camera(const t_parse_tree_node *camera_node, t_vec *cameras)
-{
- t_element element;
- t_camera *camera;
-
- element.type = CAMERA;
- camera = &element.object.camera;
- camera->position = node_to_vec3(ft_cget_node_child(
- ft_cget_node_child(camera_node, 1), 0));
- camera->orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
- camera->orientation = vec_normalize(camera->orientation);
- camera->up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
- camera->up_direction = vec_vec_mul(
- camera->orientation, camera->up_direction);
- if (vec_norm(camera->up_direction) < 1e-3)
- camera->up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
- camera->up_direction = vec_vec_mul(
- camera->up_direction, camera->orientation);
- camera->up_direction = vec_normalize(camera->up_direction);
- camera->field_of_view = node_to_double(ft_cget_node_child(
- ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
- return (ft_vec_append(cameras, &element) != success);
-}
-
-int add_plane(const t_parse_tree_node *plane_node, t_vec *objects)
-{
- t_object object;
- t_plane *plane;
-
- object.type = PLANE;
- plane = &object.object.plane;
- plane->point = node_to_vec3(
- ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
- plane->normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
- plane->color = node_to_linear_rgb(ft_cget_node_child(plane_node, 3));
- plane->normal = vec_normalize(plane->normal);
- return (ft_vec_append(objects, &object) != success);
-}
-
-int add_sphere(const t_parse_tree_node *sphere_node, t_vec *objects)
-{
- t_object object;
- t_sphere *sphere;
-
- object.type = SPHERE;
- sphere = &object.object.sphere;
- sphere->center = node_to_vec3(
- ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
- sphere->radius = node_to_double(
- ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
- sphere->color = node_to_linear_rgb(ft_cget_node_child(sphere_node, 3));
- return (ft_vec_append(objects, &object) != success);
-}
-
-int add_cylinder(const t_parse_tree_node *cylinder_node, t_vec *objects)
-{
- t_object object;
- t_cylinder *cylinder;
-
- object.type = CYLINDER;
- cylinder = &object.object.cylinder;
- cylinder->center = node_to_vec3(
- ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
- cylinder->rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
- cylinder->rot_axis = vec_normalize(cylinder->rot_axis);
- cylinder->color = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
- cylinder->radius = node_to_double(
- ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
- cylinder->height = node_to_double(
- ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
- object.object.sphere.color
- = node_to_linear_rgb(ft_cget_node_child(cylinder_node, 5));
- return (ft_vec_append(objects, &object) != success);
-}
-
-int add_element_to_scene(const t_parse_tree_node *element, t_scene *scene)
-{
- const char *type;
- const t_parse_tree_node *specific_element;
-
- specific_element = ft_cget_node_child(element, 0);
- type = specific_element->token.type;
- if (!ft_strcmp(type, "ambient_light"))
- set_ambient_light(specific_element, &scene->ambient_light);
- else if (!ft_strcmp(type, "light")
- && add_light(specific_element, &scene->lights))
- return (1);
- else if (!ft_strcmp(type, "camera")
- && add_camera(specific_element, &scene->cameras))
- return (1);
- else if (!ft_strcmp(type, "sphere")
- && add_sphere(specific_element, &scene->objects))
- return (1);
- else if (!ft_strcmp(type, "plane")
- && add_plane(specific_element, &scene->objects))
- return (1);
- else if (!ft_strcmp(type, "cylinder")
- && add_cylinder(specific_element, &scene->objects))
- return (1);
- return (0);
-}
-
-int parse_tree_to_scene(const t_parse_tree_node *tree, t_scene *scene)
-{
- if (tree->children.size == 2)
- {
- if (parse_tree_to_scene(ft_cget_node_child(tree, 0), scene))
- return (1);
- if (add_element_to_scene(ft_cget_node_child(tree, 1), scene))
- return (1);
- }
- return (0);
-}
-
-int parse_rt_file(const char *filename, t_scene *scene)
-{
- int res;
- t_vec tokens;
- t_parsing_table parsing_table;
- t_parse_tree_node *parse_tree;
-
- res = 1;
- ft_vec_init(&tokens, sizeof(t_token));
- if (!tokenize(filename, &tokens))
- {
- if (ft_parsing_table_init(&parsing_table) == success
- && ft_parsing_table_load_str
- (&parsing_table, g_parsing_table, g_grammar) == success)
- {
- parse_tree = ft_parse(&tokens, &parsing_table);
- if (parse_tree && !parse_tree_to_scene(parse_tree, scene)
- && scene->cameras.size > 0)
- res = 0;
- ft_parse_tree_free(parse_tree);
- }
- ft_parsing_table_free(&parsing_table);
- }
- ft_vec_free(&tokens, free_token);
- return (res);
-}
+#include <stddef.h>
static int parse_arg(char **argv, t_session *s, int *i)
{
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* tokenize.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2025/01/14 14:49:32 by ljiriste #+# #+# */
+/* Updated: 2025/01/14 14:51:04 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "miniRT.h"
+#include "libft.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+static const char *extract_keyword(const char *line, size_t *i)
+{
+ if (line[*i + 1] == '\0' || ft_isspace(line[*i + 1]))
+ {
+ if (line[*i] == 'A')
+ return ("A");
+ if (line[*i] == 'C')
+ return ("C");
+ if (line[*i] == 'L')
+ return ("L");
+ }
+ else if (line[*i + 2] == '\0' || ft_isspace(line[*i + 2]))
+ {
+ ++*i;
+ if (!ft_strncmp(line + *i - 1, "cy", 2))
+ return ("CY");
+ if (!ft_strncmp(line + *i - 1, "pl", 2))
+ return ("PL");
+ if (!ft_strncmp(line + *i - 1, "sp", 2))
+ return ("SP");
+ }
+ return (NULL);
+}
+
+static char *extract_int(const char *line, size_t *i)
+{
+ size_t j;
+
+ j = *i;
+ while (ft_isdigit(line[*i]) || line[*i] == '-')
+ ++*i;
+ return (ft_strndup(line + j, ((*i)--) - j));
+}
+
+static int create_token(t_token *token, const char *line, size_t *i)
+{
+ if (line[*i] == '.')
+ token->type = "DOT";
+ else if (line[*i] == ',')
+ token->type = "COMMA";
+ else if (ft_isdigit(line[*i]) || line[*i] == '-')
+ {
+ token->type = "INT";
+ token->str = extract_int(line, i);
+ if (!token->str)
+ return (1);
+ }
+ else
+ {
+ token->type = (char *)extract_keyword(line, i);
+ if (!token->type)
+ return (1);
+ }
+ return (0);
+}
+
+static int tokenize_line(const char *line, t_vec *tokens)
+{
+ size_t i;
+ t_token token;
+
+ i = 0;
+ while (line[i])
+ {
+ token.str = NULL;
+ while (ft_isspace(line[i]))
+ ++i;
+ if (!line[i])
+ break ;
+ if (create_token(&token, line, &i))
+ return (1);
+ if (ft_vec_append(tokens, &token) != success)
+ {
+ free_token(&token);
+ return (1);
+ }
+ ++i;
+ }
+ return (0);
+}
+
+int tokenize(const char *filename, t_vec *tokens)
+{
+ int fd;
+ char *line;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return (1);
+ line = get_next_line(fd);
+ while (line)
+ {
+ if (ft_strncmp(line, "//", 2) && tokenize_line(line, tokens))
+ {
+ free(line);
+ get_next_line(-1);
+ close(fd);
+ return (1);
+ }
+ free(line);
+ line = get_next_line(fd);
+ }
+ close(fd);
+ return (0);
+}