81 lines
2.4 KiB
C
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;
|
|
} |