Skip to content

Commit

Permalink
[Project 1] Fix a bug related list and add comments and add documenta…
Browse files Browse the repository at this point in the history
…tion.
  • Loading branch information
taeguk committed Apr 4, 2017
1 parent e8c869b commit 8b51732
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 18 deletions.
5 changes: 5 additions & 0 deletions main.c → 20141500.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define MEMORY_SIZE (1 * 1024 * 1024) /* 1MB */
#define OPCODE_FILE "opcode.txt"

/* Opcode File을 읽어들여서, opcode manager를 구축해주는 함수. */
static struct opcode_manager *read_opcode_file ()
{
FILE *fp = fopen (OPCODE_FILE, "rt");
Expand All @@ -17,6 +18,7 @@ static struct opcode_manager *read_opcode_file ()
char format_buf[16];
unsigned int val;

/* 파일에서 opcode 정보를 읽어들이면서 opcode manager에 그 정보를 추가한다. */
while (fscanf (fp, "%X %6s %5s", /* TODO */
&val, opcode.name, format_buf) != EOF)
{
Expand Down Expand Up @@ -48,6 +50,8 @@ int main()
{
struct command_state state;

/* Command Loop의 State를 초기화한다. */

state.history_manager = history_manager_construct ();
state.memory_manager = memory_manager_construct (MEMORY_SIZE);
if (!(state.opcode_manager = read_opcode_file ()))
Expand All @@ -57,6 +61,7 @@ int main()
}
state.saved_dump_start = 0;

/* Command Loop로 진입하여, 사용자의 입력을 처리한다. */
command_loop(&state);

return 0;
Expand Down
Binary file added Document.doc
Binary file not shown.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
SOURCES=command.c history.c list.c main.c memory.c opcode.c
SOURCES=command.c history.c list.c 20141500.c memory.c opcode.c
TARGET=20141500.out

all: $(TARGET)

$(TARGET): $(SOURCES)
gcc -std=gnu99 $(SOURCES) -o $(TARGET)
gcc -std=gnu99 -W -Wall $(SOURCES) -o $(TARGET)

clean:
rm -f $(TARGET)
25 changes: 23 additions & 2 deletions command.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define COMMAND_TOKEN_MAX_NUM 8

/* 사용자가 입력한 명령에 대한 parsing / processing 결과에 대한 코드 */
#define COMMAND_STATUS_SUCCESS 0
#define COMMAND_STATUS_INVALID_INPUT 1
#define COMMAND_STATUS_TOO_MANY_TOKENS 2
Expand All @@ -23,12 +24,13 @@ enum command_type
COMMAND_OPCODE, COMMAND_OPCODELIST
};

/* 사용자가 입력한 명령을 의미하는 구조체 */
struct command
{
enum command_type type;
size_t token_cnt;
char *token_list[COMMAND_TOKEN_MAX_NUM+1];
char *input;
char *token_list[COMMAND_TOKEN_MAX_NUM+1]; // 사용자가 입력한 명령어가 token별로 쪼개서 여기에 들어간다.
char *input; // 사용자 입력한 명령어 라인 전부가 이 곳에 들어간다.
};

static int command_fetch (struct command *command);
Expand Down Expand Up @@ -98,6 +100,9 @@ bool command_loop (struct command_state *state)
return true;
}

/* Command를 fetch하는 함수.
* 사용자로 부터 명령어를 입력받고, 그 것을 바탕으로 command 구조체를 구축한다.
*/
static int command_fetch (struct command *command)
{
static char input[COMMAND_INPUT_MAX_LEN];
Expand Down Expand Up @@ -157,6 +162,9 @@ static int command_fetch (struct command *command)
return COMMAND_STATUS_SUCCESS;
}

/* Command를 처리하는 함수.
* command type에 따라 서로 다른 handler를 호출해 준다.
*/
static int command_process (struct command_state *state, struct command *command, bool *quit)
{
*quit = false;
Expand Down Expand Up @@ -199,6 +207,7 @@ static int command_process (struct command_state *state, struct command *command
}
}

/* help 명령어에 대한 handler. */
static int command_h_help (__attribute__((unused)) struct command_state *state, __attribute__((unused)) struct command *command)
{
if (command->token_cnt != 1)
Expand All @@ -218,6 +227,7 @@ static int command_h_help (__attribute__((unused)) struct command_state *state,
return COMMAND_STATUS_SUCCESS;
}

/* dir 명령어에 대한 handler */
static int command_h_dir (__attribute__((unused)) struct command_state *state, __attribute__((unused)) struct command *command)
{
if (command->token_cnt != 1)
Expand Down Expand Up @@ -260,6 +270,7 @@ static int command_h_dir (__attribute__((unused)) struct command_state *state, _
return COMMAND_STATUS_SUCCESS;
}

/* history 명령어에 대한 handler */
static int command_h_history (struct command_state *state, __attribute__((unused)) struct command *command)
{
if (command->token_cnt != 1)
Expand All @@ -269,28 +280,33 @@ static int command_h_history (struct command_state *state, __attribute__((unused
return COMMAND_STATUS_SUCCESS;
}

/* dump 명령어에 대한 handler */
static int command_h_dump (struct command_state *state, struct command *command)
{
uint32_t start, end;
bool enable_max_end;
uint32_t memory_size = memory_get_memory_size (state->memory_manager);

// 명령어의 형태가 매개변수없는 dump 일 때,
if (command->token_cnt == 1)
{
start = state->saved_dump_start;
end = start + 159;
// memory size를 넘어가는 경우, 다음 dump때 출력할 위치를 0으로 초기화한다.
if (end > memory_size)
state->saved_dump_start = 0;
else
state->saved_dump_start += 160;
enable_max_end = true;
}
// 명령어의 형태가 dump start 일 때,
else if (command->token_cnt == 2)
{
start = strtol (command->token_list[1], NULL, 16);
end = start + 159;
enable_max_end = true;
}
// 명령어의 형태가 dump start, end 일 때,
else if (command->token_cnt == 3)
{
start = strtol (command->token_list[1], NULL, 16);
Expand All @@ -308,6 +324,7 @@ static int command_h_dump (struct command_state *state, struct command *command)
return COMMAND_STATUS_SUCCESS;
}

/* edit 명령어에 대한 handler */
static int command_h_edit (struct command_state *state, struct command *command)
{
if (command->token_cnt != 3)
Expand All @@ -329,6 +346,7 @@ static int command_h_edit (struct command_state *state, struct command *command)
return COMMAND_STATUS_SUCCESS;
}

/* fill 명령어에 대한 handler */
static int command_h_fill (struct command_state *state, struct command *command)
{
if (command->token_cnt != 4)
Expand All @@ -351,6 +369,7 @@ static int command_h_fill (struct command_state *state, struct command *command)
return COMMAND_STATUS_SUCCESS;
}

/* reset 명령어에 대한 handler */
static int command_h_reset (struct command_state *state, __attribute__((unused)) struct command *command)
{
if (command->token_cnt != 1)
Expand All @@ -360,6 +379,7 @@ static int command_h_reset (struct command_state *state, __attribute__((unused))
return COMMAND_STATUS_SUCCESS;
}

/* opcode 명령어에 대한 handler */
static int command_h_opcode (struct command_state *state, struct command *command)
{
if (command->token_cnt != 2)
Expand All @@ -379,6 +399,7 @@ static int command_h_opcode (struct command_state *state, struct command *comman
}
}

/* opcodelist 명령어에 대한 handler */
static int command_h_opcodelist (struct command_state *state, __attribute__((unused)) struct command *command)
{
if (command->token_cnt != 1)
Expand Down
8 changes: 7 additions & 1 deletion command.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@
#include "opcode.h"
#include "command_def.h"

/* Command Loop의 state를 의미하는 구조체
* command loop 내에서 이 state 구조체 정보를 바탕으로 사용자 명령들을 처리하게 된다.
* 만약, memory manager를 바꾼다던지 등등, state를 변경하고 싶다면, command loop내에서
* 이 구조체 내의 값들을 변경하면 된다.
*/
struct command_state
{
struct history_manager *history_manager;
struct memory_manager *memory_manager;
struct opcode_manager *opcode_manager;
uint32_t saved_dump_start;
uint32_t saved_dump_start; /* parameter가 없는 dump 명령어에서 위치를 저장하기 위해 쓰인다. */
};

/* 사용자의 입력을 받아서 처리하는 Command Loop로 진입하는 함수. */
bool command_loop (struct command_state *state);

#endif
8 changes: 7 additions & 1 deletion history.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@

struct history_manager
{
struct list *history_list;
struct list *history_list; // history들을 관리하는 링크드 리스트
};

struct history
{
char command_str[COMMAND_INPUT_MAX_LEN+1];
};

/* history manager 내의 history_list에 사용될 node 구조체 */
struct history_node
{
struct history history;
struct list_node list_node;
};

/* history manager를 생성하는 factory 함수 */
struct history_manager *history_manager_construct ()
{
struct history_manager *manager = malloc (sizeof(*manager));
Expand All @@ -31,16 +33,19 @@ struct history_manager *history_manager_construct ()
return manager;
}

/* history manager를 소멸시키는 함수 */
void history_manager_destroy (struct history_manager *manager)
{
struct list_node *node;
while ((node = list_pop_front (manager->history_list)))
{
free (list_entry (node, struct history_node, list_node));
}
list_destroy (manager->history_list);
free (manager);
}

/* history manager에 history를 추가하는 함수 */
void history_insert (struct history_manager *manager, const char *command_str)
{
struct history_node *node = malloc (sizeof(*node));
Expand All @@ -50,6 +55,7 @@ void history_insert (struct history_manager *manager, const char *command_str)
list_push_back (manager->history_list, &node->list_node);
}

/* history manager내에 있는 history 들을 출력하는 함수 */
void history_print (struct history_manager *manager, const char *cur_command_str)
{
struct list_node *node;
Expand Down
4 changes: 4 additions & 0 deletions history.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#ifndef __HISTORY_H__
#define __HISTORY_H__

/* history manager는 오직 factory 함수를 통해서만 얻을 수 있다. */
struct history_manager;

/* history manager를 생성하고 소멸시키는 함수들 */
struct history_manager *history_manager_construct ();
void history_manager_destroy (struct history_manager *manager);

/* history manager에 history를 추가하는 함수 */
void history_insert (struct history_manager *manager, const char *command_str);

/* history manager내에 있는 history 들을 출력하는 함수 */
void history_print (struct history_manager *manager, const char *cur_command_str);

#endif
16 changes: 12 additions & 4 deletions list.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

struct list
{
struct list_node head_node;
struct list_node tail_node;
struct list_node head_node; // 링크드 리스트의 맨 앞에 위치하는 dummy node
struct list_node tail_node; // 링크드 리스트의 맨 뒤에 위치하는 dummy node
};

/* list를 생성하는 factory 함수 */
struct list *list_construct ()
{
struct list *list = malloc (sizeof(*list));
Expand All @@ -20,37 +21,42 @@ struct list *list_construct ()
return list;
}

/* list를 소멸시키는 함수 */
void list_destroy (struct list *list)
{
assert (list_empty (list));
free (list);
}

/* list의 시작 node를 반환하는 함수 */
struct list_node *list_begin (struct list *list)
{
assert (list);
return list->head_node.next;
}

/* 다음 node를 반환하는 함수 */
struct list_node *list_next (struct list_node *cur_node)
{
assert (cur_node);
return cur_node->next;
}

/* list의 끝을 의미하는 node (즉, tail dummy node)를 반환하는 함수 */
struct list_node *list_end (struct list *list)
{
assert (list);
return &list->tail_node;
}

/* List Property */
/* list가 비었는 지 확인해주는 함수. */
bool list_empty (struct list *list)
{
assert (list);
return list->head_node.next == &list->tail_node;
}

/* list의 맨 앞에 node를 추가하는 함수 */
void list_push_front (struct list *list, struct list_node *node)
{
assert (list && node);
Expand All @@ -61,6 +67,7 @@ void list_push_front (struct list *list, struct list_node *node)
list->head_node.next = node;
}

/* list의 맨 뒤에 node를 추가하는 함수 */
void list_push_back (struct list *list, struct list_node *node)
{
assert (list && node);
Expand All @@ -71,7 +78,7 @@ void list_push_back (struct list *list, struct list_node *node)
list->tail_node.prev = node;
}

/* List Remove */
/* list의 맨 앞에서 node를 삭제하고 반환하는 함수 */
struct list_node *list_pop_front (struct list *list)
{
assert (list && list->head_node.next);
Expand All @@ -82,6 +89,7 @@ struct list_node *list_pop_front (struct list *list)
return node;
}

/* list의 맨 뒤에서 node를 삭제하고 반환하는 함수 */
struct list_node *list_pop_back (struct list *list)
{
assert (list && list->tail_node.prev);
Expand Down
Loading

0 comments on commit 8b51732

Please sign in to comment.