[42Seoul] cub3d description 파일 파싱하기 2

seomoon·2021년 1월 17일
0

42Seoul

목록 보기
6/9

description 파일 파싱하기

check_file_name() : 파일명 체크하기

int			check_file_name(char *file_name)
{
	int		i;

	if (!file_name || ft_strlen(file_name) > 4)
		return (-1);
	i = ft_strlen(file_name) - 1;
	if (file_name[i] == 'd' && file_name[i - 1] == 'u' && 
			file_name[i - 2] == 'c' && file_name[i - 3] == '.')
		return (1);
}
  • 파싱할 description 파일이 유효한 파일인지 확인하는 함수.
    - 파일 이름이 NULL이 아닌지 확인한다.
    - 파일명이 4글자 이상인지 확인한다. (*.cub)
    - 파일 이름이 .cub로 끝나는지 확인한다.

parse_line() : 한 줄씩 파싱하기

int			parse_line(char *line, t_info *info, int gnl_return)
{
	t_map	*map;
	int		i;
	int		line_length;
	int		result;

	line_length = ft_strlen(line);
	if (line_length == 0)
		return (0);
	i = 0;
	while (line[i] != '\0')
	{
		if (is_space(line[i]))
			i++;
		else if (is_type_identifier(line[i], line[i + 1], line))
			break ;
		else if (is_map_character(line[i], gnl_return))
			i += save_map(line, gnl_return);
		else
			return (-1);
	}
	return (1);
}
  • treat_description() 함수에서 get_next_line()으로 파일을 한 줄씩 읽어서 parse_line()으로 넘긴다.
  • line 길이를 확인한다. line 길이가 0이면 0을 리턴한다.
  • line의 문자들을 확인한다.
    • 공백이면 건너뛰기
    • type identifier : is_type_identifier() 함수 안에서 처리하기
    • map character : save_map() 함수로 보내 임시 문자열에 저장하기
    • 공백/type identifier/map character를 제외한 다른 문자가 포함되어 있는 경우 에러 리턴(-1 리턴)하기
  • 라인 파싱이 정상적으로 끝나면 SUCCESS (+1) 리턴하기

is_space() : 공백 체크

int			is_space(char c)
{
	if ((c >= 9 && c <= 13) || c == 32)
		return (1);
	else
		return (-1);
}
  • character c가 공백인지 검사한다.

is_type_identifier() : type identifier 확인 & 처리

int			is_type_identifier(char a, char b, char *line)
{
	if ((a == 'R' || a == 'S' || a == 'F' || a == 'C') && is_space(b))
	{
		if (a == 'R')
			config_resolution(line + 1);
		else if (a == 'S')
			config_path(4, line + 1);
		else 
			config_color(a, line + 1);
	}
	else if (a == 'N' && b == 'O')
		config_path(0, line + 2);
	else if (a == 'S' && b == 'O')
		config_path(1, line + 2);
	else if (a == 'W' && b == 'E')
		config_path(2, line + 2);
	else if (a == 'E' && b == 'A')
		config_path(3, line + 2);
	else
		return (-1);
	return (0);
}
  • line 문자열의 문자가 type identifier인지 검사하고,
  • type identifier라면 해당 type 처리 함수를 호출한다.

is_map_character : map character인지 검사

int			is_map_character(char c)
{
	if (c == '0' || c == '1' || c == '2' || c == 'N' || c == 'S' || 
			c == 'W' || c == 'E')
		return (1);
	return (0);
}
  • line 문자열의 문자가 map character인지 검사한다.
  • N, S, W, E처럼 type identifier와 첫 글자가 겹치는 문자는 is_type_identifier() 함수에서 먼저 type identifier인지 확인하고
  • type identifier가 아닌 경우에만 map character인지 확인한다.

save_map()

int				save_map(char *line, int gnl_return)
{
	static char	**save;
	char		*tmp;
	int			line_len;

	line_len = ft_strlen(line);
	tmp = *save;
	*save = ft_strjoin(*save, line);
	free(tmp);
	if (gnl_return != 0) //is_not_eof
	{
		tmp = *save;
		*save = ft_strjoin(*save, "\n");
		free(tmp);
	}
	free(line);
	return (line_len);
}
  • map에 해당하는 line을 character 타입 배열인 save 변수에 저장한다.

  • libft의 ft_strjoin() 함수를 이용해 map line들을 연결한다.

  • 메모리 누수를 막기 위해 tmp 변수를 선언한다. save 포인터를 strjoin()의 결과값으로 덮어씌우기 전에
    tmp에 할당해 메모리 주소를 잃어버려 접근이 불가능해지는 것을 막는다.

  • line 연결이 끝나면 tmp 변수는 메모리에서 해제해준다.

  • get_next_line()에서 반환되는 리턴값 gnl_return을 인자로 받는다.
    - gnl_return이 0이 아니면, EOF(End of File)이 아니므로 각 map line 끝을 개행문자 \n로 마무리해준다.
    - gnl_return이 0이면(=EOF일 때) 개행문자로 마무리하지 않아도 된다.

  • 사용이 끝난 line 변수도 메모리에서 해제한다.

  • 리턴값은 line의 길이인 line_len이다.

profile
💛💛 🖥🏐🛋🥗💵📖 💛💛

0개의 댓글