/* ** File: hey_format.c ** Desc: Reading & formatting functions for 'hey' ** Auth: Cian Synnott ** Date: Sun Nov 15 19:56:51 GMT 1998 */ #include #include #include #include "hey_format.h" #include "config.h" #include "aux.h" #ifdef HAVE_LIBREADLINE /* readline includes */ #include #include #endif #define LINESIZE 128 /* Should be plenty */ /* Buffer to keep things in */ dyn_page *hey_page = NULL; /* Read user input into hey_page, also allocates it & suchlike */ void hey_user_input(void) { /* return from readline is char *, not good, but hey ! */ #ifdef HAVE_LIBREADLINE char *line; #else char line[LINESIZE]; #endif char *ptr; int len; /* Allocate hey_page, passing hey_wrap as the word wrapping width */ if (!(hey_page = dyn_pageAlloc(hey_wrap))) printerr_exit ("Woah. Error allocating hey_page.\n"); /* Read from standard input until end of file, store in hey_page, ** cleaning up any dodgy whitespace */ /* just use readline instead */ #ifdef HAVE_LIBREADLINE while ((line=readline(NULL))){ #else while (fgets(line, LINESIZE, stdin)) { #endif len = strlen(line); /* Remove newlines from strings that don't consist merely of ** them ... */ /* Readline is _supposed_ to do this itself */ #ifndef HAVE_LIBREADLINE if (len > 1) if (line[len - 1] == '\n') line[len -1] = 0; #endif /* Clean up whitespace */ for (ptr = line; *ptr; ptr++) switch (*ptr) { case '\t': case '\f': case '\r': case '\n': *ptr = ' '; } /* Append line to page */ dyn_pageAppend(hey_page, line); } /* And that's that ... */ return; } /* Prototype for strprint(); see below ... */ char *strprint(char *, int, char *, ...); /* Formats the lines present in hey_page into the 'hey' to be sent. */ void hey_format_input(void) { dyn_page *new_format; char line[LINESIZE]; char *ptr; int offset, topwidth; int width = strlen(hey_title) + 2; /* Calculate the width of the hey .. It's either the strlen (hey_title) ** + 2 (spaces on either side), or the longest string in hey_page ** Then add 4 for the space on either side of the message & ** the side border chars */ if(!(ptr = dyn_pageRead(hey_page))) return; do { if (strlen(ptr) > width) width = strlen(ptr); } while ((ptr = dyn_pageRead(NULL))); width += 4; /* Set up the offset to print before each line (thus centering it ...) */ offset = ((80 - width) / 2); /* Allocate the new page, with no wrapping width */ if (!(new_format = dyn_pageAlloc(0))) printerr_exit("Woah. Error allocating formatted page.\n"); /* Print top line into it */ if (!strlen(hey_title)) strprint(line, LINESIZE, "%xc%c%xc%c", ' ', offset, B_TOPLFT, B_TOP, width - 2, B_TOPRHT); else { /* The total number of 'top' border chars we'll have to print is the ** the width minus two chars for the corners, two chars for the spaces ** either side of the title, and the length of the title itself */ topwidth = width - 4 - strlen(hey_title); strprint(line, LINESIZE, "%xc%c%xc %s %xc%c", ' ', offset, B_TOPLFT, B_TOP, topwidth / 2, hey_title, B_TOP, topwidth - (topwidth / 2), B_TOPRHT); } dyn_pageAppend(new_format, line); /* Print all the other lines into it */ if(!(ptr = dyn_pageRead(hey_page))) return; do { /* Format the line & append to new page */ strprint(line, LINESIZE, "%xc%c %s%xc%c", ' ', offset, B_LFT, ptr, ' ', width - 3 - strlen(ptr), B_RHT); dyn_pageAppend(new_format, line); } while ((ptr = dyn_pageRead(NULL))); strprint(line, LINESIZE, "%xc%c%xc%c", ' ', offset, B_BOTLFT, B_BOT, width - 2, B_BOTRHT); dyn_pageAppend(new_format, line); /* Free the old hey_page, and point at the new formatted one */ dyn_pageFree(hey_page); hey_page = new_format; return; } /* A little like a stripped-down version of snprintf. Accepts only string and ** character arguments, and only one modifier - x, meaning that the argument ** after the string or char will be the number of times to repeat it. */ char *strprint(char *str, int size, char *fmt, ...) { char *str_p, *fmt_p, *str_arg, char_arg; va_list args; int multiple; /* Clear the string and setup the va_* macros */ memset(str, 0, size); va_start(args, fmt); str_p = str; fmt_p = fmt; /* Cycle through the format string */ while (*fmt_p && (str_p - str) < size) { if (*fmt_p == '%') { multiple = 1; char_arg = 0; str_arg = 0; fmt_p++; switch (*fmt_p) { case 'c': char_arg = va_arg(args, char); break; case 's': str_arg = va_arg(args, char *); break; case 'x': fmt_p++; if (*fmt_p == 'c') char_arg = va_arg(args, char); if (*fmt_p == 's') str_arg = va_arg(args, char *); multiple = va_arg(args, int); break; default: return NULL; } fmt_p++; /* Concat the char or string arg onto the end of str 'multiple' ** times */ while (multiple && (str_p - str) < size) { if (str_arg) { strncat(str, str_arg, size - strlen(str)); str_p += strlen(str_arg); } else if (char_arg) { *str_p = char_arg; str_p++; } multiple--; } } else { *str_p = *fmt_p; str_p++, fmt_p++; } } /* Set the last character to 0 if necessary */ if ((str_p - str) >= size) str[size - 1] = 0; /* Finish & return */ va_end(args); return str; }