Type * TypeAllocVar(Var * var) { Type * type; type = TypeAlloc(TYPE_VAR); type->typevar = var; return type; }
Type * TypeAllocArg(UInt8 arg_no, Type * arg_type) { Type * type; type = TypeAlloc(TYPE_ARG); type->arg_no = arg_no; type->arg_type = arg_type; return type; }
Type * ParseTypeInline() /* Syntax: "+" full_type | "(" full_type ")" | normal_type | identifier | int ".." exp | "-" int ".." exp */{ Type * type = NULL; Var * var; UInt16 bookmark; BigInt * bi; PARSE_INLINE = true; if (TOK == TOKEN_OPEN_P || TOK == TOKEN_PLUS) { type = ParseType2(INSTR_TYPE); } else { type = ParseType3(); if (!TOK) return NULL; if (type != NULL) return type; if (ParseArg(&var)) { type = TypeAllocVar(var); } else if (TOK == TOKEN_ID) { bookmark = SetBookmark(); var = ParseVariable(); if (TOK) { if (var->mode == INSTR_TYPE) { type = var->type; } else if (var->mode == INSTR_VAR && var->type->variant == TYPE_TYPE) { type = var->type_value; } else { ErrArg(var); SyntaxErrorBmk("Variable [A] does not define type.", bookmark); } } } else if (TOK == TOKEN_INT || TOK == TOKEN_MINUS) { type = TypeAlloc(TYPE_INT); bi = ParseIntConstExpression(NULL); if (TOK) { IntModify(&type->range.min, bi); if (NextIs(TOKEN_DOTDOT)) { bi = ParseIntConstExpression(NULL); if (TOK) { IntModify(&type->range.max, bi); } } else { IntModify(&type->range.max, &type->range.min); } } } } return type; }
Type* GetCharArrayType (unsigned Len) /* Return the type for a char array of the given length */ { /* Allocate memory for the type string */ Type* T = TypeAlloc (3); /* array/char/terminator */ /* Fill the type string */ T[0].C = T_ARRAY; T[0].A.L = Len; /* Array length is in the L attribute */ T[1].C = GetDefaultChar (); T[2].C = T_END; /* Return the new type */ return T; }
Type* PointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ { /* Get the size of the type string including the terminator */ unsigned Size = TypeLen (T) + 1; /* Allocate the new type string */ Type* P = TypeAlloc (Size + 1); /* Create the return type... */ P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE); memcpy (P+1, T, Size * sizeof (Type)); /* ...and return it */ return P; }
void TranslateInit() { Var * var; UInt8 i; Type * type; // Create RULE procedure and allocate it's arguments type = TypeAlloc(TYPE_PROC); RULE_PROC = VarAlloc(INSTR_VAR, NULL, 0); RULE_PROC->type = type; for(i=0; i<MACRO_ARG_CNT; i++) { var = VarAllocScope(RULE_PROC, INSTR_VAR, NULL, i+1); var->submode = SUBMODE_ARG_IN; MACRO_ARG_VAR[i] = var; } RuleSetInit(&TRANSLATE_RULES); RuleSetInit(&INSTR_RULES); }
Type* GetImplicitFuncType (void) /* Return a type string for an inplicitly declared function */ { /* Get a new function descriptor */ FuncDesc* F = NewFuncDesc (); /* Allocate memory for the type string */ Type* T = TypeAlloc (3); /* func/returns int/terminator */ /* Prepare the function descriptor */ F->Flags = FD_EMPTY | FD_VARIADIC; F->SymTab = &EmptySymTab; F->TagTab = &EmptySymTab; /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); T[0].A.P = F; T[1].C = T_INT; T[2].C = T_END; /* Return the new type */ return T; }
int main(int argc, char *argv[]) { int found, j, value; unsigned k, kk; char *s, *t; char *type_list = 0; char bfr[MAXPATHLEN]; caseless = C_VALUE; while ((j = getopt(argc, argv, "cD:e:iI:prt:U:vVwW:x")) != EOF) { switch (j) { case 'V': printf("conflict %s\n", RELEASE); return (EXIT_SUCCESS); case 'c': caseless = 0; break; case 'i': caseless = 1; break; case 'e': env_name = optarg; break; case 't': type_list = optarg; break; case 'v': v_opt++; break; case 'p': p_opt = TRUE; break; case 'W': value = (int) strtol(optarg, &t, 0); if (*t != EOS || value < 0) usage(); value = (int) strlen(w_opt_text) - value; if (value < 0) value = 0; w_opt = w_opt_text + value; break; case 'r': acc_mask |= R_OK; break; case 'w': acc_mask |= W_OK; break; case 'x': acc_mask |= X_OK; break; /* * The 'U' and 'D' options are parsed to simplify * using C-preprocessor options to scan for include- * files. */ case 'U': /* ignored */ break; case 'D': /* ignored */ break; case 'I': AddToPath(optarg); break; case 'L': AddToPath(optarg); break; default: usage(); /*NOTREACHED */ } } /* The "-v" and "-p" options aren't meaningful in combination */ if (v_opt && p_opt) usage(); /* The remaining arguments are the programs/symbols that we're looking * for. Reduce the argument-list to the leaf-names (stripping paths). */ if (argc > optind) { for (j = optind; j < argc; j++) { argv[j] = MakeString(DOS_upper(fleaf(argv[j]))); } } do_blips = ((v_opt > 1) && isatty(fileno(stderr))); if (acc_mask == 0) acc_mask = X_OK; /* * Get the current working-directory, so we have a reference point to * go back after scanning directories. */ if (getwd(bfr) == 0) failed("getcwd"); dot = MakeString(bfr); if (!p_opt) (void) printf("Current working directory is \"%s\"\n", dot); /* * Obtain the list of directories that we'll scan. */ if (pathlist == 0) { if (env_name == 0) env_name = "PATH"; if ((s = getenv(env_name)) != 0) pathlist = strdup(s); else failed(env_name); #if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX if (!strcmp(env_name, "PATH")) { /* look in current directory before looking in $PATH */ s = malloc(strlen(pathlist) + 3); (void) sprintf(s, ".%c%s", PATHLIST_SEP, pathlist); free(pathlist); pathlist = s; } #endif } for (s = DOS_upper(pathlist), path_len = 1; *s != EOS; s++) if (*s == PATHLIST_SEP) path_len++; dirs = TypeAlloc(DIRS, path_len); /* * Reconstruct the type-list (if any) as an array to simplify scanning. */ #ifdef TYPES_PATH if (type_list == 0) { if (!strcmp(env_name, "PATH")) type_list = TYPES_PATH; } #endif if (type_list != 0) { type_list = DOS_upper(strdup(type_list)); for (s = type_list, num_types = 0; *s != EOS; s++) { if (*s == '.') { num_types++; #if NULL_FTYPE /* "." and "" are different types */ if ((s[1] == '.') || (s[1] == EOS)) num_types++; #endif } } if (num_types == 0 || *type_list != '.') { (void) fprintf(stderr, "Type-list must be .-separated\n"); exit(EXIT_FAILURE); } FileTypes = TypeAlloc(char *, num_types); j = (int) num_types; do { if (*--s == '.') { FileTypes[--j] = strdup(s); #if NULL_FTYPE /* "." and "" are different types */ if (s[1] == EOS) FileTypes[--j] = strdup(""); #endif *s = EOS; } } while (j != 0); free(type_list); }
static void ScanConflicts(char *path, unsigned inx, int argc, char **argv) { DIR *dp; struct dirent *de; struct stat sb; int j; unsigned k; #if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX char save_wd[MAXPATHLEN]; #endif /* * When scanning a directory, we first chdir to it, mostly to make * the scan+stat work faster, but also because some systems don't * scan properly otherwise. * * MSDOS and OS/2 are a little more complicated, because each drive * has its own current directory. */ #if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX (void) strcpy(save_wd, dot); if (!strcmp(".", path)) { path = dot; } else if (!same_drive(dot, path)) { if (!set_drive(path)) return; getwd(save_wd); } #endif if (v_opt > 2) printf("ScanConflicts \"%s\"\n", path); if (set_directory(path) && (dp = opendir(path)) != NULL) { while ((de = readdir(dp)) != NULL) { register type_t ok = 0; int found = FALSE; char buffer[MAXPATHLEN]; char *the_name; char *the_NAME; if (do_blips) blip('.'); (void) sprintf(buffer, "%.*s", (int) NAMLEN(de), de->d_name); the_name = MakeString(DOS_upper(buffer)); the_NAME = ToCompare(the_name); /* If arguments are given, restrict search to them */ if (argc > optind) { for (j = optind; j < argc; j++) { if (SameName(argv[j], the_name)) { found = TRUE; break; } } if (!found) continue; } /* Verify that the name is a file, and executable */ if (stat(the_name, &sb) < 0) continue; if ((sb.st_mode & S_IFMT) != S_IFREG) continue; #if SYS_UNIX || SYS_OS2 || SYS_OS2_EMX if (access(the_name, acc_mask) < 0) continue; ok = 1; #endif if (FileTypes != 0) { if ((ok = LookupType(the_name)) == 0) continue; } /* Find the name in our array of all names */ found = FALSE; for (k = 0; k < total; k++) { if (SameName(inpath[k].ip_NAME, the_NAME)) { FoundNode(&inpath[k], inx); found = TRUE; break; } } /* If not there, add it */ if (found) { if (the_NAME != the_name) { FreeString(the_NAME); } } else { if (!(total & CHUNK)) { size_t need = (((total * 3) / 2) | CHUNK) + 1; if (inpath != 0) inpath = TypeRealloc(INPATH, inpath, need); else inpath = TypeAlloc(INPATH, need); } j = (int) total++; inpath[j].ip_name = the_name; inpath[j].ip_NAME = the_NAME; inpath[j].node = TypeAlloc(NODE, path_len); FoundNode(&inpath[j], inx); } if (v_opt > 2) { (void) printf("%c %s%c%s\n", found ? '+' : '*', path, PATHNAME_SEP, buffer); } } (void) closedir(dp); } #if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX if (strcmp(dot, save_wd)) { chdir(save_wd); } #endif (void) set_directory(dot); }
/* Type * ParseIntRange(Type * type) { Var * min, * max; Bookmark bookmark; bookmark = SetBookmark(); ParseExpressionType(TypeType(NULL)); if (TOK && TOP != 0) { min = BufPop(); max = NULL; if (NextIs(TOKEN_DOTDOT)) { ExpectExpression(NULL); if (TOK) { max = BufPop(); type = TypeDerive(type); } } if (VarIsIntConst(min) && VarIsIntConst(max)) { type = TypeAllocRange(min, max); if (type->range.min > type->range.max) { SyntaxErrorBmk("range minimum bigger than maximum", bookmark); } } else { SyntaxErrorBmk("expected type constant expression", bookmark); } } return type; } */ Type * ParseType2(InstrOp mode) /* Purpose: Parse: <int> [".." <int>] | <var> | proc <VarList> Input: mode Type of variable for which we parse. */ { Var * var; Type * type = NULL, * variant_type = NULL; Var * min, * max; Bookmark bookmark; next: type = ParseType3(); if (!TOK) return NULL; if (type == NULL) { bookmark = SetBookmark(); ParseExpressionType(TypeType(NULL)); if (TOK && TOP != 0) { min = BufPop(); max = NULL; if (NextIs(TOKEN_DOTDOT)) { ExpectExpression(NULL); if (TOK) { max = BufPop(); } } type = NULL; if (max == NULL) { var = min; if (var->mode == INSTR_TYPE) { type = var->type; } else if (var->mode == INSTR_VAR && var->type->variant == TYPE_TYPE) { type = var->type_value; SetFlagOn(var->submode, SUBMODE_USED_AS_TYPE); } // This is directly type if (type != NULL) { // For integer type, constants may be defined if (type->variant == TYPE_INT) { // type = ParseIntRange(type); goto const_list; } goto done; } max = var; } if (VarIsIntConst(min) && VarIsIntConst(max)) { type = TypeAllocRange(min, max); if (type->range.min > type->range.max) { SyntaxErrorBmk("range minimum bigger than maximum", bookmark); } } else { SyntaxErrorBmk("expected type constant expression", bookmark); } } else if (TOK == TOKEN_STRING) { type = TypeAlloc(TYPE_VAR); type->typevar = VarNewStr(NAME); NextToken(); } } const_list: // Parse type specific constants // There can be list of constants specified in block. // First thing in the block must be an identifier, so we try to open the block with this in mind. // We try to parse constants only for integer types (in future, we may try other numberic or string types) if (type != NULL && type->variant == TYPE_INT && !type->is_enum) { if (TOK != TOKEN_OR) { type = ParseConstList(type); } } done: if (TOK) { if (variant_type != NULL) { variant_type->right = type; type = variant_type; } if (NextIs(TOKEN_OR)) { variant_type = TypeAlloc(TYPE_VARIANT); variant_type->left = type; goto next; } } return type; }
Type * ParseType3() { Type * type = NULL, * variant_type = NULL; Type * elmt, * t; Var * var; BigInt * st; //# "type" restrict_type if (NextIs(TOKEN_TYPE2)) { variant_type = ParseType2(INSTR_VAR); type = TypeType(variant_type); //# "enum" ["struct"] } else if (NextIs(TOKEN_ENUM)) { type = TypeAlloc(TYPE_INT); type->range.flexible = true; type->is_enum = true; if (NextIs(TOKEN_STRUCT)) { ParseEnumStruct(type); } else { type = ParseConstList(type); } //# "proc" args } else if (NextIs(TOKEN_PROC)) { type = TypeAlloc(TYPE_PROC); ParseArgList(SUBMODE_ARG_IN, type); if (TOK) { ProcTypeFinalize(type); } //# "macro" args } else if (NextIs(TOKEN_MACRO)) { type = TypeAlloc(TYPE_MACRO); ParseArgList(SUBMODE_ARG_IN, type); // Struct } else if (NextIs(TOKEN_STRUCT)) { type = TypeAlloc(TYPE_STRUCT); ParseArgList(SUBMODE_EMPTY, type); // String } else if (NextIs(TOKEN_STRING_TYPE)) { type = TypeAlloc(TYPE_STRING); // Array } else if (NextIs(TOKEN_ARRAY)) { type = TypeAlloc(TYPE_ARRAY); t = NULL; if (TOK == TOKEN_OPEN_P) { EnterBlockWithStop(TOKEN_EQUAL); while (TOK != TOKEN_ERROR && !NextIs(TOKEN_BLOCK_END)) { elmt = ParseIntType(); if (type->index == NULL) { type->index = elmt; } else if (t != NULL) { t->right = TypeTuple(t->right, elmt); t = t->right; } else { t = TypeTuple(type->index, elmt); type->index = t; } NextIs(TOKEN_COMMA); }; } // If no dimension has been defined, use flexible array. // This is possible only for constants now. if (TOK) { if (type->index == NULL) { elmt = TypeAlloc(TYPE_INT); elmt->range.flexible = true; elmt->range.min = 0; type->index = elmt; } } // Element STEP may be defined if (TOK) { if (NextIs(TOKEN_STEP)) { ExpectExpression(NULL); if (TOK) { var = STACK[0]; st = VarIntConst(var); if (st != NULL) { type->step = IntN(st); } else { SyntaxError("Expected integer constant"); } } } } if (TOK) { if (NextIs(TOKEN_OF)) { type->element = ParseSubtype(); } else { type->element = TypeByte(); } } if (TOK) { if (type->step == 0) { type->step = TypeSize(type->element); } } } else if (NextIs(TOKEN_ADR2)) { elmt = NULL; if (NextIs(TOKEN_OF)) { elmt = ParseSubtype(); } type = TypeAdrOf(elmt); } return type; }