Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
150
Task/Abbreviations-simple/C/abbreviations-simple.c
Normal file
150
Task/Abbreviations-simple/C/abbreviations-simple.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const char* command_table =
|
||||
"add 1 alter 3 backup 2 bottom 1 Cappend 2 change 1 Schange Cinsert 2 Clast 3 "
|
||||
"compress 4 copy 2 count 3 Coverlay 3 cursor 3 delete 3 Cdelete 2 down 1 duplicate "
|
||||
"3 xEdit 1 expand 3 extract 3 find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2 "
|
||||
"forward 2 get help 1 hexType 4 input 1 powerInput 3 join 1 split 2 spltJOIN load "
|
||||
"locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2 macro merge 2 modify 3 move 2 "
|
||||
"msg next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit read recover 3 "
|
||||
"refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left "
|
||||
"2 save set shift 2 si sort sos stack 3 status 4 top transfer 3 type 1 up 1";
|
||||
|
||||
typedef struct command_tag {
|
||||
char* cmd;
|
||||
size_t length;
|
||||
size_t min_len;
|
||||
struct command_tag* next;
|
||||
} command_t;
|
||||
|
||||
// str is assumed to be all uppercase
|
||||
bool command_match(const command_t* command, const char* str) {
|
||||
size_t olen = strlen(str);
|
||||
return olen >= command->min_len && olen <= command->length
|
||||
&& strncmp(str, command->cmd, olen) == 0;
|
||||
}
|
||||
|
||||
// convert string to uppercase
|
||||
char* uppercase(char* str, size_t n) {
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
str[i] = toupper((unsigned char)str[i]);
|
||||
return str;
|
||||
}
|
||||
|
||||
void fatal(const char* message) {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void* xmalloc(size_t n) {
|
||||
void* ptr = malloc(n);
|
||||
if (ptr == NULL)
|
||||
fatal("Out of memory");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* xrealloc(void* p, size_t n) {
|
||||
void* ptr = realloc(p, n);
|
||||
if (ptr == NULL)
|
||||
fatal("Out of memory");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char** split_into_words(const char* str, size_t* count) {
|
||||
size_t size = 0;
|
||||
size_t capacity = 16;
|
||||
char** words = xmalloc(capacity * sizeof(char*));
|
||||
size_t len = strlen(str);
|
||||
for (size_t begin = 0; begin < len; ) {
|
||||
size_t i = begin;
|
||||
for (; i < len && isspace((unsigned char)str[i]); ++i) {}
|
||||
begin = i;
|
||||
for (; i < len && !isspace((unsigned char)str[i]); ++i) {}
|
||||
size_t word_len = i - begin;
|
||||
if (word_len == 0)
|
||||
break;
|
||||
char* word = xmalloc(word_len + 1);
|
||||
memcpy(word, str + begin, word_len);
|
||||
word[word_len] = 0;
|
||||
begin += word_len;
|
||||
if (capacity == size) {
|
||||
capacity *= 2;
|
||||
words = xrealloc(words, capacity * sizeof(char*));
|
||||
}
|
||||
words[size++] = word;
|
||||
}
|
||||
*count = size;
|
||||
return words;
|
||||
}
|
||||
|
||||
command_t* make_command_list(const char* table) {
|
||||
command_t* cmd = NULL;
|
||||
size_t count = 0;
|
||||
char** words = split_into_words(table, &count);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
char* word = words[i];
|
||||
command_t* new_cmd = xmalloc(sizeof(command_t));
|
||||
size_t word_len = strlen(word);
|
||||
new_cmd->length = word_len;
|
||||
new_cmd->min_len = word_len;
|
||||
new_cmd->cmd = uppercase(word, word_len);
|
||||
if (i + 1 < count) {
|
||||
char* eptr = 0;
|
||||
unsigned long min_len = strtoul(words[i + 1], &eptr, 10);
|
||||
if (min_len > 0 && *eptr == 0) {
|
||||
free(words[i + 1]);
|
||||
new_cmd->min_len = min_len;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
new_cmd->next = cmd;
|
||||
cmd = new_cmd;
|
||||
}
|
||||
free(words);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void free_command_list(command_t* cmd) {
|
||||
while (cmd != NULL) {
|
||||
command_t* next = cmd->next;
|
||||
free(cmd->cmd);
|
||||
free(cmd);
|
||||
cmd = next;
|
||||
}
|
||||
}
|
||||
|
||||
const command_t* find_command(const command_t* commands, const char* word) {
|
||||
for (const command_t* cmd = commands; cmd != NULL; cmd = cmd->next) {
|
||||
if (command_match(cmd, word))
|
||||
return cmd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void test(const command_t* commands, const char* input) {
|
||||
printf(" input: %s\n", input);
|
||||
printf("output:");
|
||||
size_t count = 0;
|
||||
char** words = split_into_words(input, &count);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
char* word = words[i];
|
||||
uppercase(word, strlen(word));
|
||||
const command_t* cmd_ptr = find_command(commands, word);
|
||||
printf(" %s", cmd_ptr ? cmd_ptr->cmd : "*error*");
|
||||
free(word);
|
||||
}
|
||||
free(words);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
command_t* commands = make_command_list(command_table);
|
||||
const char* input = "riG rePEAT copies put mo rest types fup. 6 poweRin";
|
||||
test(commands, input);
|
||||
free_command_list(commands);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue