-CFLAGS:=-std=c99 -O2 -Wall -Wextra -Wpedantic -Wvla -Wshadow -Wundef
+include chad.mk
+DEBUG:=1
+CFLAGS:=-std=c99 -O2 -Wvla -Wshadow -Wundef $(if ${DEBUG}, ${CHAD_DEBUG},'')
CPPFLAGS:=-D_FORTIFY_SOURCE=2
-SRC.dir:=src/
+SRC.dir:=source/
SRC:=$(shell find ${SRC.dir} -iname '*.c')
+HDR:=$(shell find ${SRC.dir} -iname '*.h')
OBJ:=$(subst .c,.o,${SRC})
+OUT:=hl
+OUTARGS:=${OUT} < source/main.c
+
+main: ${OBJ} ${HDR}
+ ${LINK.c} ${OBJ} -o hl
+
%.o: %.c
${COMPILE.c} $< -o $@
-hl: ${OBJ}
- ${LINK.c} ${OBJ} -o $@
+install:
+ cp hl /usr/bin/hl
+
+clean:
+ -rm ${OBJ}
+ -rm ${OUT}
-new:
- g++ src2/main.cpp -o hl -ggdb
+test: chad_test
--- /dev/null
+# Make script for Chad projects
+# This script depends on the following variables
+# - OUT : output program name
+# - OUTARGS : default flags to fork ${OUT} with
+
+#
+CHAD_DEBUG:=-Og -ggdb -pg -fno-inline
+
+# Programs to check warnings for as defined by the Chad standard
+GCC:=gcc
+GCC.warnings:=-Wall -Wextra -Wpedantic
+CLANG:=clang
+CLANG.warnings:=-Weverything
+VALGRIND:=valgrind
+
+chad_test:
+ ${GCC} ${GCC.warnings} ${SRC} -o ${OUT}
+ ${CLANG} ${GCC.warnings} ${SRC} -o ${OUT}
+ ${VALGRIND} ${OUT} ${OUTARGS}
+
+.DEFAULT_GOAL:=main
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#define UNUSED(x) ((void) (x))
-
-#define ALLOCATION_CHUNK (10UL)
-
-enum {
- NORMAL, BOLD, DARKNESS, ITALIC,
- UNDERLINE, BLINK, DUNNO_6, REVERSE,
- INVISIBLE
-};
-
-enum {
- GREY, RED, GREEN, YELLOW,
- BLUE, PINK, CYAN, WHITE,
- CANCEL
-};
-
-static char * buffer = NULL;
-static size_t buffer_size = 0;
-
-static void render_character(char * character) {
- write(STDOUT_FILENO, character, sizeof (*character));
-}
-
-static void render_string(char * string) {
- write(STDOUT_FILENO, string, strlen(string));
-}
-
-static void render_colour(int colour,
- int effect) {
- char format[8] = "\033[ ;3 m";
-
- format[2] = (char) (effect % 9) + '0';
- format[5] = (char) (colour % 8) + '0';
-
- render_string(format);
-}
-
-static void render_cancel(void) {
- render_string("\033[0m");
-}
-
-static int is_separator(char character) {
- if (( isascii(character))
- && (!isalnum(character))
- && (character != '_')) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static int compare_multiple_strings(char * string,
- const char * * strings,
- const int count) {
- int i = 0;
-
- do {
- if (!strcmp(string, strings[i])) {
- return 1;
- }
- } while (++i != count);
-
- return 0;
-}
-
-int main(int argc,
- char * * argv) {
- UNUSED(argc);
- UNUSED(argv);
-
- buffer = realloc(buffer, ALLOCATION_CHUNK);
-
- do {
- if (!((buffer_size + 1) % ALLOCATION_CHUNK)) {
- // Linear incremental reallocation (advanced)!
- size_t chunks = (buffer_size + 1) / ALLOCATION_CHUNK;
- buffer = realloc(buffer, ++chunks * ALLOCATION_CHUNK);
- }
- buffer[buffer_size] = '\0';
- read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer));
- ++buffer_size;
- } while (buffer[buffer_size - 1]);
-
- buffer[buffer_size - 1] = '\0';
-
- render_colour(RED, BOLD);
- render_string(buffer);
- render_cancel();
-
- free (buffer);
-
- return 0;
-}
+++ /dev/null
-default:
- gcc -g -Wall -Wextra -Wpedantic -o hl hl_xolatile.c
- clang -g -Weverything -o hl hl_xolatile.c
-
-# 'This shit requires to be in /usr/bin currently...'
-# 'There are unused functions that will be used, ignore now.'
-# 'Next please do [$ sudo cp hl /usr/bin/hl].'
-# 'Then test it with example [$ echo ABCDEF | valgrind hl].'
--- /dev/null
+#ifndef CHAD_H
+#define CHAD_H
+
+#include <stdbool.h>
+
+#define UNUSED(x) ((void)x)
+
+// Terminal manipulation
+#define TERMINAL_RESET "\033[0m"
+
+#define TERMINAL_COLOR_FG_BLACK "\033[30m"
+#define TERMINAL_COLOR_FG_RED "\033[31m"
+#define TERMINAL_COLOR_FG_GREEN "\033[32m"
+#define TERMINAL_COLOR_FG_YELLOW "\033[33m"
+#define TERMINAL_COLOR_FG_BLUE "\033[34m"
+#define TERMINAL_COLOR_FG_MAGENTA "\033[35m"
+#define TERMINAL_COLOR_FG_CYAN "\033[36m"
+#define TERMINAL_COLOR_FG_WHITE "\033[37m"
+
+#define TERMINAL_COLOR_BG_BLACK "\033[40m"
+#define TERMINAL_COLOR_BG_RED "\033[41m"
+#define TERMINAL_COLOR_BG_GREEN "\033[42m"
+#define TERMINAL_COLOR_BG_YELLOW "\033[43m"
+#define TERMINAL_COLOR_BG_BLUE "\033[44m"
+#define TERMINAL_COLOR_BG_MAGENTA "\033[45m"
+#define TERMINAL_COLOR_BG_CYAN "\033[46m"
+#define TERMINAL_COLOR_BG_WHITE "\033[47m"
+
+#define TERMINAL_STYLE_BOLD "\033[1m"
+#define TERMINAL_STYLE_ITALICS "\033[3m"
+#define TERMINAL_STYLE_REVERSE "\033[7m"
+
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <uthash.h>
+#include <ctype.h>
+#include <string.h>
+#include "chad.h"
+
+typedef void (*attribute_callback_t)(const char * const string,
+ const int length,
+ void * const attributes);
+
+typedef struct {
+ char * key;
+ attribute_callback_t callback;
+ UT_hash_handle hh;
+} display_t;
+display_t * display_table = NULL;
+
+typedef struct {
+ void * attributes;
+ struct hl_group_t * link;
+} hl_group_t;
+
+typedef enum {
+ KEYWORD,
+ MATCH,
+ REGION
+} token_t;
+
+typedef struct {
+ hl_group_t * hl;
+ token_t t;
+ char* syntax;
+} token; // XXX: this will have to be renamed
+
+/* Temp solution
+ */
+token * token_table[1000];
+int token_table_top = 0;
+
+token * new_token(const char * const syntax,
+ const token_t t,
+ const hl_group_t * const g) {
+ token * mt = (token*)malloc(sizeof(token));
+ mt->hl = g;
+ mt->t = t;
+ mt->syntax = syntax;
+ token_table[token_table_top++] = mt;
+ return mt;
+}
+
+void new_keyword_tokens(const char * const * words,
+ hl_group_t * const g) {
+ while (*words) {
+ new_token(*words, KEYWORD, g);
+ words = words + 1;
+ }
+}
+
+int token_fits(const char* const pattern,
+ const char* const to) {
+ if (pattern == NULL) {
+ return true;
+ }
+ for (int i = 0;; i++) {
+ if (pattern[i] == '\00') {
+ return i;
+ }
+ if (to[i] == '\00'
+ || pattern[i] != to[i]) {
+ return false;
+ }
+ }
+}
+
+bool is_word_separator(const char character) {
+ if (( isascii(character))
+ && (!isalnum(character))
+ && ( character != '_')) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void render_string(const char * const string,
+ const char * const mode) {
+ for (const char * s = string; *s != '\00';) {
+ int f;
+ int i = 0;
+ for (; i < token_table_top; i++) {
+ f = token_fits(token_table[i]->syntax, s);
+ if(f){ break; };
+ }
+ //
+ display_t * display;
+ HASH_FIND_STR(display_table, mode, display);
+ //
+ if(f){
+ display->callback(s, f, token_table[i]->hl->attributes);
+ s += f;
+ } else {
+ display->callback(s, 0, NULL);
+ ++s;
+ }
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "hl.h"
+
+#define ALLOCATION_CHUNK (10UL)
+
+static char * buffer = NULL;
+static size_t buffer_size = 0;
+
+typedef struct {
+ int attribute;
+ int foreground_color;
+ int background_color;
+} terminal_hl_t;
+
+void cterm_render_callback(const char * const string,
+ const int length,
+ void * const attributes) {
+ if(!length){
+ putchar(*string);
+ return;
+ }
+
+ UNUSED(attributes);
+ fputs(TERMINAL_STYLE_BOLD, stdout);
+ for (int i = 0; i < length; i++) {
+ putchar(*(string+i));
+ }
+ fputs(TERMINAL_RESET, stdout);
+}
+
+int main(int argc,
+ char * * argv) {
+ UNUSED(argc);
+ UNUSED(argv);
+
+ // Buffer init
+ buffer = realloc(buffer, ALLOCATION_CHUNK);
+
+ do {
+ if (!((buffer_size + 1) % ALLOCATION_CHUNK)) {
+ /* Linear incremental reallocation (advanced)!
+ */
+ size_t chunks = (buffer_size + 1) / ALLOCATION_CHUNK;
+ buffer = realloc(buffer, ++chunks * ALLOCATION_CHUNK);
+ }
+ buffer[buffer_size] = '\0';
+ read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer));
+ ++buffer_size;
+ } while (buffer[buffer_size - 1]);
+
+ buffer[buffer_size - 1] = '\0';
+
+ // Highlight init
+ const char * c_keywords[] = {
+ "register", "volatile", "auto", "const", "static", "extern", "if", "else",
+ "do", "while", "for", "continue", "switch", "case", "default", "break",
+ "enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof",
+ "char", "short", "int", "long", "signed", "unsigned", "float", "double",
+ NULL
+ };
+
+ const char * preprocessor_keywords[] = {
+ "#include", "#pragma", "#define", "#undef", "#ifdef", "#ifndef", "#elifdef", "#elifndef",
+ "#if", "#elif", "#else", "#endif", "#embed", "#line", "#error", "#warning",
+ NULL
+ };
+
+ terminal_hl_t my_hl = (terminal_hl_t) {
+ .attribute = 1
+ };
+
+ display_t * cterm = &(display_t) {
+ .key = "cterm",
+ .callback = cterm_render_callback
+ };
+ hl_group_t mygroup = (hl_group_t) {
+ .link = NULL
+ };
+
+ HASH_ADD_STR(display_table,
+ key,
+ cterm);
+ new_keyword_tokens(c_keywords, &mygroup);
+ new_keyword_tokens(preprocessor_keywords, &mygroup);
+
+ //
+ render_string(buffer, "cterm");
+ putchar('\n');
+ free (buffer);
+
+ return 0;
+}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#define ALLOCATION_CHUNK (1024UL)
-#define ALLOCATION_LIMIT (1024UL * 1024UL)
-
-#ifndef PROGRAM_NAME
-# define PROGRAM_NAME "hl"
-#endif
-
-enum { NORMAL, BOLD, DARKNESS, ITALIC, UNDERLINE, BLINK, DUNNO_6, REVERSE, INVISIBLE };
-enum { GREY, RED, GREEN, YELLOW, BLUE, PINK, CYAN, WHITE, CANCEL };
-
-static int colour_short_comment = GREY;
-static int colour_long_comment = GREY;
-static int colour_short_string = PINK;
-static int colour_long_string = RED;
-static int colour_separator = BLUE;
-static int colour_number = CYAN;
-static int colour_keyword = YELLOW;
-static int colour_preprocessor = YELLOW;
-static int colour_default = WHITE;
-
-static int effect_short_comment = BOLD;
-static int effect_long_comment = BOLD;
-static int effect_short_string = BOLD;
-static int effect_long_string = BOLD;
-static int effect_separator = BOLD;
-static int effect_number = BOLD;
-static int effect_keyword = BOLD;
-static int effect_preprocessor = BOLD;
-static int effect_default = BOLD;
-
-static unsigned long int buffer_size = 0;
-
-static void render_character (
- char character
-) {
- putchar (character);
-}
-
-static void render_string (
- char * string
-) {
- while (* string) render_character (* string++);
-}
-
-static void render_colour (
- int colour,
- int effect
-) {
- if (colour == CANCEL) {
- render_string ("\033[0m");
- return;
- }
-
- render_string ("\033[");
- render_character ((char) (effect % 9) + '0');
- render_string (";3");
- render_character ((char) (colour % 8) + '0');
- render_character ('m');
-}
-
-static int is_space (
- char character
-) {
- switch (character)
- {
- case ' ': case '\t': case '\r': case '\n':
- return (1);
- default:
- return (0);
- }
-}
-
-static int is_separator (
- char character
-) {
- switch (character)
- {
- case ' ': case '\t': case '\r': case '\n':
- case '+': case '-': case '*': case '/':
- case '(': case ')': case '[': case ']':
- case '{': case '}': case '<': case '>':
- case ';': case ':': case ',': case '.':
- case '!': case '&': case '|': case '?':
- case '~': case '^': case '%': case '=':
- return (1);
- default:
- return (0);
- }
-}
-
-static int compare_multiple_strings (
- char * string,
- const char ** strings,
- const int count
-) {
- int i = 0;
-
- do {
- if (strcmp (string, strings [i]) == 0) {
- return (1);
- }
- ++i;
- } while (i != count);
-
- return (0);
-}
-
-static int render_short_comment (
- char * buffer,
- int data_offset
-) {
- render_colour (colour_short_comment, effect_short_comment);
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- } while ((buffer [data_offset] != '\n') && (buffer [data_offset] != '\0'));
-
- render_character (buffer [data_offset]);
- ++data_offset;
-
- return (data_offset);
-}
-
-static int render_long_comment (
- char * buffer,
- int data_offset
-) {
- render_colour (colour_long_comment, effect_long_comment);
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- } while (((buffer [data_offset] != '/') ||
- (buffer [data_offset - 1] != '*')) &&
- (buffer [data_offset] != '\0'));
-
- render_character (buffer [data_offset]);
- ++data_offset;
-
- return (data_offset);
-}
-
-static int render_short_string (
- char * buffer,
- int data_offset
-) {
- render_colour (colour_short_string, effect_short_string);
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- if (buffer [data_offset - 1] == '\\') {
- render_character (buffer [data_offset]);
- ++data_offset;
- }
- } while ((buffer [data_offset] != '\'') && (buffer [data_offset] != '\0'));
-
- render_character (buffer [data_offset]);
- ++data_offset;
-
- return (data_offset);
-}
-
-static int render_long_string (
- char * buffer,
- int data_offset
-) {
- render_colour (colour_long_string, effect_long_string);
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- if (buffer [data_offset - 1] == '\\') {
- render_character (buffer [data_offset]);
- ++data_offset;
- }
- } while ((buffer [data_offset] != '"') && (buffer [data_offset] != '\0'));
-
- render_character (buffer [data_offset]);
- ++data_offset;
-
- return (data_offset);
-}
-
-static int render_separator (
- char * buffer,
- int data_offset
-) {
- if (is_space (buffer [data_offset]) != 0) {
- render_colour (WHITE, NORMAL);
- } else {
- render_colour (colour_separator, effect_separator);
- }
-
- render_character (buffer [data_offset]);
- ++data_offset;
-
- return (data_offset);
-}
-
-static int render_number (
- char * buffer,
- int data_offset
-) {
- render_colour (colour_number, effect_number);
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- } while ((is_separator (buffer [data_offset]) == 0) && (buffer [data_offset] != '\0'));
-
- return (data_offset);
-}
-
-static int render_word (
- char * buffer,
- int data_offset
-) {
- const char * c_keywords [32] = {
- "register", "volatile", "auto", "const", "static", "extern", "if", "else",
- "do", "while", "for", "continue", "switch", "case", "default", "break",
- "enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof",
- "char", "short", "int", "long", "signed", "unsigned", "float", "double"
- };
-
- const char * preprocessor_keywords [16] = {
- "#include", "#pragma", "#define", "#undef", "#ifdef", "#ifndef", "#elifdef", "#elifndef",
- "#if", "#elif", "#else", "#endif", "#embed", "#line", "#error", "#warning"
- };
-
- char * word = NULL;
-
- int i = 0;
-
- do {
- word = realloc (word, sizeof (* word) * (unsigned long int) (i + 1));
- word [i] = buffer [data_offset + i];
- ++i;
- } while ((is_separator (buffer [data_offset + i]) == 0) && (buffer [data_offset + i] != '\0'));
-
- word = realloc (word, sizeof (* word) * (unsigned long int) (i + 1));
- word [i] = '\0';
-
- if (compare_multiple_strings (word, c_keywords, 32) != 0) {
- render_colour (colour_keyword, effect_keyword);
- } else if (compare_multiple_strings (word, preprocessor_keywords, 16) != 0) {
- render_colour (colour_preprocessor, effect_preprocessor);
- } else {
- render_colour (colour_default, effect_default);
- }
-
- do {
- render_character (buffer [data_offset]);
- ++data_offset;
- } while ((is_separator (buffer [data_offset]) == 0) && (buffer [data_offset] != '\0'));
-
- free (word);
-
- return (data_offset);
-}
-
-void
-handle_buffer(
- char * buffer
-) {
- int offset = 0;
- while (buffer [offset] != '\0') {
- if ((buffer [offset] == '/') && (buffer [offset + 1] == '/')) {
- offset = render_short_comment (buffer, offset);
- } else if ((buffer [offset] == '/') && (buffer [offset + 1] == '*')) {
- offset = render_long_comment (buffer, offset);
- } else if (buffer [offset] == '\'') {
- offset = render_short_string (buffer, offset);
- } else if (buffer [offset] == '"') {
- offset = render_long_string (buffer, offset);
- } else if (is_separator (buffer [offset]) != 0) {
- offset = render_separator (buffer, offset);
- } else if ((buffer [offset] >= '0') && (buffer [offset] <= '9')) {
- offset = render_number (buffer, offset);
- } else {
- offset = render_word (buffer, offset);
- }
- render_colour (CANCEL, NORMAL);
- }
-}
-
-static char *
-slurp(const char * fn)
-{
- size_t len;
- char * b;
- FILE * fp = fopen(fn, "r");
- if (fp)
- {
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- rewind(fp);
- b = malloc(len);
- if (b &&
- len != fread(b, 1, len, fp))
- { perror(PROGRAM_NAME); }
- fclose(fp);
- return b;
- }
- else
- { return NULL; }
-}
-
-/* "Short" */
-#define SHORT_OPT(c,s) \
- if ((c == argv[0][0] && argv[0][1] == '\0') || \
- 0 == strncmp(argv[0], s, strlen(s)))
-
-#define OPT(s) \
- if (0 == strncmp(argv[0], s, strlen(s)))
-
-int main (
- int argc,
- char ** argv
-) {
- char * buffer = NULL;
-
- if (argc != 1) {
- (void) argv;
- while (++argv, --argc) {
- if (argv[0][0] == '-') {
- argv[0]++;
- SHORT_OPT ('?',"help") {
- fprintf (stderr, PROGRAM_NAME ": hl [OPTIONS] FILES ...\n");
- return (0);
- }
- OPT ("version") {
- fprintf(stderr, PROGRAM_NAME ": Version 9000\n");
- return (0);
- }
- else {
- fprintf (stderr, PROGRAM_NAME ": Unrecognized option '%s'\n", argv [0]);
- return (1);
- }
- } else {
- if ((buffer = slurp (argv [0]))) {
- handle_buffer (buffer);
- free (buffer);
- }
- }
- }
- return (0);
- }
-
- buffer = realloc (buffer, ALLOCATION_CHUNK);
-
-#define MEMFAIL(v) if (v == NULL) { perror(PROGRAM_NAME); return (1); }
- MEMFAIL(buffer);
-
- do {
- if ((buffer_size + 1) % ALLOCATION_CHUNK == 0) {
- buffer = realloc (buffer,
- ((buffer_size + 1)
- / ALLOCATION_CHUNK + 1)
- * ALLOCATION_CHUNK);
- MEMFAIL(buffer);
- }
- buffer [buffer_size] = '\0'; /* Fixing Valgrind warnings... */
- read (STDIN_FILENO, & buffer [buffer_size], sizeof (* buffer));
- ++buffer_size;
- } while ((buffer [buffer_size - 1] != '\0') /*||
- (buffer_size != ALLOCATION_LIMIT)*/);
-
- buffer [buffer_size - 1] = '\0';
-
- // Checking if short comments work...
- /* Checking if long comments work... */
-
- handle_buffer(buffer);
-
- free (buffer);
-
- return (0);
-}
+++ /dev/null
-#include <map>
-#include <vector>
-#include <stdio.h>
-
-typedef enum {
- BOLD,
- ITALICS,
- UNDERLINE,
- END
-} attr_t;
-
-typedef void (*attr_callback_t)(void);
-void bold_on(void){
- fputs("\033[1m", stdout);
-}
-void bold_off(void){
- fputs("\033[0m", stdout);
-}
-attr_callback_t attr_callbacks[END*2] = {
- (attr_callback_t)bold_on,
- (attr_callback_t)bold_off,
-};
-
-typedef int color;
-
-struct hl_t {
- attr_t attrs;
- color fg_color;
- color bg_color;
- //? font;
-};
-
-struct hl_group {
- char* name;
- std::map<char*, hl_t> o;
- hl_group* link;
-};
-
-typedef enum {
- KEYWORD,
- MATCH,
- REGION
-} token_t;
-
-struct token{
- hl_group* hl;
- token_t t;
- char* syntax;
-};
-
-std::vector<token*> token_table;
-
-token* newtoken(char* syntax, token_t t, hl_group* g){
- token* mt = new (token){
- .hl = g,
- .t = t,
- .syntax = syntax
- };
- token_table.push_back(mt);
- return mt;
-}
+++ /dev/null
-#include "Highlight.h"
-
-const char *const test_string = "this (test) is my test string which im with testing in this test";
-
-int fits(const char* const pattern, const char* const to){
- if(pattern == NULL){ return true; }
- for(int i = 0;; i++){
- if(pattern[i] == '\00'){ return i; }
- if(to[i] == '\00' or pattern[i] != to[i]){ return false; }
- }
-}
-
-void render_string(const char* const string, char* mode){
- for(const char* s = string; *s != '\00';){
- for(auto &i : token_table){
- int f;
- f = fits(i->syntax, s);
- if(f){
- int pos = i->hl->o.find(mode)->second.attrs;
- attr_callbacks[pos]();
- for(int h = 0; h < f; h++){
- putchar(*(s+h));
- }
- attr_callbacks[pos+1]();
- s += f;
- }else{
- putchar(*s);
- ++s;
- }
- }
- }
-}
-
-signed main(){
- hl_group mygroup = (hl_group){
- .name = "test",
- .link = NULL
- };
- mygroup.o["cterm"] = (hl_t){
- .attrs = BOLD
- };
- token* mytoken = newtoken("test", KEYWORD, &mygroup);
- render_string(test_string, "cterm");
- putchar('\n');
-}