bool_t sd_lld_interrupt_pending(void) { bool_t b; CH_IRQ_PROLOGUE(); b = connint(&SD1) || connint(&SD2) || inint(&SD1) || inint(&SD2) || outint(&SD1) || outint(&SD2); CH_IRQ_EPILOGUE(); return b; }
/* * write the name of a tag or typename * * if the tag is named, the name of the * tag is written, otherwise, if a typename exists which * refers to this tag, this typename is written */ static void outtt(sym_t *tag, sym_t *tdef) { if (tag->s_name != unnamed) { outint(1); outname(tag->s_name); } else if (tdef != NULL) { outint(2); outname(tdef->s_name); } else { outint(0); } }
const char * fnnalloc(const char *s, size_t len) { fn_t *fn; static int nxt_id = 0; if (s == NULL) return (NULL); if ((fn = srchfn(s, len)) == NULL) { if ((fn = malloc(sizeof (fn_t))) == NULL) nomem(); /* Do not used strdup() because string is not NUL-terminated.*/ if ((fn->fn_name = malloc(len + 1)) == NULL) nomem(); (void)memcpy(fn->fn_name, s, len); fn->fn_name[len] = '\0'; fn->fn_len = len; fn->fn_id = nxt_id++; fn->fn_nxt = fnames; fnames = fn; /* Write id of this filename to the output file. */ outclr(); outint(fn->fn_id); outchar('s'); outstrg(fn->fn_name); } return (fn->fn_name); }
/* * Write a new lint library. */ void outlib(const char *name) { /* Open of output file and initialisation of the output buffer */ outopen(name); /* write name of lint library */ outsrc(name); /* name of lint lib has index 0 */ outclr(); outint(0); outchar('s'); outstrg(name); /* * print the names of all files references by unnamed * struct/union/enum declarations. */ outfiles(); /* write all definitions with external linkage */ forall(dumpname); /* close the output */ outclose(); }
bool sd_lld_interrupt_pending(void) { bool b = false; CH_IRQ_PROLOGUE(); #if USE_WIN32_SERIAL1 b |= connint(&SD1) || inint(&SD1) || outint(&SD1); #endif #if USE_WIN32_SERIAL2 b |= connint(&SD2) || inint(&SD2) || outint(&SD2); #endif CH_IRQ_EPILOGUE(); return b; }
/* * writes a record if sym was used */ void outusg(sym_t *sym) { /* reset buffer */ outclr(); /* * line number of .c source, 'u' for used, Id of current * source (.c or .h), and line in current source */ outint(csrc_pos.p_line); outchar('u'); outint(getfnid(curr_pos.p_file)); outchar('.'); outint(curr_pos.p_line); /* necessary to delimit both numbers */ outchar('x'); /* Den Namen des Symbols ausgeben */ outname(sym->s_name); }
static void outfiles(void) { struct outflist *ofl; int i; for (ofl = outflist, i = 1; ofl != NULL; ofl = ofl->ofl_next, i++) { /* reset output buffer */ outclr(); outint(i); outchar('s'); outstrg(fnames[ofl->ofl_num]); } }
/* * Write a new lint library. */ void outlib(const char *name) { /* Open of output file and initialisation of the output buffer */ outopen(name); /* write name of lint library */ outsrc(name); /* name of lint lib has index 0 */ outclr(); outint(0); outchar('s'); outstrg(name); /* write all definitions with external linkage */ forall(dumpname); /* close the output */ outclose(); }
/* * Write a definition. */ static void outdef(hte_t *hte, sym_t *sym) { /* reset output buffer */ outclr(); /* line number in C source file */ outint(0); /* this is a definition */ outchar('d'); /* index of file where symbol was defined and line number of def. */ outint(0); outchar('.'); outint(0); /* flags */ if (sym->s_va) { outchar('v'); /* varargs */ outint(sym->s_nva); } if (sym->s_scfl) { outchar('S'); /* scanflike */ outint(sym->s_nscfl); } if (sym->s_prfl) { outchar('P'); /* printflike */ outint(sym->s_nprfl); } /* definition or tentative definition */ outchar(sym->s_def == DEF ? 'd' : 't'); if (TP(sym->s_type)->t_tspec == FUNC) { if (sym->s_rval) outchar('r'); /* fkt. has return value */ if (sym->s_osdef) outchar('o'); /* old style definition */ } outchar('u'); /* used (no warning if not used) */ /* name */ outname(hte->h_name); /* type */ outtype(TP(sym->s_type)); }
/* * write the name of a tag or typename * * if the tag is named, the name of the * tag is written, otherwise, if a typename exists which * refers to this tag, this typename is written */ static void outtt(sym_t *tag, sym_t *tdef) { /* * 0 is no longer used. */ if (tag->s_name != unnamed) { outint(1); outname(tag->s_name); } else if (tdef != NULL) { outint(2); outname(tdef->s_name); } else { outint(3); outint(tag->s_dpos.p_line); outchar('.'); outint(getfnid(tag->s_dpos.p_file)); outchar('.'); outint(tag->s_dpos.p_uniq); } }
/* * Write type into the output buffer. * The type is written as a sequence of substrings, each of which describes a * node of type type_t * a node is coded as follows: * _Bool B * _Complex float s X * _Complex double X * _Complex long double l X * char C * signed char s C * unsigned char u C * short S * unsigned short u S * int I * unsigned int u I * long L * unsigned long u L * long long Q * unsigned long long u Q * float s D * double D * long double l D * void V * * P * [n] A n * () F * (void) F 0 * (n arguments) F n arg1 arg2 ... argn * (n arguments, ...) F n arg1 arg2 ... argn-1 E * (a, b, c, ...) f n arg1 arg2 ... * enum tag e T tag_or_typename * struct tag s T tag_or_typename * union tag u T tag_or_typename * * tag_or_typename 0 no tag or type name * 1 n tag Tag * 2 n typename only type name * * spaces are only for better readability * additionaly it is possible to prepend the characters 'c' (for const) * and 'v' (for volatile) */ void outtype(type_t *tp) { int t, s, na; sym_t *arg; tspec_t ts; while (tp != NULL) { if ((ts = tp->t_tspec) == INT && tp->t_isenum) ts = ENUM; switch (ts) { case BOOL: t = 'B'; s = '\0'; break; case CHAR: t = 'C'; s = '\0'; break; case SCHAR: t = 'C'; s = 's'; break; case UCHAR: t = 'C'; s = 'u'; break; case SHORT: t = 'S'; s = '\0'; break; case USHORT: t = 'S'; s = 'u'; break; case INT: t = 'I'; s = '\0'; break; case UINT: t = 'I'; s = 'u'; break; case LONG: t = 'L'; s = '\0'; break; case ULONG: t = 'L'; s = 'u'; break; case QUAD: t = 'Q'; s = '\0'; break; case UQUAD: t = 'Q'; s = 'u'; break; case FLOAT: t = 'D'; s = 's'; break; case DOUBLE: t = 'D'; s = '\0'; break; case LDOUBLE: t = 'D'; s = 'l'; break; case VOID: t = 'V'; s = '\0'; break; case PTR: t = 'P'; s = '\0'; break; case ARRAY: t = 'A'; s = '\0'; break; case FUNC: t = 'F'; s = '\0'; break; case ENUM: t = 'T'; s = 'e'; break; case STRUCT: t = 'T'; s = 's'; break; case UNION: t = 'T'; s = 'u'; break; case FCOMPLEX: t = 'X'; s = 's'; break; case DCOMPLEX: t = 'X'; s = '\0'; break; case LCOMPLEX: t = 'X'; s = 'l'; break; default: LERROR("outtyp()"); } if (tp->t_const) outchar('c'); if (tp->t_volatile) outchar('v'); if (s != '\0') outchar(s); outchar(t); if (ts == ARRAY) { outint(tp->t_dim); } else if (ts == ENUM) { outtt(tp->t_enum->etag, tp->t_enum->etdef); } else if (ts == STRUCT || ts == UNION) { outtt(tp->t_str->stag, tp->t_str->stdef); } else if (ts == FUNC && tp->t_proto) { na = 0; for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) na++; if (tp->t_vararg) na++; outint(na); for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) outtype(arg->s_type); if (tp->t_vararg) outchar('E'); } tp = tp->t_subt; } }
/* * write out all information necessary for lint2 to check function * calls * * rvused is set if the return value is used (asigned to a variable) * rvdisc is set if the return value is not used and not ignored * (casted to void) */ void outcall(tnode_t *tn, int rvused, int rvdisc) { tnode_t *args, *arg; int narg, n, i; int64_t q; tspec_t t; /* reset buffer */ outclr(); /* * line number of .c source, 'c' for function call, Id of current * source (.c or .h), and line in current source */ outint(csrc_pos.p_line); outchar('c'); outint(getfnid(curr_pos.p_file)); outchar('.'); outint(curr_pos.p_line); /* * flags; 'u' and 'i' must be last to make sure a letter * is between the numeric argument of a flag and the name of * the function */ narg = 0; args = tn->tn_right; for (arg = args; arg != NULL; arg = arg->tn_right) narg++; /* informations about arguments */ for (n = 1; n <= narg; n++) { /* the last argument is the top one in the tree */ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) continue; arg = arg->tn_left; if (arg->tn_op == CON) { if (isityp(t = arg->tn_type->t_tspec)) { /* * XXX it would probably be better to * explicitly test the sign */ if ((q = arg->tn_val->v_quad) == 0) { /* zero constant */ outchar('z'); } else if (msb(q, t, 0) == 0) { /* positive if casted to signed */ outchar('p'); } else { /* negative if casted to signed */ outchar('n'); } outint(n); } } else if (arg->tn_op == AMPER && arg->tn_left->tn_op == STRING && arg->tn_left->tn_strg->st_tspec == CHAR) { /* constant string, write all format specifiers */ outchar('s'); outint(n); outfstrg(arg->tn_left->tn_strg); } } /* return value discarded/used/ignored */ outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i')); /* name of the called function */ outname(tn->tn_left->tn_left->tn_sym->s_name); /* types of arguments */ outchar('f'); outint(narg); for (n = 1; n <= narg; n++) { /* the last argument is the top one in the tree */ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) continue; outtype(arg->tn_left->tn_type); } /* expected type of return value */ outtype(tn->tn_type); }
/* * write information about function definition * * this is also done for static functions so we are able to check if * they are called with proper argument types */ void outfdef(sym_t *fsym, pos_t *posp, int rval, int osdef, sym_t *args) { int narg; sym_t *arg; /* reset the buffer */ outclr(); /* * line number of .c source, 'd' for declaration, Id of current * source (.c or .h), and line in current source * * we are already at the end of the function. If we are in the * .c source, posp->p_line is correct, otherwise csrc_pos.p_line * (for functions defined in header files). */ if (posp->p_file == csrc_pos.p_file) { outint(posp->p_line); } else { outint(csrc_pos.p_line); } outchar('d'); outint(getfnid(posp->p_file)); outchar('.'); outint(posp->p_line); /* flags */ /* both SCANFLIKE and PRINTFLIKE imply VARARGS */ if (prflstrg != -1) { nvararg = prflstrg; } else if (scflstrg != -1) { nvararg = scflstrg; } if (nvararg != -1) { outchar('v'); outint(nvararg); } if (scflstrg != -1) { outchar('S'); outint(scflstrg); } if (prflstrg != -1) { outchar('P'); outint(prflstrg); } nvararg = prflstrg = scflstrg = -1; outchar('d'); if (rval) /* has return value */ outchar('r'); if (llibflg) /* * mark it as used so lint2 does not complain about * unused symbols in libraries */ outchar('u'); if (osdef) /* old style function definition */ outchar('o'); if (fsym->s_scl == STATIC) outchar('s'); /* name of function */ outname(fsym->s_name); /* renamed name of function, if necessary */ if (fsym->s_rename) { outchar('r'); outname(fsym->s_rename); } /* argument types and return value */ if (osdef) { narg = 0; for (arg = args; arg != NULL; arg = arg->s_nxt) narg++; outchar('f'); outint(narg); for (arg = args; arg != NULL; arg = arg->s_nxt) outtype(arg->s_type); outtype(fsym->s_type->t_subt); } else { outtype(fsym->s_type); } }
/* * write information about an global declared/defined symbol * with storage class extern * * informations about function definitions are written in outfdef(), * not here */ void outsym(sym_t *sym, scl_t sc, def_t def) { /* * Static function declarations must also be written to the output * file. Compatibility of function declarations (for both static * and extern functions) must be checked in lint2. Lint1 can't do * this, especially not, if functions are declared at block level * before their first declaration at level 0. */ if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC)) return; /* reset buffer */ outclr(); /* * line number of .c source, 'd' for declaration, Id of current * source (.c or .h), and line in current source. */ outint(csrc_pos.p_line); outchar('d'); outint(getfnid(sym->s_dpos.p_file)); outchar('.'); outint(sym->s_dpos.p_line); /* flags */ switch (def) { case DEF: /* defined */ outchar('d'); break; case TDEF: /* tentative defined */ outchar('t'); break; case DECL: /* declared */ outchar('e'); break; default: LERROR("outsym()"); } if (llibflg && def != DECL) { /* * mark it as used so we get no warnings from lint2 about * unused symbols in libraries. */ outchar('u'); } if (sc == STATIC) outchar('s'); /* name of the symbol */ outname(sym->s_name); /* renamed name of symbol, if necessary */ if (sym->s_rename) { outchar('r'); outname(sym->s_rename); } /* type of the symbol */ outtype(sym->s_type); }
/* * Write type into the output buffer. */ static void outtype(type_t *tp) { int t, s, na; tspec_t ts; type_t **ap; while (tp != NULL) { if ((ts = tp->t_tspec) == INT && tp->t_isenum) ts = ENUM; switch (ts) { case BOOL: t = 'B'; s = '\0'; break; case CHAR: t = 'C'; s = '\0'; break; case SCHAR: t = 'C'; s = 's'; break; case UCHAR: t = 'C'; s = 'u'; break; case SHORT: t = 'S'; s = '\0'; break; case USHORT: t = 'S'; s = 'u'; break; case INT: t = 'I'; s = '\0'; break; case UINT: t = 'I'; s = 'u'; break; case LONG: t = 'L'; s = '\0'; break; case ULONG: t = 'L'; s = 'u'; break; case QUAD: t = 'Q'; s = '\0'; break; case UQUAD: t = 'Q'; s = 'u'; break; case FLOAT: t = 'D'; s = 's'; break; case DOUBLE: t = 'D'; s = '\0'; break; case LDOUBLE: t = 'D'; s = 'l'; break; case COMPLEX: t = 'X'; s = 's'; break; case DCOMPLEX: t = 'X'; s = '\0'; break; case LDCOMPLEX: t = 'X'; s = 'l'; break; case IMAGINARY: t = 'J'; s = 's'; break; case DIMAGINARY: t = 'J'; s = '\0'; break; case LDIMAGINARY:t = 'J'; s = 'l'; break; case VOID: t = 'V'; s = '\0'; break; case PTR: t = 'P'; s = '\0'; break; case ARRAY: t = 'A'; s = '\0'; break; case ENUM: t = 'T'; s = 'e'; break; case STRUCT: t = 'T'; s = 's'; break; case UNION: t = 'T'; s = 'u'; break; case FUNC: if (tp->t_args != NULL && !tp->t_proto) { t = 'f'; } else { t = 'F'; } s = '\0'; break; default: errx(1, "internal error: outtype() 1"); } if (tp->t_const) outchar('c'); if (tp->t_volatile) outchar('v'); if (s != '\0') outchar(s); outchar(t); if (ts == ARRAY) { outint(tp->t_dim); } else if (ts == ENUM || ts == STRUCT || ts == UNION) { if (tp->t_istag) { outint(1); outname(tp->t_tag->h_name); } else if (tp->t_istynam) { outint(2); outname(tp->t_tynam->h_name); } else { outint(0); } } else if (ts == FUNC && tp->t_args != NULL) { na = 0; for (ap = tp->t_args; *ap != NULL; ap++) na++; if (tp->t_vararg) na++; outint(na); for (ap = tp->t_args; *ap != NULL; ap++) outtype(*ap); if (tp->t_vararg) outchar('E'); } tp = tp->t_subt; } }