/* * 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 */