#define STR_TYPE_EMPTY (1 << 0) #define STR_TYPE_BINARY (1 << 1) #define STR_TYPE_ALPHABETIC (1 << 2) #define STR_TYPE_ALPHANUMERIC (1 << 3) #define STR_TYPE_ASCII (1 << 4) #define STR_TYPE_UNICODE (1 << 5) #define STR_TYPE_HEXADECIMAL (1 << 6) #define STR_TYPE_UPPERCASE (1 << 7) #define STR_TYPE_LOWERCASE (1 << 8) #define STR_TYPE_SPACE (1 << 9) #define STR_TYPE_PUNCTUATION (1 << 10) #define STR_TYPE_PRINTABLE (1 << 11) #define STR_TYPE_GRAPH (1 << 12) #define STR_TYPE_DIGIT (1 << 13) #define STR_TYPE_CONTROL (1 << 14) #define STR_TYPE_BLANK (1 << 15) #define STR_TYPE_ADD_TYPE(STR, STR_TYPE) (STR).type |= STR_TYPE; #define STR_TYPE_REMOVE_TYPE(STR, STR_TYPE) (STR).type &= ~STR_TYPE; // uses ctypes.h, unknows if safe or portable #include #define range_BINARY(ch) (ch=='0'||ch=='1') #define range_UNICODE(ch) (ch==ch) /* to be improved */ #define range_ALPHABETIC(ch) isalpha((unsigned char) ch) #define range_ALPHANUMERIC(ch) isalnum((unsigned char) ch) #define range_ASCII(ch) isascii((unsigned char) ch) #define range_HEXADECIMAL(ch) isxdigit((unsigned char) ch) #define range_UPPERCASE(ch) isupper((unsigned char) ch) #define range_LOWERCASE(ch) islower((unsigned char) ch) #define range_SPACE(ch) isspace((unsigned char) ch) #define range_PUNCTUATION(ch) ispunct((unsigned char) ch) #define range_PRINTABLE(ch) isprint((unsigned char) ch) #define range_GRAPH(ch) isgraph((unsigned char) ch) #define range_DIGIT(ch) isxdigit((unsigned char) ch) #define range_CONTROL(ch) iscntrl((unsigned char) ch) #define range_BLANK(ch) isblank((unsigned char) ch) // this is not consistant throughout strings and is currently only the representation of the last character added // if a flag gets disabled it should not be allowed to become re-enabled unless on the event of an undo #define AUTOTYPE_TEST_(AUTOSTR, AUTOCH, AUTORANGE, AUTOTYPE) { \ \ /* AUTORANGE */ \ if(range_##AUTORANGE(AUTOCH)) { \ if ((AUTOSTR).type == STR_TYPE_EMPTY) { \ STR_TYPE_REMOVE_TYPE((AUTOSTR), STR_TYPE_EMPTY) \ } \ STR_TYPE_ADD_TYPE((AUTOSTR), STR_TYPE_##AUTOTYPE) \ } \ else { \ STR_TYPE_REMOVE_TYPE((AUTOSTR), STR_TYPE_##AUTOTYPE) \ } \ } #define AUTOTYPE_TEST(AUTOSTR, AUTOCH, AUTOTYPE) AUTOTYPE_TEST_(AUTOSTR, AUTOCH, AUTOTYPE, AUTOTYPE) #define AUTOTYPE(str, ch) { \ AUTOTYPE_TEST((str), (ch), BINARY) \ AUTOTYPE_TEST((str), (ch), ALPHABETIC) \ AUTOTYPE_TEST((str), (ch), ALPHANUMERIC) \ AUTOTYPE_TEST((str), (ch), ASCII) \ AUTOTYPE_TEST((str), (ch), UNICODE) \ AUTOTYPE_TEST((str), (ch), HEXADECIMAL) \ AUTOTYPE_TEST((str), (ch), UPPERCASE) \ AUTOTYPE_TEST((str), (ch), LOWERCASE) \ AUTOTYPE_TEST((str), (ch), SPACE) \ AUTOTYPE_TEST((str), (ch), PUNCTUATION) \ AUTOTYPE_TEST((str), (ch), PRINTABLE) \ AUTOTYPE_TEST((str), (ch), GRAPH) \ AUTOTYPE_TEST((str), (ch), DIGIT) \ AUTOTYPE_TEST((str), (ch), CONTROL) \ AUTOTYPE_TEST((str), (ch), BLANK) \ } #define TYPECHECK(str, type_) { \ if ((str).type & type_) puts(#type_); \ } #define TYPEINFO(str) { \ printf("(%s).type = %d\n", #str, (str).type); \ TYPECHECK((str), STR_TYPE_EMPTY) \ TYPECHECK((str), STR_TYPE_BINARY) \ TYPECHECK((str), STR_TYPE_ALPHABETIC) \ TYPECHECK((str), STR_TYPE_ALPHANUMERIC) \ TYPECHECK((str), STR_TYPE_ASCII) \ TYPECHECK((str), STR_TYPE_UNICODE) \ TYPECHECK((str), STR_TYPE_HEXADECIMAL) \ TYPECHECK((str), STR_TYPE_UPPERCASE) \ TYPECHECK((str), STR_TYPE_LOWERCASE) \ TYPECHECK((str), STR_TYPE_PUNCTUATION) \ TYPECHECK((str), STR_TYPE_PRINTABLE) \ TYPECHECK((str), STR_TYPE_GRAPH) \ TYPECHECK((str), STR_TYPE_DIGIT) \ TYPECHECK((str), STR_TYPE_CONTROL) \ TYPECHECK((str), STR_TYPE_BLANK) \ }