UnixReview.com
June 2006
Listing 7: case.c
/* case - this file provides lcase, ucase, icase, ncase and cap ucase: ucase [-p var] string The string is converted to upper case and either: stored in the variable supplied with -p or printed to stdout if no variable is given lcase: lcase [-p VAR] STRING The STRING is converted to lower case and either: stored in the variable supplied with -p or printed to stdout if no variable is given icase: icase [-p var] string Upper case characters in string are converted to lower case and lower case characters in are converted to upper case and stored in the variable supplied with -p or printed to stdout if no variable is given ncase: ncase [-p var][-e][-E CHARS] string Letters in string are converted to both upper and lower case, enclosed in square brackets, non-alpha characters are retained as is OPTIONS -e The special characters (?*|\[] ) are escaped -E CHARLIST The characters in CHARLIST are escaped -p VAR The result is stored in the variable VAR cap: cap [-p var][-n N] string The first letter of each word is capitalized and the rest are converted to lowercase All non-alpha characters are considered word separators OPTIONS -n N Process only the first N words -p VAR The result is stored in the variable VAR Copyright 2006, Chris F.A. Johnson Released under the terms of the GNU General Public License, Version 2 */ /* Add the following lines to Makefile: case: case.o $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ case.o $(SHOBJ_LIBS) case.o: case.c */ #include "config.h" #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif #include <stdio.h> #include "builtins.h" #include "shell.h" #include "bashgetopt.h" lcase_builtin (list) WORD_LIST *list; { int n = 0; int ch; char *string; char *var = NULL; reset_internal_getopt (); while ((ch = internal_getopt (list, "p:")) != -1) switch(ch) { case 'p': var = list_optarg; break; default: builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } if (no_options (list)) return (EX_USAGE); string = list->word->word; while ( string[n] ) { string[n] = tolower(string[n]); ++n; } if ( var ) bind_variable (var, string, 0); else printf ("%s\n", string); return (EXECUTION_SUCCESS); } char *lcase_doc[] = { "The STRING is converted to lower case and either:", " stored in the variable supplied with -p", " or", " printed to stdout if no variable is given", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. */ struct builtin lcase_struct = { "lcase", /* builtin name */ lcase_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ lcase_doc, /* array of long documentation strings. */ "lcase [-p VAR] STRING", /* usage synopsis */ 0 /* reserved for internal use */ }; /* *************************************************************************** */ ucase_builtin (list) WORD_LIST *list; { int n = 0; int ch; char *string; char *var = NULL; reset_internal_getopt (); while ((ch = internal_getopt (list, "p:")) != -1) switch(ch) { case 'p': var = list_optarg; break; default: builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } string = list->word->word; while ( string[n] ) { string[n] = toupper(string[n]); ++n; } if ( var ) bind_variable (var, string, 0); else printf ("%s\n", string); return (EXECUTION_SUCCESS); } char *ucase_doc[] = { "The string is converted to upper case and either:", " stored in the variable supplied with -p", " or", " printed to stdout if no variable is given", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. */ struct builtin ucase_struct = { "ucase", /* builtin name */ ucase_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ ucase_doc, /* array of long documentation strings. */ "ucase [-p var] string", /* usage synopsis */ 0 /* reserved for internal use */ }; /* *************************************************************************** */ icase_builtin (list) WORD_LIST *list; { int n = 0; int ch; char *string; char *var = NULL; reset_internal_getopt (); while ((ch = internal_getopt (list, "p:")) != -1) switch(ch) { case 'p': var = list_optarg; break; default: builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } string = list->word->word; while ( string[n] ) { if ( islower(string[n]) ) string[n] = toupper(string[n]); else if ( isupper(string[n]) ) string[n] = tolower(string[n]); ++n; } if ( var ) bind_variable (var, string, 0); else printf ("%s\n", string); return (EXECUTION_SUCCESS); } char *icase_doc[] = { " Upper case characters in string are converted to lower case and", " lower case characters in are converted to upper case and", " stored in the variable supplied with -p", " or", " printed to stdout if no variable is given", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. */ struct builtin icase_struct = { "icase", /* builtin name */ icase_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ icase_doc, /* array of long documentation strings. */ "icase [-p var] string", /* usage synopsis */ 0 /* reserved for internal use */ }; /* *************************************************************************** */ ncase_builtin (list) WORD_LIST *list; { int n = 0; int nn = 0; int ch; int escape = 0; char *string; char *newstring; char *escchars = NULL ; char *var = NULL; reset_internal_getopt (); while ((ch = internal_getopt (list, "p:eE:")) != -1) switch(ch) { case 'e': escape = 1; break; case 'E': escchars = list_optarg; break; case 'p': var = list_optarg; break; default: builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } string = list->word->word; newstring = malloc( strlen(string) * 4 + 1); if ( newstring == NULL ) { return 5; } newstring[0] = '\0'; while ( string[n] ) { if ( islower(string[n]) || isupper(string[n]) ) { newstring[nn++] = '['; newstring[nn++] = toupper(string[n]); newstring[nn++] = tolower(string[n]); newstring[nn++] = ']'; } else if ( escape == 1 ) { switch (string[n]) { case ' ': case '*': case '[': case ']': case '?': case '\\': case '&': case '|': newstring[nn++] = '\\'; newstring[nn++] = string[n]; break; default: newstring[nn++] = string[n]; break; } } else if ( escchars != NULL ) { if ( strchr(escchars,string[n]) != NULL ) { newstring[nn++] = '\\'; } newstring[nn++] = string[n]; } else { newstring[nn++] = string[n]; } ++n; newstring[nn] = '\0'; } if ( var != NULL ) bind_variable (var, newstring, 0); else printf ("%s\n", newstring); return (EXECUTION_SUCCESS); } char *ncase_doc[] = { " Letters in string are converted to both upper and lower case,", " enclosed in square brackets, non-alpha characters are retained as is", "", " OPTIONS", " -e The special characters (?*|\\[] ) are escaped", " -E CHARLIST The characters in CHARLIST are escaped", " -p VAR The result is stored in the variable VAR", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. */ struct builtin ncase_struct = { "ncase", /* builtin name */ ncase_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ ncase_doc, /* array of long documentation strings. */ "ncase [-p var][-e][-E CHARS] string", /* usage synopsis */ 0 /* reserved for internal use */ }; /* *************************************************************************** */ cap_builtin (list) WORD_LIST *list; { int n = 0; int nn = 0; int ch; int escape = 0; int firstletter = 1; int num = 0; int max = 666; char *string; char *escchars = NULL ; char *var = NULL; reset_internal_getopt (); while ((ch = internal_getopt (list, "p:n:")) != -1) switch(ch) { case 'E': escchars = list_optarg; break; case 'n': max = atoi(list_optarg); break; case 'p': var = list_optarg; break; default: builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0 || list->next) { builtin_usage (); return (EX_USAGE); } string = list->word->word; while ( string[n] ) { if ( isalpha(string[n]) && firstletter == 1 ) { firstletter = 0; if ( num < max ) { string[n] = toupper(string[n]); } ++num; } else if ( isupper(string[n]) ) { string[n] = tolower(string[n]); } else if ( ! isalpha(string[n]) ) { firstletter = 1; } ++n; } if ( var != NULL ) bind_variable (var, string, 0); else printf ("%s\n", string); return (EXECUTION_SUCCESS); } char *cap_doc[] = { "", " The first letter of each word is capitalized and the rest", " are converted to lowercase", " All non-alpha characters are considered word separators", "", " OPTIONS", " -n N Process only the first N words", " -p VAR The result is stored in the variable VAR", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. */ struct builtin cap_struct = { "cap", /* builtin name */ cap_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ cap_doc, /* array of long documentation strings. */ "cap [-p var][-n N] string", /* usage synopsis */ 0 /* reserved for internal use */ };