Skip to content

Commit

Permalink
cii: Add get_word
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Nov 25, 2023
1 parent 961ec25 commit e1900e8
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
1 change: 1 addition & 0 deletions cii/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ if (BUILD_TESTING)
)

add_executable(cii_table_test
tests/table_test.c
tests/get_word.c
tests/get_word.h
)
Expand Down
48 changes: 47 additions & 1 deletion cii/tests/get_word.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,50 @@
// Use of this source is governed by GNU General Public License
// that can be found in the LICENSE file.

#include "get_word.h"
#include "get_word.h"

#include <ctype.h>
#include <string.h>

#include "cii/assert.h"

int get_word(FILE* fp, char* buf, size_t buf_size,
int first(int c), int rest(int c)) {
assert(fp != NULL);
assert(buf != NULL);
assert(buf_size > 1);
assert(first != NULL);
assert(rest != NULL);

int c = getc(fp);
int i = 0;
for (/* empty */; c != EOF; c = getc(fp)) {
if (first(c) == 0) {
// store c in buffer.
if (i < buf_size - 1) {
buf[i] = (char)c;
i += 1;
}

c = getc(fp);
break;
}
}
for (/* empty */; c != EOF && rest(c) == 0; c = getc(fp)) {
// store c in buffer.
if (i < buf_size - 1) {
buf[i] = (char)c;
i += 1;
}
}
if (i < buf_size) {
buf[i] = '\0';
} else {
buf[buf_size - 1] = '\0';
}
if (c != EOF) {
ungetc(c, fp);
}

return i > 0;
}
24 changes: 24 additions & 0 deletions cii/tests/get_word.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,28 @@
#ifndef CII_TESTS_GET_WORD_H_
#define CII_TESTS_GET_WORD_H_

#include <stdio.h>

/**
* Consumes the next word in the file opened on |fp|, stores it as a null-terminated
* string in |buf|, and returns one.
*
* When it reaches end of file without consuming a word, it returns zero.
*
* A word is a contiguous sequence of characters, it starts with a character for
* which |first| returns nonzero value followed by characters for which |rest|
* returns nonzero values.
*
* If a word is longer than |buf_size - 2| characters, the excess characters are
* discarded.
* @param fp must be non-null.
* @param buf must be non-null.
* @param buf_size must exceed one.
* @param first must be non-null.
* @param rest must be non-null.
* @return
*/
extern int get_word(FILE* fp, char* buf, size_t buf_size,
int first(int c), int rest(int c));

#endif //CII_TESTS_GET_WORD_H_
9 changes: 9 additions & 0 deletions cii/tests/table_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) 2023 Xu Shaohua <[email protected]>. All rights reserved.
// Use of this source is governed by GNU General Public License
// that can be found in the LICENSE file.

#include "get_word.h"

int main() {
return 0;
}

0 comments on commit e1900e8

Please sign in to comment.