Files
kernel-study/userprog/gmsh/parser.c
T

81 lines
2.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "job.h"
// 문자열을 공백 기준으로 쪼개서 argv에 넣기
static void parse_args(char *cmd_str, command_t *cmd) {
char *token = strtok(cmd_str, " \t\n");
while (token != NULL && cmd->argc < MAX_ARGS - 1) {
// 리다이렉션 처리 (간이 버전)
if (strcmp(token, "<") == 0) {
token = strtok(NULL, " \t\n");
if (token) cmd->input_path = strdup(token);
}
else if (strcmp(token, ">") == 0) {
token = strtok(NULL, " \t\n");
if (token) cmd->output_path = strdup(token);
cmd->append_mode = 0;
}
else if (strcmp(token, ">>") == 0) {
token = strtok(NULL, " \t\n");
if (token) cmd->output_path = strdup(token);
cmd->append_mode = 1;
}
else {
// 일반 인자
cmd->argv[cmd->argc++] = strdup(token);
}
token = strtok(NULL, " \t\n");
}
cmd->argv[cmd->argc] = NULL;
}
// 메인 파서 함수
job_t *parse_line(char *line) {
if (line == NULL || strlen(line) == 0) return NULL;
// 1. Job 껍데기 생성
job_t *job = create_job(line);
// 2. 백그라운드(&) 확인
// 문자열 끝에서부터 역탐색하거나, 토큰화 과정에서 체크해야 함.
// 편의상 strrchr 사용 (단, 따옴표 안에 있는 &는 무시 못함. 일단 간단히 구현)
char *bg_ptr = strrchr(line, '&');
if (bg_ptr != NULL) {
job->is_bg = 1;
*bg_ptr = ' '; // &를 공백으로 치환해서 명령어 파싱 방해 안 되게 함
}
// 3. 파이프(|) 단위로 자르기
// strtok는 원본을 훼손하므로 복사본 사용
char *line_copy = strdup(line);
char *cmd_str = strtok(line_copy, "|");
while (cmd_str != NULL) {
command_t *cmd = (command_t *)malloc(sizeof(command_t));
memset(cmd, 0, sizeof(command_t));
// 내부 인자 및 리다이렉션 파싱
parse_args(cmd_str, cmd);
if (cmd->argc > 0) {
append_command(job, cmd);
} else {
free(cmd); // 빈 명령어는 버림
}
cmd_str = strtok(NULL, "|");
}
free(line_copy);
if (job->head == NULL) { // 명령어가 하나도 없으면
free_job(job);
return NULL;
}
return job;
}