commit d6e408e4b8d1329d1047b693a565b904112e2edb Author: heinzel Date: Mon Feb 20 13:48:25 2012 +0100 Initial commit. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e86a007 --- /dev/null +++ b/COPYING @@ -0,0 +1,3 @@ +Author: Jens Kleineheismann +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e28c283 --- /dev/null +++ b/INSTALL @@ -0,0 +1,13 @@ +To build typomix, run the following commands: +./configure +make + +To build a static binary, run: +./configure --static +make + +To install the binary and the man page, run: +make install + +To only install the binary, run: +make install-bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a72bf8f --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +help: + @echo "Run ./configure first!" + @echo "Or even better: take a look at the file INSTALL." +install: help +all: help diff --git a/Makefile.dist b/Makefile.dist new file mode 100644 index 0000000..a72bf8f --- /dev/null +++ b/Makefile.dist @@ -0,0 +1,5 @@ +help: + @echo "Run ./configure first!" + @echo "Or even better: take a look at the file INSTALL." +install: help +all: help diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..7921039 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,72 @@ +# @Makefile.in@ + +PREFIX := @PREFIX@ +BINDIR := @BINDIR@ +MAN1DIR := @MAN1DIR@ + +MAIN := typomix +OBJS := typomix.o +#LIBS := +MAN1 := typomix.1 + +MANGZ := @MANGZ@ +ifeq ($(MANGZ), 1) + MAN1 := $(addsuffix .gz, $(MAN1)) +endif + +CC := @CC@ +CP := @CP@ +GZIP := @GZIP@ +INSTALL := @INSTALL@ +RM := @RM@ +STRIP := @STRIP@ +TAR := @TAR@ + +.PHONY: help strip install install-bin install-man install-man1 uninstall \ + clean distclean mrproper dist +.DEFAULT: $(MAIN) + +$(MAIN): $(OBJS) +ifeq (@STATIC@, 1) + $(CC) --static -g -o $(MAIN) $(LIBS) $(OBJS) +else + $(CC) -g -o $(MAIN) $(LIBS) $(OBJS) +endif + +%.o : %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +help: + @echo "There is no help." + +strip: $(MAIN) + $(STRIP) $(MAIN) + +install: install-bin install-man + +install-bin: strip + $(INSTALL) $(MAIN) $(BINDIR) + +install-man: install-man1 + +install-man1: $(MAN1) + $(INSTALL) $^ $(MAN1DIR) + +%.gz : % + $(GZIP) -c $< > $@ + +uninstall: + -$(RM) $(BINDIR)/$(MAIN) + cd $(MAN1DIR) ; -$(RM) $(MAN1) + +clean: + $(RM) -f *.o $(MAIN) + +distclean: clean + $(CP) Makefile.dist Makefile +mrproper: distclean + +dist: distclean + cd .. ; $(TAR) -czf $(notdir $(PWD)).tar.gz $(notdir $(PWD)) + +#end diff --git a/configure b/configure new file mode 100755 index 0000000..bb71323 --- /dev/null +++ b/configure @@ -0,0 +1,290 @@ +#!/bin/sh +# +# configure +# +# A simple script to configure Makefiles +# (i.e. read Makefile.in, replace strings and write Makefile). +# +# heinzel +# +VERSION='configure Version 0.3 (08.Sep.2011 heinzel)' + +### config ### +FILES="" +FILES_DEF="configure.files" + +TEMPLATE_SUFFIX=".in" +MACROS_DEF="configure.macros" + +MACROS="CTEMPLATE" +MACRO_CTEMPLATE="@CFILE@ (created by configure script)" + +### functions ### +function print_help() { + cat </dev/null ; then + MACROS="$MACROS ${name}" + fi +} + +function eval_macro() { + local name="$1" + local text="" + local return="" + + eval text="\$MACRO_${name}" + while : ; do + # Test if text contains more macros. + echo "$text" | grep -E "@[A-Z][A-Z0-9]*@" >/dev/null + r=$? + if test "1${r}" != "10" ; then + # Text is macro free. + return="$text" + break + else + # Get the last macro name from text... + sm_name="`echo $text | sed -e 's=^.*@\([A-Z][A-Z0-9]*\)@.*$=\1='`" + # Resolve it... + sm_text="`eval_macro $sm_name`" + # Substitute macro... + text="`echo $text | sed -e 's=@'${sm_name}'@='${sm_text}'=g'`" + fi + done + + echo "$return" +} + +function load_defaults() { + local inc="${MACROS_DEF:-configure.macros}" + local i=0 + local line="" + + if test "X${inc}" = "X" ; then + return 1 + fi + if test ! -r "$inc" -o -d "$inc" ; then + echo "${inc}: not a readable file." >&2 + return 1 + fi + + while read line ; do + i="`expr $i + 1`" + case "$line" in + \#*|\ *|'') + continue + ;; + *=*) + set_macro "$line" + ;; + *) + echo "Warning: $inc: unexpected line ($i)." >&2 + ;; + esac + done < "$inc" +} + +function configure() { + local file="$1" + local ext="${TEMPLATE_SUFFIX:-.in}" + local template="" + + local static_file="" + + local expr="" + local name="" + local text="" + + if test "X${file}" = "X" ; then + echo "No filename given." >&2 + return 1 + fi + template="${file}${ext}" + if test ! -r "$template" -o -d "$template" ; then + echo "$file: cannot read template ($template)." + return 1 + fi + + set_macro CFILE="$file" + ctext="`eval_macro CTEMPLATE`" + cexpr="s=@${template}@=${ctext}=g" + + if test "X${CONFIGURE_STATIC_FILE}" != "X" ; then + static_file="$CONFIGURE_STATIC_FILE" + expr="`cat \"$static_file\"`" + else + static_file="`mktemp configure.tmp.XXXXXX`" + if test "1$?" -ne "10" -o "X${static_file}" = "X" \ + -o ! -w "$static_file" ; then + echo "Cannot create temp file." >&2 + return 1 + fi + CONFIGURE_STATIC_FILE="$static_file" + + expr="" + for name in $MACROS ; do + case "$name" in + CFILE|CTEMPLATE) + continue + ;; + esac + text="`eval_macro $name`" + expr="s=@$name@=$text=g +$expr" + done + + echo "$expr" > "$static_file" + fi + + sed -e "$cexpr" -e "$expr" "$template" > "$file" +} + +function clean_up() { + if test "X${CONFIGURE_STATIC_FILE}" != "X" -a -f "$CONFIGURE_STATIC_FILE" ; then + rm "$CONFIGURE_STATIC_FILE" + fi +} + +### set options ### +load_defaults + +while test "1$#" -gt "10" ; do +case "$1" in +-h|--help) + print_help + exit 0 + ;; +-V|--version) + print_version + exit 0 + ;; +--with-*|--without-*) + set_macro "$1" + shift + ;; +--enable-*|--disable-*) + set_macro "$1" + shift + ;; +--*=*) + set_macro "$1" + shift + ;; +--*) + case "$2" in + ''|-*) + set_macro "${1}=1" + shift + ;; + *) + set_macro "$1" "$2" + shift + shift + ;; + esac + ;; +esac +done + +### action ### + +files="$FILES" +if test "X${FILES_DEF}" != "X" -a -f "$FILES_DEF" ; then + while read line ; do + files="$files $line" + done < "$FILES_DEF" +fi + + +if test "X${files}" = "X" ; then + echo "No files to configure." >&2 + echo " Make sure '$FILES_DEF' is there and readable." >&2 + exit 1 +fi + +for f in $files ; do + echo "Creating file $f..." + configure $f +done + +clean_up +### end ### diff --git a/configure.files b/configure.files new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/configure.files @@ -0,0 +1 @@ +Makefile diff --git a/configure.macros b/configure.macros new file mode 100644 index 0000000..80912f3 --- /dev/null +++ b/configure.macros @@ -0,0 +1,35 @@ +# configure.macros + +# Directories +PREFIX="/usr/local" +BINDIR="@PREFIX@/bin" +SBINDIR="@PREFIX@/sbin" +MANDIR="@PREFIX@/share/man" +MAN1DIR="@MANDIR@/man1" +MAN2DIR="@MANDIR@/man2" +MAN3DIR="@MANDIR@/man3" +MAN4DIR="@MANDIR@/man4" +MAN5DIR="@MANDIR@/man5" +MAN6DIR="@MANDIR@/man6" +MAN7DIR="@MANDIR@/man7" +MAN8DIR="@MANDIR@/man8" +MAN9DIR="@MANDIR@/man9" + +# Programms +CAT="cat" +CC="cc" +CP="cp" +GZIP="gzip" +INSTALL="install" +RM="rm" +SHELL="/bin/sh" +STRIP="strip" +TAR="tar" +ZCAT="zcat" + +# Magic macros +# @CFILE@ will be expanded to the name of the file, that will be created. +# Also the current template name (e.g. @Makefile.in@) can be used as a macro +# that will be expanded to another macro named CTEMPLATE (which can be +# defined here or will default to a buildin text). +#end diff --git a/typomix.1 b/typomix.1 new file mode 100644 index 0000000..083230d --- /dev/null +++ b/typomix.1 @@ -0,0 +1,31 @@ +.\" typomix.1 +.TH TYPOMIX 1 "Feb. 2012" "heinzel" "User Commands" + +.SH NAME +typomix \- scrambles letters within words + +.SH SYNOPSIS +.B typomix +[\fIOPTION\fR]... [\fIFILE\fR]... + +.SH DESCRIPTION +.B typomix +scrambles letters within words. +.TP +If no FILE is given, input will be read from stdin. + +.SH OPTIONS +.TP +.B -h +Print a short help text. +.TP +.B -V +Print the version number. + +.SH BUGS +.B typomix +is not useful at all. + +.SH AUTHOR +heinzel + diff --git a/typomix.c b/typomix.c new file mode 100644 index 0000000..a2df0b6 --- /dev/null +++ b/typomix.c @@ -0,0 +1,237 @@ +/* + * typomix.c + * + * Jens Kleineheismann + */ + +/* include headers */ +#include +#include +#include +#include +#include +#include +#include + +/* symbols */ +#define TRUE 1 +#define FALSE 0 +#define VERSION "0.5" + +/* prototypes */ +int print_version(void); +int print_help(void); +char *scramble(char *word); +int xisalpha(char c); + +/* definition of extern objects */ +char *progname; +const char *version = VERSION; + +/* + * main + */ + +int main( int argc, char *argv[] ) { + int i; + int j; + char c; + char *p; + char *word; + FILE **input = NULL; + FILE **intemp = NULL; + size_t extend = 1024; + size_t maxlen; + + /* Store program name without path */ + if( (progname = strdup(basename(argv[0]))) == NULL ) { + fprintf(stderr, "%s: ", basename(argv[0])); + perror(NULL); + exit(EX_OSERR); + } + + /* Initialize the random generator once here for scramble() */ + srand( (unsigned int) time((time_t *)NULL) ); + + /* Initialize array of input streams */ + if( (input = malloc(1 * sizeof(FILE*))) == NULL ) { + fprintf(stderr, "%s: ", progname); + perror(NULL); + exit(EX_OSERR); + } + input[0] = NULL; + + /* Parse command line options */ + for( i = 1 ; i < argc ; i++ ) { + if(!strncmp("--", argv[i], 2)) { + /* Current argument is a word option */ + if(!strcmp( "--help", argv[i])) { + print_help(); + exit(EX_OK); + } else if(!strcmp("--version", argv[i])) { + print_version(); + exit(EX_OK); + } else { + fprintf(stderr, "%s: invalid option '%s'\n", progname, argv[i]); + fprintf(stderr, "Try '%s -h' for help.\n", progname); + exit(EX_USAGE); + } + } else if(!strncmp("-", argv[i], 1)) { + /* Current argument is one or more char options */ + p = argv[i]; + for( j = 1 ; (c = p[j]) != '\0' ; j++) { + switch(c) { + case 'h': + print_help(); + exit(EX_OK); + break; + case 'V': + print_version(); + exit(EX_OK); + break; + default: + fprintf(stderr, "%s: invalid option -- %c\n", progname, c); + fprintf(stderr, "Try '%s -h' for help.\n", progname); + exit(EX_USAGE); + } + } + } else { + /* Argument */ + j = 0; + while(input[j++] != NULL); + + intemp = input; + if( (input = malloc((j + 1) * sizeof(FILE*))) == NULL ) { + fprintf(stderr, "%s: ", progname); + perror(NULL); + exit(EX_OSERR); + } + j = 0; + while(intemp[j] != NULL) { + input[j] = intemp[j]; + j++; + } + + free(intemp); + + if( (input[j++] = fopen(argv[i], "r")) == NULL ) { + fprintf(stderr, "%s: %s: ", progname, argv[i]); + perror(NULL); + } + + input[j] = NULL; + } + } + + if( input[0] == NULL ) { + if( (input = malloc(2 * sizeof(FILE*))) == NULL ) { + fprintf(stderr, "%s: ", progname); + perror(NULL); + exit(EX_OSERR); + } + + input[0] = stdin; + input[1] = NULL; + } + + for( i = 0 ; input[i] != NULL ; i++) { + word = p = NULL; + maxlen = j = 0; + while( (c = getc(input[i])) != EOF ) { + if(xisalpha(c)) { + if(j >= maxlen) { + p = word; + if( (word = malloc((maxlen + extend) )) == NULL ) { + fprintf(stderr, "%s: ", progname); + perror(NULL); + exit(EX_OSERR); + } + maxlen += extend; + if(p) { + strcpy(word, p); + free(p); + } + } + word[j++] = c; + } else if(word) { + + word[j] = '\0'; + scramble(word); + j = 0; + while(word[j] != '\0') { + putchar(word[j++]); + } + free(word); + word = NULL; + maxlen = 0; + j = 0; + putchar(c); + } else { + putchar(c); + } + } + } + exit(EX_OK); +} + +int print_version( void ) { + printf("%s Version %s\n",progname, version); + return TRUE; +} + +int print_help( void ) { + printf("\n"); + printf("typomix scrambles letters within words.\n"); + printf("\n"); + printf("Usage: typomix [OPTIONS] [FILE]...\n"); + printf("\n"); + printf("If no file is given, input will be read from stdin.\n"); + printf("\n"); + printf("Options:\n"); + printf(" -h, --help\n"); + printf(" -V, --version\n"); + printf("\n"); + return TRUE; +} + +char *scramble(char *word) { + int i; + int j; + char c; + size_t len; + + len = strlen(word); + + /* To short to scramble */ + if( len < 4 ) + return word; + + + for( i = j = 1 ; i < (len - 1) ; i++) { + j = 1 + (int)((float)(len - 2) * rand()/(RAND_MAX+1.0)); + if( i != j ) { + c = word[i]; + word[i] = word[j]; + word[j] = c; + //fprintf(stderr, "%d <-> %d: %s\n", i, j, word); + } + } + return word; +} + +int xisalpha(char c) { + switch(c) { + case 'ä': + case 'ö': + case 'ü': + case 'Ä': + case 'Ö': + case 'Ü': + case 'ß': + return 1; + } + + return isalpha(c); +} + +/* end */