#ifndef TIKKER_DECODE_H #define TIKKER_DECODE_H #include #include #include static inline char tikker_get_shifted_char(char c) { switch (c) { case '1': return '!'; case '2': return '@'; case '3': return '#'; case '4': return '$'; case '5': return '%'; case '6': return '^'; case '7': return '&'; case '8': return '*'; case '9': return '('; case '0': return ')'; case '-': return '_'; case '=': return '+'; case '[': return '{'; case ']': return '}'; case '\\': return '|'; case ';': return ':'; case '\'': return '"'; case ',': return '<'; case '.': return '>'; case '/': return '?'; case '`': return '~'; default: return c; } } static inline int tikker_decode_buffer(const char *input, char *output, size_t output_size) { size_t out_pos = 0; int shift_active = 0; const char *p = input; while (*p && out_pos < output_size - 1) { if (*p == '[') { const char *end = strchr(p, ']'); if (!end) { p++; continue; } size_t token_len = end - p - 1; char token[64]; if (token_len >= sizeof(token)) token_len = sizeof(token) - 1; strncpy(token, p + 1, token_len); token[token_len] = '\0'; if (strcmp(token, "LEFT_SHIFT") == 0 || strcmp(token, "RIGHT_SHIFT") == 0) { shift_active = 1; } else if (strcmp(token, "BACKSPACE") == 0) { if (out_pos > 0) out_pos--; } else if (strcmp(token, "ENTER") == 0) { output[out_pos++] = '\n'; } else if (strcmp(token, "TAB") == 0) { output[out_pos++] = '\t'; } else if (token_len == 1) { char c = token[0]; if (shift_active) { if (c >= 'A' && c <= 'Z') { output[out_pos++] = c; } else if (c >= 'a' && c <= 'z') { output[out_pos++] = c - 32; } else { output[out_pos++] = tikker_get_shifted_char(c); } shift_active = 0; } else { if (c >= 'A' && c <= 'Z') { output[out_pos++] = c + 32; } else { output[out_pos++] = c; } } } p = end + 1; } else if (*p == ' ' || *p == '\n' || *p == '\t') { output[out_pos++] = *p; p++; } else if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == ',' || *p == '-' || *p == '_' || *p == '\'' || *p == '"') { char c = *p; if (shift_active) { if (c >= 'a' && c <= 'z') { output[out_pos++] = c - 32; } else { output[out_pos++] = tikker_get_shifted_char(c); } shift_active = 0; } else { if (c >= 'A' && c <= 'Z') { output[out_pos++] = c + 32; } else { output[out_pos++] = c; } } p++; } else { p++; } } output[out_pos] = '\0'; return (int)out_pos; } static inline int tikker_decode_file(const char *filename) { FILE *f = fopen(filename, "r"); if (!f) { fprintf(stderr, "Error: Cannot open file '%s'\n", filename); return 1; } fseek(f, 0, SEEK_END); long file_size = ftell(f); fseek(f, 0, SEEK_SET); char *input = malloc(file_size + 1); if (!input) { fclose(f); fprintf(stderr, "Error: Memory allocation failed\n"); return 1; } size_t bytes_read = fread(input, 1, file_size, f); input[bytes_read] = '\0'; fclose(f); char *output = malloc(file_size + 1); if (!output) { free(input); fprintf(stderr, "Error: Memory allocation failed\n"); return 1; } tikker_decode_buffer(input, output, file_size + 1); printf("%s", output); free(input); free(output); return 0; } #endif