void identifyDriver ( const char *type, const DriverDefinition *definition, int full ) { { char buffer[0X100]; STR_BEGIN(buffer, sizeof(buffer)); STR_PRINTF("%s %s Driver:", definition->name, type); if (definition->version && *definition->version) { STR_PRINTF(" version %s", definition->version); } if (full) { STR_PRINTF(" [compiled on %s at %s]", definition->date, definition->time); } STR_END; logMessage(LOG_NOTICE, "%s", buffer); } if (full) { if (definition->developers && *definition->developers) logMessage(LOG_INFO, " Developed by %s", definition->developers); } }
size_t formatKeyName (KeyTable *table, char *buffer, size_t size, const KeyValue *value) { const KeyNameEntry *kne = findKeyNameEntry(table, value); size_t length; STR_BEGIN(buffer, size); if (kne) { STR_PRINTF("%s", kne->name); } else if (value->number != KTB_KEY_ANY) { const KeyValue anyKey = { .group = value->group, .number = KTB_KEY_ANY }; if ((kne = findKeyNameEntry(table, &anyKey))) { STR_PRINTF("%s.%u", kne->name, value->number+1); } } if (STR_LENGTH == 0) STR_PRINTF("?"); length = STR_LENGTH; STR_END; return length; } static int putKeyName (ListGenerationData *lgd, const KeyValue *value) { char name[0X100]; formatKeyName(lgd->keyTable, name, sizeof(name), value); return putUtf8String(lgd, name); }
size_t formatCharacterDescription (char *buffer, size_t size, int column, int row) { static char *const colours[] = { strtext("black"), strtext("blue"), strtext("green"), strtext("cyan"), strtext("red"), strtext("magenta"), strtext("brown"), strtext("light grey"), strtext("dark grey"), strtext("light blue"), strtext("light green"), strtext("light cyan"), strtext("light red"), strtext("light magenta"), strtext("yellow"), strtext("white") }; size_t length; ScreenCharacter character; readScreen(column, row, 1, 1, &character); STR_BEGIN(buffer, size); { uint32_t text = character.text; STR_PRINTF("char %" PRIu32 " (U+%04" PRIX32 "): %s on %s", text, text, gettext(colours[character.attributes & 0X0F]), gettext(colours[(character.attributes & 0X70) >> 4])); } if (character.attributes & SCR_ATTR_BLINK) { STR_PRINTF(" %s", gettext("blink")); } #ifdef HAVE_ICU { char name[0X40]; UErrorCode error = U_ZERO_ERROR; u_charName(character.text, U_EXTENDED_CHAR_NAME, name, sizeof(name), &error); if (U_SUCCESS(error)) { STR_PRINTF(" [%s]", name); } } #endif /* HAVE_ICU */ length = STR_LENGTH; STR_END; return length; }
static size_t formatTitle_HelpScreen (char *buffer, size_t size) { size_t length; STR_BEGIN(buffer, size); STR_PRINTF("%s", gettext("Help Screen")); length = STR_LENGTH; STR_END return length; }
static void usbLogLineCoding_CDC_ACM (const USB_CDC_ACM_LineCoding *lineCoding) { char log[0X80]; STR_BEGIN(log, sizeof(log)); STR_PRINTF("CDC ACM line coding:"); { // baud (bits per second) uint32_t baud = getLittleEndian32(lineCoding->dwDTERate); STR_PRINTF(" Baud:%" PRIu32, baud); } { // number of data bits STR_PRINTF(" Data:%u", lineCoding->bDataBits); } { // number of stop bits const char *bits; #define USB_CDC_ACM_STOP(value,name) \ case USB_CDC_ACM_STOP_##value: bits = #name; break; switch (lineCoding->bCharFormat) { USB_CDC_ACM_STOP(1 , 1 ) USB_CDC_ACM_STOP(1_5, 1.5) USB_CDC_ACM_STOP(2 , 2 ) default: bits = "?"; break; } #undef USB_CDC_ACM_STOP STR_PRINTF(" Stop:%s", bits); } { // type of parity const char *parity; #define USB_CDC_ACM_PARITY(value,name) \ case USB_CDC_ACM_PARITY_##value: parity = #name; break; switch (lineCoding->bParityType) { USB_CDC_ACM_PARITY(NONE , none ) USB_CDC_ACM_PARITY(ODD , odd ) USB_CDC_ACM_PARITY(EVEN , even ) USB_CDC_ACM_PARITY(MARK , mark ) USB_CDC_ACM_PARITY(SPACE, space) default: parity = "?"; break; } #undef USB_CDC_ACM_PARITY STR_PRINTF(" Parity:%s", parity); } STR_END; logMessage(LOG_CATEGORY(USB_IO), "%s", log); }
size_t formatInputError (char *buffer, size_t size, const char *file, const int *line, const char *format, va_list argp) { size_t length; STR_BEGIN(buffer, size); if (file) STR_PRINTF("%s", file); if (line) STR_PRINTF("[%d]", *line); if (STR_LENGTH) STR_PRINTF(": "); STR_VPRINTF(format, argp); length = STR_LENGTH; STR_END return length; }
static int monitorKeyboard (KeyboardInstanceObject *kio) { const char *deviceName = locatePathName(kio->kix->device.path); if ((kio->kix->file.descriptor = open(kio->kix->device.path, O_RDONLY)) != -1) { struct stat status; if (fstat(kio->kix->file.descriptor, &status) != -1) { if (S_ISCHR(status.st_mode)) { { char description[0X100]; STR_BEGIN(description, sizeof(description)); STR_PRINTF("%s:", deviceName); { struct input_id identity; if (ioctl(kio->kix->file.descriptor, EVIOCGID, &identity) != -1) { STR_PRINTF(" bus=%04X vnd=%04X prd=%04X ver=%04X", identity.bustype, identity.vendor, identity.product, identity.version); { static const KeyboardType typeTable[] = { #ifdef BUS_I8042 [BUS_I8042] = KBD_TYPE_PS2, #endif /* BUS_I8042 */ #ifdef BUS_USB [BUS_USB] = KBD_TYPE_USB, #endif /* BUS_USB */ #ifdef BUS_BLUETOOTH [BUS_BLUETOOTH] = KBD_TYPE_Bluetooth, #endif /* BUS_BLUETOOTH */ }; if (identity.bustype < ARRAY_COUNT(typeTable)) { kio->actualProperties.type = typeTable[identity.bustype]; } } kio->actualProperties.vendor = identity.vendor; kio->actualProperties.product = identity.product; } else if (errno != ENOTTY) { logMessage(LOG_WARNING, "cannot get input device identity: %s: %s", deviceName, strerror(errno)); } }
static size_t usbFormatURB (char *buffer, size_t size, const void *data) { const UsbFormatUrbData *fud = data; const struct usbdevfs_urb *urb = fud->urb; size_t length; STR_BEGIN(buffer, size); STR_PRINTF("%s URB:", fud->action); STR_PRINTF(" Adr:%p", urb); STR_PRINTF(" Ept:%02X", urb->endpoint); STR_PRINTF(" Typ:%u", urb->type); { static const char *const types[] = { [USBDEVFS_URB_TYPE_CONTROL] = "ctl", [USBDEVFS_URB_TYPE_BULK] = "blk", [USBDEVFS_URB_TYPE_INTERRUPT] = "int", [USBDEVFS_URB_TYPE_ISO] = "iso" }; if (urb->type < ARRAY_COUNT(types)) { const char *type = types[urb->type]; if (type) STR_PRINTF("(%s)", type); } } STR_PRINTF(" Flg:%02X", urb->flags); { typedef struct { unsigned char bit; const char *name; } UrbFlagEntry; static const UrbFlagEntry urbFlagTable[] = { #ifdef USBDEVFS_URB_SHORT_NOT_OK { .bit = USBDEVFS_URB_SHORT_NOT_OK, .name = "spd" }, #endif /* USBDEVFS_URB_SHORT_NOT_OK */ #ifdef USBDEVFS_URB_ISO_ASAP { .bit = USBDEVFS_URB_ISO_ASAP, .name = "isa" }, #endif /* USBDEVFS_URB_ISO_ASAP */ #ifdef USBDEVFS_URB_BULK_CONTINUATION { .bit = USBDEVFS_URB_BULK_CONTINUATION,
static size_t usbFormatLogSetupPacket (char *buffer, size_t size, const void *data) { const UsbSetupPacket *setup = data; size_t length; STR_BEGIN(buffer, size); STR_PRINTF("setup packet: Typ:%02X Req:%02X Val:%04X Idx:%04X Len:%04X", setup->bRequestType, setup->bRequest, getLittleEndian16(setup->wValue), getLittleEndian16(setup->wIndex), getLittleEndian16(setup->wLength)); length = STR_LENGTH; STR_END; return length; }
static size_t formatLogCommandData (char *buffer, size_t size, const void *data) { const LogCommandData *cmd = data; size_t length; STR_BEGIN(buffer, size); STR_PRINTF("command: "); { size_t sublength = formatCommand(STR_NEXT, STR_LEFT, cmd->command); STR_ADJUST(sublength); } length = STR_LENGTH; STR_END return length; }
static size_t formatCommandModifiers (char *buffer, size_t size, int command, const CommandModifierEntry *modifiers) { const CommandModifierEntry *modifier = modifiers; size_t length; STR_BEGIN(buffer, size); while (modifier->name) { if (command & modifier->bit) { STR_PRINTF(" + %s", modifier->name); } modifier += 1; } length = STR_LENGTH; STR_END; return length; }
static size_t formatLogSpeechActionData (char *buffer, size_t size, const void *data) { const LogSpeechActionData *lsa = data; size_t length; STR_BEGIN(buffer, size); STR_PRINTF("%s speech %s: ", lsa->action, lsa->type); if (lsa->name) { STR_PRINTF("%s", lsa->name); } else { STR_PRINTF("%u", lsa->value); } length = STR_LENGTH; STR_END; return length; }
static size_t formatCommand (char *buffer, size_t size, int command) { size_t length; STR_BEGIN(buffer, size); STR_PRINTF("%06X (", command); { size_t length = describeCommand(command, STR_NEXT, STR_LEFT, CDO_IncludeName | CDO_IncludeOperand); STR_ADJUST(length); } STR_PRINTF(")"); length = STR_LENGTH; STR_END; return length; }
static int insertKey_ScreenScreen (ScreenKey key) { char *sequence; char buffer[0X10]; setScreenKeyModifiers(&key, 0); wchar_t character = key & SCR_KEY_CHAR_MASK; if (isSpecialKey(key)) { const unsigned char flags = getAuxiliaryData()[1]; #define KEY(key,string) case (key): sequence = (string); break #define CURSOR_KEY(key,string1,string2) KEY((key), ((flags & 0X01)? (string1): (string2))) switch (character) { KEY(SCR_KEY_ENTER, "\r"); KEY(SCR_KEY_TAB, "\t"); KEY(SCR_KEY_BACKSPACE, "\x7f"); KEY(SCR_KEY_ESCAPE, "\x1b"); CURSOR_KEY(SCR_KEY_CURSOR_LEFT , "\x1bOD", "\x1b[D"); CURSOR_KEY(SCR_KEY_CURSOR_RIGHT, "\x1bOC", "\x1b[C"); CURSOR_KEY(SCR_KEY_CURSOR_UP , "\x1bOA", "\x1b[A"); CURSOR_KEY(SCR_KEY_CURSOR_DOWN , "\x1bOB", "\x1b[B"); KEY(SCR_KEY_PAGE_UP, "\x1b[5~"); KEY(SCR_KEY_PAGE_DOWN, "\x1b[6~"); KEY(SCR_KEY_HOME, "\x1b[1~"); KEY(SCR_KEY_END, "\x1b[4~"); KEY(SCR_KEY_INSERT, "\x1b[2~"); KEY(SCR_KEY_DELETE, "\x1b[3~"); KEY(SCR_KEY_FUNCTION+0, "\x1bOP"); KEY(SCR_KEY_FUNCTION+1, "\x1bOQ"); KEY(SCR_KEY_FUNCTION+2, "\x1bOR"); KEY(SCR_KEY_FUNCTION+3, "\x1bOS"); KEY(SCR_KEY_FUNCTION+4, "\x1b[15~"); KEY(SCR_KEY_FUNCTION+5, "\x1b[17~"); KEY(SCR_KEY_FUNCTION+6, "\x1b[18~"); KEY(SCR_KEY_FUNCTION+7, "\x1b[19~"); KEY(SCR_KEY_FUNCTION+8, "\x1b[20~"); KEY(SCR_KEY_FUNCTION+9, "\x1b[21~"); KEY(SCR_KEY_FUNCTION+10, "\x1b[23~"); KEY(SCR_KEY_FUNCTION+11, "\x1b[24~"); KEY(SCR_KEY_FUNCTION+12, "\x1b[25~"); KEY(SCR_KEY_FUNCTION+13, "\x1b[26~"); KEY(SCR_KEY_FUNCTION+14, "\x1b[28~"); KEY(SCR_KEY_FUNCTION+15, "\x1b[29~"); KEY(SCR_KEY_FUNCTION+16, "\x1b[31~"); KEY(SCR_KEY_FUNCTION+17, "\x1b[32~"); KEY(SCR_KEY_FUNCTION+18, "\x1b[33~"); KEY(SCR_KEY_FUNCTION+19, "\x1b[34~"); default: logMessage(LOG_WARNING, "unsuported key: %04X", key); return 0; } #undef CURSOR_KEY #undef KEY } else { int byte = convertWcharToChar(character); if (byte == EOF) { logMessage(LOG_WARNING, "character not supported in local character set: 0X%04X", key); return 0; } STR_BEGIN(buffer, sizeof(buffer)); if (key & SCR_KEY_ALT_LEFT) STR_PRINTF("%c", ESC); STR_PRINTF("\\%03o", byte); STR_END; sequence = buffer; } logBytes(LOG_CATEGORY(SCREEN_DRIVER), "insert bytes", sequence, strlen(sequence)); return doScreenCommand("stuff", sequence, NULL); }
void formatAddress (char *buffer, size_t bufferSize, const void *address, int addressSize) { #ifdef AF_INET const struct sockaddr *sa = address; switch (sa->sa_family) { #ifndef __MINGW32__ case AF_LOCAL: { const struct sockaddr_un *local = address; if (addressSize <= sizeof(sa_family_t)) { snprintf(buffer, bufferSize, "local <unnamed>"); } else { snprintf(buffer, bufferSize, "local %s", local->sun_path); } break; } #endif /* __MINGW32__ */ case AF_INET: { const struct sockaddr_in *inet = address; snprintf(buffer, bufferSize, "inet %s:%d", inet_ntoa(inet->sin_addr), ntohs(inet->sin_port)); break; } default: #if defined(HAVE_GETNAMEINFO) && !defined(WINDOWS) { char host[NI_MAXHOST]; char service[NI_MAXSERV]; int err; if (!(err = getnameinfo(address, addressSize, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV))) { snprintf(buffer, bufferSize, "af=%d %s:%s", sa->sa_family, host, service); break; } if (err != EAI_FAMILY) { #ifdef HAVE_GAI_STRERROR snprintf(buffer, bufferSize, "reverse lookup error for address family %d: %s", sa->sa_family, #ifdef EAI_SYSTEM (err == EAI_SYSTEM)? strerror(errno): #endif /* EAI_SYSTEM */ gai_strerror(err)); #else /* HAVE_GAI_STRERROR */ snprintf(buffer, bufferSize, "reverse lookup error %d for address family %d.", err, sa->sa_family); #endif /* HAVE_GAI_STRERROR */ break; } } #endif /* GETNAMEINFO */ { STR_BEGIN(buffer, bufferSize); STR_PRINTF("address family %d:", sa->sa_family); { const unsigned char *byte = address; const unsigned char *end = byte + addressSize; while (byte < end) STR_PRINTF(" %02X", *byte++); } STR_END } break; } #else /* AF_INET */ snprintf(buffer, bufferSize, "unknown"); #endif /* AF_INET */ }
void logData (int level, LogDataFormatter *formatLogData, const void *data) { const char *prefix = NULL; if (level & LOG_FLG_CATEGORY) { int category = level & LOG_MSK_CATEGORY; if (!logCategoryFlags[category]) return; level = categoryLogLevel; { const LogCategoryEntry *ctg = &logCategoryTable[category]; prefix = ctg->prefix; } } { int write = level <= systemLogLevel; int print = level <= stderrLogLevel; if (write || print) { int oldErrno = errno; char record[0X1000]; STR_BEGIN(record, sizeof(record)); if (prefix) STR_PRINTF("%s: ", prefix); { size_t sublength = formatLogData(STR_NEXT, STR_LEFT, data); STR_ADJUST(sublength); } STR_END if (write) { writeLogRecord(record); #if defined(WINDOWS) if (windowsEventLog != INVALID_HANDLE_VALUE) { const char *strings[] = {record}; ReportEvent(windowsEventLog, toWindowsEventType(level), 0, 0, NULL, ARRAY_COUNT(strings), 0, strings, NULL); } #elif defined(__MSDOS__) #elif defined(__ANDROID__) __android_log_write(toAndroidLogPriority(level), PACKAGE_TARNAME, record); #elif defined(HAVE_SYSLOG_H) if (syslogOpened) syslog(level, "%s", record); #endif /* write system log */ } if (print) { FILE *stream = stderr; lockStream(stream); if (logPrefixStack) { const char *prefix = logPrefixStack->prefix; if (*prefix) { fputs(prefix, stream); fputs(": ", stream); } } fputs(record, stream); fputc('\n', stream); flushStream(stream); unlockStream(stream); } errno = oldErrno; } }
size_t describeCommand (int command, char *buffer, size_t size, CommandDescriptionOption options) { size_t length; STR_BEGIN(buffer, size); unsigned int arg = BRL_ARG_GET(command); unsigned int arg1 = BRL_CODE_GET(ARG, command); unsigned int arg2 = BRL_CODE_GET(EXT, command); const CommandEntry *cmd = getCommandEntry(command); if (!cmd) { STR_PRINTF("%s: %06X", gettext("unknown command"), command); } else { if (options & CDO_IncludeName) { STR_PRINTF("%s: ", cmd->name); } if (cmd->isToggle && (command & BRL_FLG_TOGGLE_MASK)) { const char *text = gettext(cmd->description); size_t length = strlen(text); char buffer[length + 1]; char *delimiter; strcpy(buffer, text); delimiter = strchr(buffer, '/'); if (delimiter) { char *source; char *target; if (command & BRL_FLG_TOGGLE_ON) { target = delimiter; if (!(source = strchr(target, ' '))) source = target + strlen(target); } else if (command & BRL_FLG_TOGGLE_OFF) { { char oldDelimiter = *delimiter; *delimiter = 0; target = strrchr(buffer, ' '); *delimiter = oldDelimiter; } target = target? (target + 1): buffer; source = delimiter + 1; } else { goto toggleReady; } memmove(target, source, (strlen(source) + 1)); } toggleReady: STR_PRINTF("%s", buffer); } else { STR_PRINTF("%s", gettext(cmd->description)); } if (options & CDO_IncludeOperand) { if (cmd->isCharacter) { STR_PRINTF(" [U+%04X]", arg); } if (cmd->isBraille) { int none = 1; STR_PRINTF(" ["); { static const int dots[] = { BRL_DOTC, BRL_DOT1, BRL_DOT2, BRL_DOT3, BRL_DOT4, BRL_DOT5, BRL_DOT6, BRL_DOT7, BRL_DOT8, 0 }; const int *dot = dots; while (*dot) { if (command & *dot) { none = 0; if (dot == dots) { STR_PRINTF("C"); } else { unsigned int number = dot - dots; STR_PRINTF("%u", number); } } dot += 1; } } if (none) STR_PRINTF("%s", gettext("space")); STR_PRINTF("]"); } if (cmd->isKeyboard) { STR_PRINTF(" [\\X%02X]", arg1); } if (cmd->isColumn && !cmd->isRouting && ( (arg == BRL_MSK_ARG) /* key event processing */ || ((options & CDO_DefaultOperand) && !arg) /* key table listing */ )) { STR_PRINTF(" %s", gettext("at cursor")); } else if (cmd->isColumn || cmd->isRow || cmd->isOffset) { STR_PRINTF(" #%u", arg - (cmd->code & BRL_MSK_ARG) + 1); } else if (cmd->isRange) { STR_PRINTF(" #%u-%u", arg1, arg2); } if (cmd->isInput) { size_t length = formatCommandModifiers(STR_NEXT, STR_LEFT, command, commandModifierTable_input); STR_ADJUST(length); } if (cmd->isCharacter) { size_t length = formatCommandModifiers(STR_NEXT, STR_LEFT, command, commandModifierTable_character); STR_ADJUST(length); } if (cmd->isKeyboard) { size_t length = formatCommandModifiers(STR_NEXT, STR_LEFT, command, commandModifierTable_keyboard); STR_ADJUST(length); } } if (cmd->isMotion) { if (cmd->isRow) { if (command & BRL_FLG_LINE_TOLEFT) { STR_PRINTF(", %s", gettext("left margin")); } if (command & BRL_FLG_LINE_SCALED) { STR_PRINTF(", %s", gettext("normalized position")); } } if (command & BRL_FLG_MOTION_ROUTE) { STR_PRINTF(", %s", gettext("drag cursor")); } } } length = STR_LENGTH; STR_END; return length; }
size_t formatBrailleTime (char *buffer, size_t size, const TimeFormattingData *fmt) { size_t length; char time[0X40]; STR_BEGIN(buffer, size); { const char *hourFormat = "%02" PRIu8; const char *minuteFormat = "%02" PRIu8; const char *secondFormat = "%02" PRIu8; char separator; switch (prefs.timeSeparator) { default: case tsColon: separator = ':'; break; case tsDot: separator = '.'; break; } switch (prefs.timeFormat) { default: case tf24Hour: break; case tf12Hour: hourFormat = "%" PRIu8; break; } STR_BEGIN(time, sizeof(time)); STR_PRINTF(hourFormat, fmt->components.hour); STR_PRINTF("%c", separator); STR_PRINTF(minuteFormat, fmt->components.minute); if (prefs.showSeconds) { STR_PRINTF("%c", separator); STR_PRINTF(secondFormat, fmt->components.second); } if (fmt->meridian) STR_PRINTF("%s", fmt->meridian); STR_END } if (prefs.datePosition == dpNone) { STR_PRINTF("%s", time); } else { char date[0X40]; { const char *yearFormat = "%04" PRIu16; const char *monthFormat = "%02" PRIu8; const char *dayFormat = "%02" PRIu8; uint16_t year = fmt->components.year; uint8_t month = fmt->components.month + 1; uint8_t day = fmt->components.day + 1; char separator; switch (prefs.dateSeparator) { default: case dsDash: separator = '-'; break; case dsSlash: separator = '/'; break; case dsDot: separator = '.'; break; } STR_BEGIN(date, sizeof(date)); switch (prefs.dateFormat) { default: case dfYearMonthDay: STR_PRINTF(yearFormat, year); STR_PRINTF("%c", separator); STR_PRINTF(monthFormat, month); STR_PRINTF("%c", separator); STR_PRINTF(dayFormat, day); break; case dfMonthDayYear: STR_PRINTF(monthFormat, month); STR_PRINTF("%c", separator); STR_PRINTF(dayFormat, day); STR_PRINTF("%c", separator); STR_PRINTF(yearFormat, year); break; case dfDayMonthYear: STR_PRINTF(dayFormat, day); STR_PRINTF("%c", separator); STR_PRINTF(monthFormat, month); STR_PRINTF("%c", separator); STR_PRINTF(yearFormat, year); break; } STR_END switch (prefs.datePosition) { case dpBeforeTime: STR_PRINTF("%s %s", date, time); break; case dpAfterTime: STR_PRINTF("%s %s", time, date); break; default: STR_PRINTF("%s", date); break; } } } length = STR_LENGTH; STR_END return length; }