static unsigned8 read_icr (struct hw *me, struct mn103int *controller, unsigned_word base) { unsigned_word offset; struct mn103int_group *group = decode_group (me, controller, base, &offset); unsigned8 val = 0; switch (group->type) { case NMI_GROUP: switch (offset) { case 0: val = INSERT_ID (group->request); HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x", group->gid, val)); break; default: break; } break; case LEVEL_GROUP: switch (offset) { case 0: val = (INSERT_IR (group->request) | INSERT_ID (group->request & group->enable)); HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x", group->gid, val)); break; case 1: val = (INSERT_LV (group->level) | INSERT_IE (group->enable)); HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x", group->gid, val)); break; } break; default: break; } return val; }
//------------------------------------------------------------------------------------------------- unsigned MessageBase::decode(const f8String& from, const unsigned offset) { unsigned s_offset(offset), result; const unsigned fsize(from.size()); const char *dptr(from.data()); char tag[MAX_FLD_LENGTH], val[MAX_FLD_LENGTH]; for (unsigned pos(_pos.size()); s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));) { const unsigned tv(fast_atoi<unsigned>(tag)); const BaseEntry *be(_ctx._be.find_ptr(tv)); #if defined PERMIT_CUSTOM_FIELDS if (!be && (!_ctx._ube || (be = _ctx._ube->find_ptr(tv)) == 0)) #else if (!be) #endif throw InvalidField(tv); Presence::const_iterator itr(_fp.get_presence().end()); if (!_fp.has(tv, itr)) break; s_offset += result; if (_fp.get(tv, itr, FieldTrait::present)) { if (!_fp.get(tv, itr, FieldTrait::automatic)) throw DuplicateField(tv); } else { add_field(tv, itr, ++pos, be->_create(val, be->_rlm, -1), false); if (_fp.is_group(tv, itr)) s_offset = decode_group(tv, from, s_offset); } } const unsigned short missing(_fp.find_missing()); if (missing) { const BaseEntry& tbe(_ctx._be.find_ref(missing)); ostringstream ostr; ostr << tbe._name << " (" << missing << ')'; throw MissingMandatoryField(ostr.str()); } return s_offset; }
static InternetAddress * decode_address (const char **in) { const char *inptr, *start, *word, *comment = NULL; InternetAddress *addr = NULL; gboolean has_lwsp = FALSE; gboolean is_word; GString *name; decode_lwsp (in); start = inptr = *in; name = g_string_new (""); /* Both groups and mailboxes can begin with a phrase (denoting * the display name for the address). Collect all of the * tokens that make up this name phrase. */ while (*inptr) { if ((word = decode_word (&inptr))) { g_string_append_len (name, word, (size_t) (inptr - word)); check_lwsp: word = inptr; skip_lwsp (&inptr); /* is the next token a word token? */ is_word = *inptr == '"' || is_atom (*inptr); if (inptr > word && is_word) { g_string_append_c (name, ' '); has_lwsp = TRUE; } if (is_word) continue; } /* specials = "(" / ")" / "<" / ">" / "@" ; Must be in quoted- * / "," / ";" / ":" / "\" / <"> ; string, to use * / "." / "[" / "]" ; within a word. */ if (*inptr == ':') { /* rfc2822 group */ inptr++; addr = decode_group (&inptr); decode_lwsp (&inptr); if (*inptr != ';') w(g_warning ("Invalid group spec, missing closing ';': %.*s", inptr - start, start)); else inptr++; break; } else if (*inptr == '<') { /* rfc2822 angle-addr */ inptr++; /* check for obsolete routing... */ if (*inptr != '@' || decode_route (&inptr)) { /* rfc2822 addr-spec */ addr = decode_addrspec (&inptr); } decode_lwsp (&inptr); if (*inptr != '>') { w(g_warning ("Invalid rfc2822 angle-addr, missing closing '>': %.*s", inptr - start, start)); while (*inptr && *inptr != '>' && *inptr != ',') inptr++; if (*inptr == '>') inptr++; } else { inptr++; } /* if comment is non-NULL, we can check for a comment containing a name */ comment = inptr; break; } else if (*inptr == '(') { /* beginning of a comment, use decode_lwsp() to skip past it */ decode_lwsp (&inptr); } else if (*inptr && strchr ("@,;", *inptr)) { if (name->len == 0) { if (*inptr == '@') { GString *domain; w(g_warning ("Unexpected address: %s: skipping.", start)); /* skip over @domain? */ inptr++; domain = g_string_new (""); decode_domain (&inptr, domain); g_string_free (domain, TRUE); } else { /* empty address */ } break; } else if (has_lwsp) { /* assume this is just an unquoted special that we should treat as part of the name */ w(g_warning ("Unquoted '%c' in address name: %s: ignoring.", *inptr, start)); g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } addrspec: /* what we thought was a name was actually an addrspec? */ g_string_truncate (name, 0); inptr = start; addr = decode_addrspec (&inptr); /* if comment is non-NULL, we can check for a comment containing a name */ comment = inptr; break; } else if (*inptr == '.') { /* This would normally signify that we are * decoding the local-part of an addr-spec, * but sadly, it is common for broken mailers * to forget to quote/encode .'s in the name * phrase. */ g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } else if (*inptr) { /* Technically, these are all invalid tokens * but in the interest of being liberal in * what we accept, we'll ignore them. */ w(g_warning ("Unexpected char '%c' in address: %s: ignoring.", *inptr, start)); g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } else { goto addrspec; } } /* Note: will also skip over any comments */ decode_lwsp (&inptr); if (name->len == 0 && comment && inptr > comment) { /* missing a name, look for a trailing comment */ if ((comment = memchr (comment, '(', inptr - comment))) { const char *cend; /* find the end of the comment */ cend = inptr - 1; while (cend > comment && is_lwsp (*cend)) cend--; if (*cend == ')') cend--; g_string_append_len (name, comment + 1, (size_t) (cend - comment)); } } if (addr && name->len > 0) _internet_address_decode_name (addr, name); g_string_free (name, TRUE); *in = inptr; return addr; }
static void write_icr (struct hw *me, struct mn103int *controller, unsigned_word base, unsigned8 val) { unsigned_word offset; struct mn103int_group *group = decode_group (me, controller, base, &offset); switch (group->type) { case NMI_GROUP: switch (offset) { case 0: HW_TRACE ((me, "write-icr group=%d:0 nmi 0x%02x", group->gid, val)); group->request &= ~EXTRACT_ID (val); break; /* Special backdoor access to SYSEF flag from CPU. See interp.c:program_interrupt(). */ case 3: HW_TRACE ((me, "write-icr-special group=%d:0 nmi 0x%02x", group->gid, val)); group->request |= EXTRACT_ID (val); default: break; } break; case LEVEL_GROUP: switch (offset) { case 0: /* request/detect */ /* Clear any ID bits and then set them according to IR */ HW_TRACE ((me, "write-icr group=%d:0 level 0x%02x %x:%x:%x", group->gid, val, group->request, EXTRACT_IR (val), EXTRACT_ID (val))); group->request = ((EXTRACT_IR (val) & EXTRACT_ID (val)) | (EXTRACT_IR (val) & group->request) | (~EXTRACT_IR (val) & ~EXTRACT_ID (val) & group->request)); break; case 1: /* level/enable */ HW_TRACE ((me, "write-icr group=%d:1 level 0x%02x", group->gid, val)); group->level = EXTRACT_LV (val); group->enable = EXTRACT_IE (val); break; default: /* ignore */ break; } push_interrupt_level (me, controller); break; default: break; } }