CFCType* CFCType_new_object(int flags, CFCParcel *parcel, const char *specifier, int indirection) { // Validate params. if (indirection != 1) { CFCUtil_die("Parameter 'indirection' can only be 1"); } if (!specifier || !strlen(specifier)) { CFCUtil_die("Missing required param 'specifier'"); } if ((flags & CFCTYPE_INCREMENTED) && (flags & CFCTYPE_DECREMENTED)) { CFCUtil_die("Can't be both incremented and decremented"); } // Use default parcel if none supplied. if (!parcel) { parcel = CFCParcel_default_parcel(); } // Add flags. flags |= CFCTYPE_OBJECT; if (strstr(specifier, "String")) { // Determine whether this type is a string type. flags |= CFCTYPE_STRING_TYPE; } // Validate specifier. if (!isalpha(*specifier)) { CFCUtil_die("Invalid specifier: '%s'", specifier); } const char *small_specifier = specifier; while (!isupper(*small_specifier)) { if (!isalnum(*small_specifier) && *small_specifier != '_') { CFCUtil_die("Invalid specifier: '%s'", specifier); } small_specifier++; } if (!CFCSymbol_validate_class_name_component(small_specifier)) { CFCUtil_die("Invalid specifier: '%s'", specifier); } int acceptable_flags = CFCTYPE_OBJECT | CFCTYPE_STRING_TYPE | CFCTYPE_CONST | CFCTYPE_NULLABLE | CFCTYPE_INCREMENTED | CFCTYPE_DECREMENTED; S_check_flags(flags, acceptable_flags, "Object"); return CFCType_new(flags, parcel, specifier, 1); }
static int S_validate_class_cnick(const char *class_cnick) { // Allow all caps. const char *ptr; for (ptr = class_cnick; ; ptr++) { if (*ptr == 0) { if (strlen(class_cnick)) { return true; } else { break; } } else if (!isupper(*ptr)) { break; } } // Same as one component of a class name. return CFCSymbol_validate_class_name_component(class_cnick); }
CFCType* CFCType_new_object(int flags, CFCParcel *parcel, const char *specifier, int indirection) { // Validate params. if (indirection != 1) { CFCUtil_die("Parameter 'indirection' can only be 1"); } if (!specifier || !strlen(specifier)) { CFCUtil_die("Missing required param 'specifier'"); } if ((flags & CFCTYPE_INCREMENTED) && (flags & CFCTYPE_DECREMENTED)) { CFCUtil_die("Can't be both incremented and decremented"); } // Use default parcel if none supplied. if (!parcel) { parcel = CFCParcel_default_parcel(); } // Add flags. flags |= CFCTYPE_OBJECT; if (strstr(specifier, "CharBuf")) { // Determine whether this type is a string type. flags |= CFCTYPE_STRING_TYPE; } const size_t MAX_SPECIFIER_LEN = 256; char full_specifier[MAX_SPECIFIER_LEN + 1]; char small_specifier[MAX_SPECIFIER_LEN + 1]; if (isupper(*specifier)) { const char *prefix = CFCParcel_get_prefix(parcel); if (strlen(prefix) + strlen(specifier) > MAX_SPECIFIER_LEN) { CFCUtil_die("Specifier and/or parcel prefix too long"); } sprintf(full_specifier, "%s%s", prefix, specifier); strcpy(small_specifier, specifier); } else if (!isalpha(*specifier)) { CFCUtil_die("Invalid specifier: '%s'", specifier); } else { if (strlen(specifier) > MAX_SPECIFIER_LEN) { CFCUtil_die("Specifier too long"); } const char *probe = specifier; while (*probe) { if (isupper(*probe)) { break; } else if (!isalnum(*probe) && *probe != '_') { CFCUtil_die("Invalid specifier: '%s'", specifier); } probe++; } strcpy(full_specifier, specifier); strcpy(small_specifier, probe); } if (!CFCSymbol_validate_class_name_component(small_specifier)) { CFCUtil_die("Invalid specifier: '%s'", specifier); } // Cache C representation. char c_string[MAX_SPECIFIER_LEN + 10]; if (flags & CFCTYPE_CONST) { sprintf(c_string, "const %s*", full_specifier); } else { sprintf(c_string, "%s*", full_specifier); } int acceptable_flags = CFCTYPE_OBJECT | CFCTYPE_STRING_TYPE | CFCTYPE_CONST | CFCTYPE_NULLABLE | CFCTYPE_INCREMENTED | CFCTYPE_DECREMENTED; S_check_flags(flags, acceptable_flags, "Object"); return CFCType_new(flags, parcel, full_specifier, 1, c_string); }