Serenity Operating System
1/*
2 * Copyright (c) 2022, Brian Gianforcaro <bgianf@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/CharacterTypes.h>
8#include <AK/Vector.h>
9#include <LibGUI/GitCommitLexer.h>
10
11namespace GUI {
12
13GitCommitLexer::GitCommitLexer(StringView input)
14 : m_input(input)
15{
16}
17
18char GitCommitLexer::peek(size_t offset) const
19{
20 if ((m_index + offset) >= m_input.length())
21 return 0;
22 return m_input[m_index + offset];
23}
24
25char GitCommitLexer::consume()
26{
27 VERIFY(m_index < m_input.length());
28 char ch = m_input[m_index++];
29 if (ch == '\n') {
30 m_position.line++;
31 m_position.column = 0;
32 } else {
33 m_position.column++;
34 }
35 return ch;
36}
37
38Vector<GitCommitToken> GitCommitLexer::lex()
39{
40 Vector<GitCommitToken> tokens;
41
42 size_t token_start_index = 0;
43 GitCommitPosition token_start_position;
44
45 auto begin_token = [&] {
46 token_start_index = m_index;
47 token_start_position = m_position;
48 };
49
50 auto commit_token = [&](auto type) {
51 GitCommitToken token;
52 token.m_view = m_input.substring_view(token_start_index, m_index - token_start_index);
53 token.m_type = type;
54 token.m_start = token_start_position;
55 token.m_end = m_position;
56 tokens.append(token);
57 };
58
59 while (m_index < m_input.length()) {
60 if (is_ascii_space(peek(0))) {
61 begin_token();
62 while (is_ascii_space(peek()))
63 consume();
64 continue;
65 }
66
67 // Commit comments
68 if (peek(0) && peek(0) == '#') {
69 begin_token();
70 while (peek() && peek() != '\n')
71 consume();
72 commit_token(GitCommitToken::Type::Comment);
73 continue;
74 }
75
76 consume();
77 commit_token(GitCommitToken::Type::Unknown);
78 }
79 return tokens;
80}
81
82}