From d6e408e4b8d1329d1047b693a565b904112e2edb Mon Sep 17 00:00:00 2001 From: heinzel Date: Mon, 20 Feb 2012 13:48:25 +0100 Subject: [PATCH] Initial commit. --- COPYING | 3 + INSTALL | 13 +++ Makefile | 5 + Makefile.dist | 5 + Makefile.in | 72 ++++++++++++ configure | 290 +++++++++++++++++++++++++++++++++++++++++++++++ configure.files | 1 + configure.macros | 35 ++++++ typomix.1 | 31 +++++ typomix.c | 237 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 692 insertions(+) create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 Makefile.dist create mode 100644 Makefile.in create mode 100755 configure create mode 100644 configure.files create mode 100644 configure.macros create mode 100644 typomix.1 create mode 100644 typomix.c 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 */