void DisplayMenuToClient (edict_t *ent, MenuText *menu) { if (!IsValidPlayer (ent)) return; int clientIndex = ENTINDEX (ent) - 1; if (menu != null) { String tempText = String (menu->menuText); tempText.Replace ("\v", "\n"); char *text = g_localizer->TranslateInput (tempText); tempText = String (text); // make menu looks best for (int i = 0; i <= 9; i++) tempText.Replace (FormatBuffer ("%d.", i), FormatBuffer ("\\r%d.\\w", i)); text = tempText; while (strlen (text) >= 64) { MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (1); for (int i = 0; i <= 63; i++) WRITE_CHAR (text[i]); MESSAGE_END (); text += 64; } MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (0); WRITE_STRING (text); MESSAGE_END(); g_clients[clientIndex].menu = menu; } else { MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (0); WRITE_CHAR (0); WRITE_BYTE (0); WRITE_STRING (""); MESSAGE_END(); g_clients[clientIndex].menu = null; } CLIENT_COMMAND (ent, "speak \"player/geiger1\"\n"); // Stops others from hearing menu sounds.. }
static void bar_pane_exif_entry_write_config(GtkWidget *entry, GString *outstr, gint indent) { ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data"); if (!ee) return; WRITE_NL(); WRITE_STRING("<entry "); WRITE_CHAR(*ee, key); if (!ee->auto_title) WRITE_CHAR(*ee, title); WRITE_BOOL(*ee, if_set); WRITE_BOOL(*ee, editable); WRITE_STRING("/>"); }
/* warning - don't pass here const string */ void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen) { char *n = menu; char c = 0; int a; if (!gmsgShowMenu) return; // some games don't support ShowMenu (Firearms) do { a = mlen; if (a > 175) a = 175; mlen -= a; c = *(n+=a); *n = 0; MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pEdict); WRITE_SHORT(slots); WRITE_CHAR(time); WRITE_BYTE(c ? TRUE : FALSE); WRITE_STRING(menu); MESSAGE_END(); *n = c; menu = n; } while (*n); }
static void write_color_profile(GString *outstr, gint indent) { gint i; #ifndef HAVE_LCMS g_string_append_printf(outstr, "<!-- NOTICE: %s was not built with support for color profiles,\n" " color profile options will have no effect.\n-->\n", GQ_APPNAME); #endif WRITE_NL(); WRITE_STRING("<color_profiles "); WRITE_CHAR(options->color_profile, screen_file); WRITE_BOOL(options->color_profile, enabled); WRITE_BOOL(options->color_profile, use_image); WRITE_INT(options->color_profile, input_type); WRITE_BOOL(options->color_profile, use_x11_screen_profile); WRITE_INT(options->color_profile, render_intent); WRITE_STRING(">"); indent++; for (i = 0; i < COLOR_PROFILE_INPUTS; i++) { WRITE_NL(); WRITE_STRING("<profile "); write_char_option(outstr, indent, "input_file", options->color_profile.input_file[i]); write_char_option(outstr, indent, "input_name", options->color_profile.input_name[i]); WRITE_STRING("/>"); } indent--; WRITE_NL(); WRITE_STRING("</color_profiles>"); }
*/ static void Write_Char(char c, int n) /* ** Write out repeated number of chars. ** Unicode: not used ** ***********************************************************************/ { char buf[4]; buf[0] = c; for (; n > 0; n--) WRITE_CHAR(buf); }
static void bar_pane_keywords_write_config(GtkWidget *pane, GString *outstr, gint indent) { PaneKeywordsData *pkd; pkd = g_object_get_data(G_OBJECT(pane), "pane_data"); if (!pkd) return; WRITE_NL(); WRITE_STRING("<pane_keywords "); write_char_option(outstr, indent, "id", pkd->pane.id); write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(pkd->pane.title))); WRITE_BOOL(pkd->pane, expanded); WRITE_CHAR(*pkd, key); WRITE_STRING("/>"); }
static void bar_pane_comment_write_config(GtkWidget *pane, GString *outstr, gint indent) { PaneCommentData *pcd; pcd = g_object_get_data(G_OBJECT(pane), "pane_data"); if (!pcd) return; WRITE_NL(); WRITE_STRING("<pane_comment "); write_char_option(outstr, indent, "id", pcd->pane.id); write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(pcd->pane.title))); WRITE_BOOL(pcd->pane, expanded); WRITE_CHAR(*pcd, key); WRITE_INT(*pcd, height); WRITE_STRING("/>"); }
*/ static void Move_Cursor(STD_TERM *term, int count) /* ** Move cursor right or left by one char. ** Unicode: not yet supported! ** ***********************************************************************/ { if (count < 0) { if (term->pos > 0) { term->pos--; Write_Char(BS, 1); } } else { if (term->pos < term->end) { WRITE_CHAR(term->buffer + term->pos); term->pos++; } } }
*/ static char *Insert_Char(STD_TERM *term, char *cp) /* ** Insert a char at the current position. Adjust end position. ** Redisplay the line. ** Unicode: not yet supported! ** ***********************************************************************/ { //printf("\r\nins pos: %d end: %d ==", term->pos, term->end); if (term->end < TERM_BUF_LEN-1) { // avoid buffer overrun if (term->pos < term->end) { // open space for it: memmove(term->buffer + term->pos + 1, term->buffer + term->pos, 1 + term->end - term->pos); } WRITE_CHAR(cp); term->buffer[term->pos] = *cp; term->end++; term->pos++; Show_Line(term, 0); } return ++cp; }
void Message::Send() { msgparam *pParam = NULL; for (size_t i=1; i<=m_CurParam; i++) { pParam = m_Params[i]; switch (pParam->type) { case arg_byte: WRITE_BYTE(pParam->v.iData); break; case arg_char: WRITE_CHAR(pParam->v.iData); break; case arg_short: WRITE_SHORT(pParam->v.iData); break; case arg_long: WRITE_LONG(pParam->v.iData); break; case arg_angle: WRITE_ANGLE(pParam->v.fData); break; case arg_coord: WRITE_COORD(pParam->v.fData); break; case arg_string: WRITE_STRING(pParam->szData.chars()); break; case arg_entity: WRITE_ENTITY(pParam->v.iData); break; } } }
void UTIL_ShowMenu(edict_t* pEdict, int keybits, int time, char *menu, int mlen) { char *n = menu; char c = 0; int a; do { a = mlen; if (a > 175) a = 175; mlen -= a; c = *(n+=a); *n = 0; MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pEdict); WRITE_SHORT(keybits); WRITE_CHAR(time); WRITE_BYTE(c ? TRUE : FALSE); WRITE_STRING(menu); MESSAGE_END(); *n = c; menu = n; } while (*n); }
static void write_global_attributes(GString *outstr, gint indent) { /* General Options */ WRITE_NL(); WRITE_BOOL(*options, show_icon_names); WRITE_SEPARATOR(); WRITE_NL(); WRITE_BOOL(*options, tree_descend_subdirs); WRITE_NL(); WRITE_BOOL(*options, view_dir_list_single_click_enter); WRITE_NL(); WRITE_BOOL(*options, lazy_image_sync); WRITE_NL(); WRITE_BOOL(*options, update_on_time_change); WRITE_SEPARATOR(); WRITE_NL(); WRITE_BOOL(*options, progressive_key_scrolling); WRITE_NL(); WRITE_UINT(*options, keyboard_scroll_step); WRITE_NL(); WRITE_UINT(*options, duplicates_similarity_threshold); WRITE_NL(); WRITE_UINT(*options, duplicates_match); WRITE_NL(); WRITE_UINT(*options, duplicates_select_type); WRITE_NL(); WRITE_BOOL(*options, duplicates_thumbnails); WRITE_NL(); WRITE_BOOL(*options, rot_invariant_sim); WRITE_SEPARATOR(); WRITE_NL(); WRITE_BOOL(*options, mousewheel_scrolls); WRITE_NL(); WRITE_BOOL(*options, image_lm_click_nav); WRITE_NL(); WRITE_INT(*options, open_recent_list_maxsize); WRITE_NL(); WRITE_INT(*options, dnd_icon_size); WRITE_NL(); WRITE_BOOL(*options, place_dialogs_under_mouse); WRITE_NL(); WRITE_BOOL(*options, save_window_positions); WRITE_NL(); WRITE_BOOL(*options, use_saved_window_positions_for_new_windows); WRITE_NL(); WRITE_BOOL(*options, tools_restore_state); /* File operations Options */ WRITE_NL(); WRITE_BOOL(*options, file_ops.enable_in_place_rename); WRITE_NL(); WRITE_BOOL(*options, file_ops.confirm_delete); WRITE_NL(); WRITE_BOOL(*options, file_ops.enable_delete_key); WRITE_NL(); WRITE_BOOL(*options, file_ops.safe_delete_enable); WRITE_NL(); WRITE_CHAR(*options, file_ops.safe_delete_path); WRITE_NL(); WRITE_INT(*options, file_ops.safe_delete_folder_maxsize); /* Properties dialog Options */ WRITE_NL(); WRITE_CHAR(*options, properties.tabs_order); /* Image Options */ WRITE_NL(); WRITE_UINT(*options, image.zoom_mode); WRITE_SEPARATOR(); WRITE_NL(); WRITE_BOOL(*options, image.zoom_2pass); WRITE_NL(); WRITE_BOOL(*options, image.zoom_to_fit_allow_expand); WRITE_NL(); WRITE_UINT(*options, image.zoom_quality); WRITE_NL(); WRITE_INT(*options, image.zoom_increment); WRITE_NL(); WRITE_BOOL(*options, image.fit_window_to_image); WRITE_NL(); WRITE_BOOL(*options, image.limit_window_size); WRITE_NL(); WRITE_INT(*options, image.max_window_size); WRITE_NL(); WRITE_BOOL(*options, image.limit_autofit_size); WRITE_NL(); WRITE_INT(*options, image.max_autofit_size); WRITE_NL(); WRITE_UINT(*options, image.scroll_reset_method); WRITE_NL(); WRITE_INT(*options, image.tile_cache_max); WRITE_NL(); WRITE_INT(*options, image.image_cache_max); WRITE_NL(); WRITE_BOOL(*options, image.enable_read_ahead); WRITE_NL(); WRITE_BOOL(*options, image.exif_rotate_enable); WRITE_NL(); WRITE_BOOL(*options, image.use_custom_border_color); WRITE_NL(); WRITE_BOOL(*options, image.use_custom_border_color_in_fullscreen); WRITE_NL(); WRITE_COLOR(*options, image.border_color); WRITE_NL(); WRITE_BOOL(*options, image.use_clutter_renderer); /* Thumbnails Options */ WRITE_NL(); WRITE_INT(*options, thumbnails.max_width); WRITE_NL(); WRITE_INT(*options, thumbnails.max_height); WRITE_NL(); WRITE_BOOL(*options, thumbnails.enable_caching); WRITE_NL(); WRITE_BOOL(*options, thumbnails.cache_into_dirs); WRITE_NL(); WRITE_BOOL(*options, thumbnails.use_xvpics); WRITE_NL(); WRITE_BOOL(*options, thumbnails.spec_standard); WRITE_NL(); WRITE_UINT(*options, thumbnails.quality); WRITE_NL(); WRITE_BOOL(*options, thumbnails.use_exif); /* File sorting Options */ WRITE_NL(); WRITE_INT(*options, file_sort.method); WRITE_NL(); WRITE_BOOL(*options, file_sort.ascending); WRITE_NL(); WRITE_BOOL(*options, file_sort.case_sensitive); WRITE_NL(); WRITE_BOOL(*options, file_sort.natural); /* Fullscreen Options */ WRITE_NL(); WRITE_INT(*options, fullscreen.screen); WRITE_NL(); WRITE_BOOL(*options, fullscreen.clean_flip); WRITE_NL(); WRITE_BOOL(*options, fullscreen.disable_saver); WRITE_NL(); WRITE_BOOL(*options, fullscreen.above); WRITE_SEPARATOR(); /* Image Overlay Options */ WRITE_NL(); WRITE_CHAR(*options, image_overlay.template_string); WRITE_NL(); WRITE_INT(*options, image_overlay.x); WRITE_NL(); WRITE_INT(*options, image_overlay.y); WRITE_NL(); WRITE_INT(*options, image_overlay.text_red); WRITE_NL(); WRITE_INT(*options, image_overlay.text_green); WRITE_NL(); WRITE_INT(*options, image_overlay.text_blue); WRITE_NL(); WRITE_INT(*options, image_overlay.text_alpha); WRITE_NL(); WRITE_INT(*options, image_overlay.background_red); WRITE_NL(); WRITE_INT(*options, image_overlay.background_green); WRITE_NL(); WRITE_INT(*options, image_overlay.background_blue); WRITE_NL(); WRITE_INT(*options, image_overlay.background_alpha); WRITE_NL(); WRITE_CHAR(*options, image_overlay.font); /* Slideshow Options */ WRITE_NL(); WRITE_INT_UNIT(*options, slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION); WRITE_NL(); WRITE_BOOL(*options, slideshow.random); WRITE_NL(); WRITE_BOOL(*options, slideshow.repeat); /* Collection Options */ WRITE_NL(); WRITE_BOOL(*options, collections.rectangular_selection); /* Filtering Options */ WRITE_NL(); WRITE_BOOL(*options, file_filter.show_hidden_files); WRITE_NL(); WRITE_BOOL(*options, file_filter.show_parent_directory); WRITE_NL(); WRITE_BOOL(*options, file_filter.show_dot_directory); WRITE_NL(); WRITE_BOOL(*options, file_filter.disable_file_extension_checks); WRITE_NL(); WRITE_BOOL(*options, file_filter.disable); WRITE_SEPARATOR(); /* Sidecars Options */ WRITE_NL(); WRITE_CHAR(*options, sidecar.ext); /* Shell command */ WRITE_NL(); WRITE_CHAR(*options, shell.path); WRITE_NL(); WRITE_CHAR(*options, shell.options); /* Helpers */ WRITE_NL(); WRITE_CHAR(*options, helpers.html_browser.command_name); WRITE_NL(); WRITE_CHAR(*options, helpers.html_browser.command_line); /* Metadata Options */ WRITE_NL(); WRITE_BOOL(*options, metadata.enable_metadata_dirs); WRITE_NL(); WRITE_BOOL(*options, metadata.save_in_image_file); WRITE_NL(); WRITE_BOOL(*options, metadata.save_legacy_IPTC); WRITE_NL(); WRITE_BOOL(*options, metadata.warn_on_write_problems); WRITE_NL(); WRITE_BOOL(*options, metadata.save_legacy_format); WRITE_NL(); WRITE_BOOL(*options, metadata.sync_grouped_files); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_write); WRITE_NL(); WRITE_INT(*options, metadata.confirm_timeout); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_after_timeout); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_on_image_change); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_on_dir_change); WRITE_NL(); WRITE_BOOL(*options, metadata.keywords_case_sensitive); WRITE_NL(); WRITE_BOOL(*options, metadata.write_orientation); WRITE_NL(); WRITE_INT(*options, stereo.mode); WRITE_NL(); WRITE_INT(*options, stereo.fsmode); WRITE_NL(); WRITE_BOOL(*options, stereo.enable_fsmode); WRITE_NL(); WRITE_INT(*options, stereo.fixed_w); WRITE_NL(); WRITE_INT(*options, stereo.fixed_h); WRITE_NL(); WRITE_INT(*options, stereo.fixed_x1); WRITE_NL(); WRITE_INT(*options, stereo.fixed_y1); WRITE_NL(); WRITE_INT(*options, stereo.fixed_x2); WRITE_NL(); WRITE_INT(*options, stereo.fixed_y2); }
void RadioShowMenu( edict_t *pEntity, edict_t *pRadio, int n ) { // Cant use radio in spec mode if (pEntity->v.iuser1 > 0) return; // dont use if radio is tuning if (pRadio->v.iuser1 == 1) return; char menutext[1024]; int bitsel = 0; if (n < 3) { sprintf(menutext, "Switch to song:\n\n"); if (n == 1) { strcat(menutext, "1. Take my Breath Away\n"); strcat(menutext, "2. Dreamgate - Now we are free\n"); strcat(menutext, "3. Hamsterdance\n"); strcat(menutext, "4. Muse - Plug In Baby\n"); strcat(menutext, "5. Scooter - Ramp [Supertramp - Logical Song]\n\n"); strcat(menutext, "6. Show Page 2\n\n"); } else { strcat(menutext, "1. Boomtang Boys - Popcorn [Micro Mix]\n"); strcat(menutext, "2. Mr. Roboto\n"); strcat(menutext, "3. Chicane - Salt Water\n"); strcat(menutext, "4. John Jeski - Sailing Accordion Polka\n"); strcat(menutext, "5. Warrior - Voodoo\n\n"); strcat(menutext, "6. Show Page 1\n\n"); } strcat(menutext, "7. Switch to next song\n"); strcat(menutext, "8. Switch to previous song\n\n"); strcat(menutext, "9. Show pitch menu\n"); } else { sprintf(menutext, "Change the pitch and speed:\n\n"); strcat(menutext, "1. Change to normal pitch\n\n"); strcat(menutext, "2. 0.5x speed/pitch\n"); strcat(menutext, "3. 0.8x speed/pitch\n"); strcat(menutext, "4. 1.2x speed/pitch\n"); strcat(menutext, "5. 1.4x speed/pitch\n"); strcat(menutext, "6. 1.5x speed/pitch\n"); strcat(menutext, "7. 1.8x speed/pitch\n"); strcat(menutext, "8. 2.0x speed/pitch\n\n"); strcat(menutext, "9. Back to song menu\n"); } strcat(menutext, "\n\n0. Cancel\n"); bitsel |= 1<<0; // activate this choice in the menu 1 bitsel |= 1<<1; // activate this choice in the menu 2 bitsel |= 1<<2; // activate this choice in the menu 3 bitsel |= 1<<3; // activate this choice in the menu 4 bitsel |= 1<<4; // activate this choice in the menu 5 bitsel |= 1<<5; // activate this choice in the menu 6 bitsel |= 1<<6; // activate this choice in the menu 7 bitsel |= 1<<7; // activate this choice in the menu 8 bitsel |= 1<<8; // activate this choice in the menu 9 bitsel |= 1<<9; // activate this choice in the menu 9 // Now, show the menu to everyone! int gmsgShowMenu = 0; gmsgShowMenu = REG_USER_MSG( "ShowMenu", -1 ); int char_count = 0; char *pFileList = menutext; char *aFileList = menutext; while ( pFileList && *pFileList && char_count < 1024 ) { char chunk[MAX_MENU_CHUNK+1]; if ( strlen( pFileList ) < MAX_MENU_CHUNK ) { strcpy( chunk, pFileList ); } else { strncpy( chunk, pFileList, MAX_MENU_CHUNK ); chunk[MAX_MENU_CHUNK] = 0; // strncpy doesn't always append the null terminator } char_count += strlen( chunk ); if ( char_count < 1024 ) pFileList = aFileList + char_count; else *pFileList = 0; ALERT(at_console, "SENDING %i!!!\n", char_count); MESSAGE_BEGIN( MSG_ONE, gmsgShowMenu, NULL, pEntity ); WRITE_SHORT( bitsel ); WRITE_CHAR( 60 ); WRITE_BYTE( *pFileList ? TRUE : FALSE ); // TRUE means there is still more message to come WRITE_STRING( chunk ); MESSAGE_END(); } lastMenuPage[ENTINDEX(pEntity)] = n; lastMenuEnt[ENTINDEX(pEntity)] = ENTINDEX(pRadio); // Set the values that determine how long we accept input... menushow2[ENTINDEX(pEntity)] = gpGlobals->time + 60; }
static cell AMX_NATIVE_CALL write_char(AMX *amx, cell *params) /* 1 param */ { WRITE_CHAR(params[1]); return 1; }
/*** *int _output(stream, format, argptr), static int output(format, argptr) * *Purpose: * Output performs printf style output onto a stream. It is called by * printf/fprintf/sprintf/vprintf/vfprintf/vsprintf to so the dirty * work. In multi-thread situations, _output assumes that the given * stream is already locked. * * Algorithm: * The format string is parsed by using a finite state automaton * based on the current state and the current character read from * the format string. Thus, looping is on a per-character basis, * not a per conversion specifier basis. Once the format specififying * character is read, output is performed. * *Entry: * FILE *stream - stream for output * char *format - printf style format string * va_list argptr - pointer to list of subsidiary arguments * *Exit: * Returns the number of characters written, or -1 if an output error * occurs. *ifdef _UNICODE * The wide-character flavour returns the number of wide-characters written. *endif * *Exceptions: * *******************************************************************************/ #ifdef CPRFLAG #ifndef FORMAT_VALIDATIONS _CRTIMP int __cdecl _vtcprintf ( const _TCHAR *format, va_list argptr ) { return _vtcprintf_l(format, NULL, argptr); } #else /* FORMAT_VALIDATIONS */ _CRTIMP int __cdecl _vtcprintf_s ( const _TCHAR *format, va_list argptr ) { return _vtcprintf_s_l(format, NULL, argptr); } #endif /* FORMAT_VALIDATIONS */ #endif /* CPRFLAG */ #ifdef CPRFLAG #ifndef FORMAT_VALIDATIONS _CRTIMP int __cdecl _vtcprintf_l ( #else /* FORMAT_VALIDATIONS */ _CRTIMP int __cdecl _vtcprintf_s_l ( #endif /* FORMAT_VALIDATIONS */ #else /* CPRFLAG */ #ifdef _UNICODE #ifndef FORMAT_VALIDATIONS int __cdecl _woutput ( miniFILE *stream, #else /* FORMAT_VALIDATIONS */ int __cdecl _woutput_s ( miniFILE *stream, #endif /* FORMAT_VALIDATIONS */ #else /* _UNICODE */ #ifndef FORMAT_VALIDATIONS int __cdecl _output ( miniFILE *stream, #else /* FORMAT_VALIDATIONS */ int __cdecl _output_s ( miniFILE *stream, #endif /* FORMAT_VALIDATIONS */ #endif /* _UNICODE */ #endif /* CPRFLAG */ const _TCHAR *format, va_list argptr ) { int hexadd=0; /* offset to add to number to get 'a'..'f' */ TCHAR ch; /* character just read */ int flags=0; /* flag word -- see #defines above for flag values */ enum STATE state; /* current state */ enum CHARTYPE chclass; /* class of current character */ int radix; /* current conversion radix */ int charsout; /* characters currently written so far, -1 = IO error */ int fldwidth = 0; /* selected field width -- 0 means default */ int precision = 0; /* selected precision -- -1 means default */ TCHAR prefix[2]; /* numeric prefix -- up to two characters */ int prefixlen=0; /* length of prefix -- 0 means no prefix */ int capexp = 0; /* non-zero = 'E' exponent signifient, zero = 'e' */ int no_output=0; /* non-zero = prodcue no output for this specifier */ union { const char *sz; /* pointer text to be printed, not zero terminated */ const wchar_t *wz; } text; int textlen; /* length of the text in bytes/wchars to be printed. textlen is in multibyte or wide chars if _UNICODE */ union { char sz[BUFFERSIZE]; #ifdef _UNICODE wchar_t wz[BUFFERSIZE]; #endif /* _UNICODE */ } buffer; wchar_t wchar; /* temp wchar_t */ int buffersize; /* size of text.sz (used only for the call to _cfltcvt) */ int bufferiswide=0; /* non-zero = buffer contains wide chars already */ #ifndef CPRFLAG _VALIDATE_RETURN( (stream != NULL), EINVAL, -1); #endif /* CPRFLAG */ _VALIDATE_RETURN( (format != NULL), EINVAL, -1); charsout = 0; /* no characters written yet */ textlen = 0; /* no text yet */ state = ST_NORMAL; /* starting state */ buffersize = 0; /* main loop -- loop while format character exist and no I/O errors */ while ((ch = *format++) != _T('\0') && charsout >= 0) { #ifndef FORMAT_VALIDATIONS chclass = FIND_CHAR_CLASS(__lookuptable, ch); /* find character class */ state = FIND_NEXT_STATE(__lookuptable, chclass, state); /* find next state */ #else /* FORMAT_VALIDATIONS */ chclass = FIND_CHAR_CLASS(__lookuptable_s, ch); /* find character class */ state = FIND_NEXT_STATE(__lookuptable_s, chclass, state); /* find next state */ _VALIDATE_RETURN((state != ST_INVALID), EINVAL, -1); #endif /* FORMAT_VALIDATIONS */ /* execute code for each state */ switch (state) { case ST_NORMAL: NORMAL_STATE: /* normal state -- just write character */ #ifdef _UNICODE bufferiswide = 1; #else /* _UNICODE */ bufferiswide = 0; #endif /* _UNICODE */ WRITE_CHAR(ch, &charsout); break; case ST_PERCENT: /* set default value of conversion parameters */ prefixlen = fldwidth = no_output = capexp = 0; flags = 0; precision = -1; bufferiswide = 0; /* default */ break; case ST_FLAG: /* set flag based on which flag character */ switch (ch) { case _T('-'): flags |= FL_LEFT; /* '-' => left justify */ break; case _T('+'): flags |= FL_SIGN; /* '+' => force sign indicator */ break; case _T(' '): flags |= FL_SIGNSP; /* ' ' => force sign or space */ break; case _T('#'): flags |= FL_ALTERNATE; /* '#' => alternate form */ break; case _T('0'): flags |= FL_LEADZERO; /* '0' => pad with leading zeros */ break; } break; case ST_WIDTH: /* update width value */ if (ch == _T('*')) { /* get width from arg list */ fldwidth = get_int_arg(&argptr); if (fldwidth < 0) { /* ANSI says neg fld width means '-' flag and pos width */ flags |= FL_LEFT; fldwidth = -fldwidth; } } else { /* add digit to current field width */ fldwidth = fldwidth * 10 + (ch - _T('0')); } break; case ST_DOT: /* zero the precision, since dot with no number means 0 not default, according to ANSI */ precision = 0; break; case ST_PRECIS: /* update precison value */ if (ch == _T('*')) { /* get precision from arg list */ precision = get_int_arg(&argptr); if (precision < 0) precision = -1; /* neg precision means default */ } else { /* add digit to current precision */ precision = precision * 10 + (ch - _T('0')); } break; case ST_SIZE: /* just read a size specifier, set the flags based on it */ switch (ch) { case _T('l'): /* * In order to handle the ll case, we depart from the * simple deterministic state machine. */ if (*format == _T('l')) { ++format; flags |= FL_LONGLONG; /* 'll' => long long */ } else { flags |= FL_LONG; /* 'l' => long int or wchar_t */ } break; case _T('I'): /* * In order to handle the I, I32, and I64 size modifiers, we * depart from the simple deterministic state machine. The * code below scans for characters following the 'I', * and defaults to 64 bit on WIN64 and 32 bit on WIN32 */ #if PTR_IS_INT64 flags |= FL_I64; /* 'I' => __int64 on WIN64 systems */ #endif /* PTR_IS_INT64 */ if ( (*format == _T('6')) && (*(format + 1) == _T('4')) ) { format += 2; flags |= FL_I64; /* I64 => __int64 */ } else if ( (*format == _T('3')) && (*(format + 1) == _T('2')) ) { format += 2; flags &= ~FL_I64; /* I32 => __int32 */ } else if ( (*format == _T('d')) || (*format == _T('i')) || (*format == _T('o')) || (*format == _T('u')) || (*format == _T('x')) || (*format == _T('X')) ) { /* * Nothing further needed. %Id (et al) is * handled just like %d, except that it defaults to 64 bits * on WIN64. Fall through to the next iteration. */ } else { state = ST_NORMAL; goto NORMAL_STATE; } break; case _T('h'): flags |= FL_SHORT; /* 'h' => short int or char */ break; case _T('w'): flags |= FL_WIDECHAR; /* 'w' => wide character */ break; } break; case ST_TYPE: /* we have finally read the actual type character, so we */ /* now format and "print" the output. We use a big switch */ /* statement that sets 'text' to point to the text that should */ /* be printed, and 'textlen' to the length of this text. */ /* Common code later on takes care of justifying it and */ /* other miscellaneous chores. Note that cases share code, */ /* in particular, all integer formatting is done in one place. */ /* Look at those funky goto statements! */ switch (ch) { case _T('C'): /* ISO wide character */ if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR))) #ifdef _UNICODE flags |= FL_SHORT; #else /* _UNICODE */ flags |= FL_WIDECHAR; /* ISO std. */ #endif /* _UNICODE */ /* fall into 'c' case */ case _T('c'): { /* print a single character specified by int argument */ #ifdef _UNICODE bufferiswide = 1; wchar = (wchar_t) get_int_arg(&argptr); if (flags & FL_SHORT) { /* format multibyte character */ /* this is an extension of ANSI */ char tempchar[2]; { tempchar[0] = (char)(wchar & 0x00ff); tempchar[1] = '\0'; } if (_MBTOWC(buffer.wz,tempchar, MB_CUR_MAX) < 0) { /* ignore if conversion was unsuccessful */ no_output = 1; } } else { buffer.wz[0] = wchar; } text.wz = buffer.wz; textlen = 1; /* print just a single character */ #else /* _UNICODE */ if (flags & (FL_LONG|FL_WIDECHAR)) { wchar = (wchar_t) get_short_arg(&argptr); no_output = 1; } else { /* format multibyte character */ /* this is an extension of ANSI */ unsigned short temp; wchar = (wchar_t)get_int_arg(&argptr); temp = (unsigned short)wchar; { buffer.sz[0] = (char) temp; textlen = 1; } } text.sz = buffer.sz; #endif /* _UNICODE */ } break; case _T('Z'): { /* print a Counted String */ struct _count_string { short Length; short MaximumLength; char *Buffer; } *pstr; pstr = (struct _count_string *)get_ptr_arg(&argptr); if (pstr == NULL || pstr->Buffer == NULL) { /* null ptr passed, use special string */ text.sz = __nullstring; textlen = (int)strlen(text.sz); } else { if (flags & FL_WIDECHAR) { text.wz = (wchar_t *)pstr->Buffer; textlen = pstr->Length / (int)sizeof(wchar_t); bufferiswide = 1; } else { bufferiswide = 0; text.sz = pstr->Buffer; textlen = pstr->Length; } } } break; case _T('S'): /* ISO wide character string */ #ifndef _UNICODE if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR))) flags |= FL_WIDECHAR; #else /* _UNICODE */ if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR))) flags |= FL_SHORT; #endif /* _UNICODE */ case _T('s'): { /* print a string -- */ /* ANSI rules on how much of string to print: */ /* all if precision is default, */ /* min(precision, length) if precision given. */ /* prints '(null)' if a null string is passed */ int i; const char *p; /* temps */ const wchar_t *pwch; /* At this point it is tempting to use strlen(), but */ /* if a precision is specified, we're not allowed to */ /* scan past there, because there might be no null */ /* at all. Thus, we must do our own scan. */ i = (precision == -1) ? INT_MAX : precision; text.sz = (char *)get_ptr_arg(&argptr); /* scan for null upto i characters */ #ifdef _UNICODE if (flags & FL_SHORT) { if (text.sz == NULL) /* NULL passed, use special string */ text.sz = __nullstring; p = text.sz; for (textlen=0; textlen<i && *p; textlen++) { ++p; } /* textlen now contains length in multibyte chars */ } else { if (text.wz == NULL) /* NULL passed, use special string */ text.wz = __wnullstring; bufferiswide = 1; pwch = text.wz; while (i-- && *pwch) ++pwch; textlen = (int)(pwch - text.wz); /* in wchar_ts */ /* textlen now contains length in wide chars */ } #else /* _UNICODE */ if (flags & (FL_LONG|FL_WIDECHAR)) { if (text.wz == NULL) /* NULL passed, use special string */ text.wz = __wnullstring; bufferiswide = 1; pwch = text.wz; while ( i-- && *pwch ) ++pwch; textlen = (int)(pwch - text.wz); /* textlen now contains length in wide chars */ } else { if (text.sz == NULL) /* NULL passed, use special string */ text.sz = __nullstring; p = text.sz; while (i-- && *p) ++p; textlen = (int)(p - text.sz); /* length of the string */ } #endif /* _UNICODE */ } break; case _T('n'): { /* write count of characters seen so far into */ /* short/int/long thru ptr read from args */ void *p; /* temp */ p = get_ptr_arg(&argptr); /* %n is disabled */ _VALIDATE_RETURN(("'n' format specifier disabled" && 0), EINVAL, -1); break; /* store chars out into short/long/int depending on flags */ #if !LONG_IS_INT if (flags & FL_LONG) *(long *)p = charsout; else #endif /* !LONG_IS_INT */ #if !SHORT_IS_INT if (flags & FL_SHORT) *(short *)p = (short) charsout; else #endif /* !SHORT_IS_INT */ *(int *)p = charsout; no_output = 1; /* force no output */ } break; case _T('E'): case _T('G'): case _T('A'): capexp = 1; /* capitalize exponent */ ch += _T('a') - _T('A'); /* convert format char to lower */ /* DROP THROUGH */ case _T('e'): case _T('f'): case _T('g'): case _T('a'): { /* floating point conversion -- we call cfltcvt routines */ /* to do the work for us. */ flags |= FL_SIGNED; /* floating point is signed conversion */ text.sz = buffer.sz; /* put result in buffer */ buffersize = BUFFERSIZE; /* compute the precision value */ if (precision < 0) precision = 6; /* default precision: 6 */ else if (precision == 0 && ch == _T('g')) precision = 1; /* ANSI specified */ else if (precision > MAXPRECISION) precision = MAXPRECISION; if (precision > BUFFERSIZE - _CVTBUFSIZE) { precision = BUFFERSIZE - _CVTBUFSIZE; } /* for safecrt, we pass along the FL_ALTERNATE flag to _safecrt_cfltcvt */ if (flags & FL_ALTERNATE) { capexp |= FL_ALTERNATE; } _CRT_DOUBLE tmp; tmp=va_arg(argptr, _CRT_DOUBLE); /* Note: assumes ch is in ASCII range */ /* In safecrt, we provide a special version of _cfltcvt which internally calls printf (see safecrt_output_s.c) */ _CFLTCVT(&tmp, buffer.sz, buffersize, (char)ch, precision, capexp); /* check if result was negative, save '-' for later */ /* and point to positive part (this is for '0' padding) */ if (*text.sz == '-') { flags |= FL_NEGATIVE; ++text.sz; } textlen = (int)strlen(text.sz); /* compute length of text */ } break; case _T('d'): case _T('i'): /* signed decimal output */ flags |= FL_SIGNED; radix = 10; goto COMMON_INT; case _T('u'): radix = 10; goto COMMON_INT; case _T('p'): /* write a pointer -- this is like an integer or long */ /* except we force precision to pad with zeros and */ /* output in big hex. */ precision = 2 * sizeof(void *); /* number of hex digits needed */ #if PTR_IS_INT64 flags |= FL_I64; /* assume we're converting an int64 */ #elif !PTR_IS_INT flags |= FL_LONG; /* assume we're converting a long */ #endif /* !PTR_IS_INT */ /* DROP THROUGH to hex formatting */ case _T('X'): /* unsigned upper hex output */ hexadd = _T('A') - _T('9') - 1; /* set hexadd for uppercase hex */ goto COMMON_HEX; case _T('x'): /* unsigned lower hex output */ hexadd = _T('a') - _T('9') - 1; /* set hexadd for lowercase hex */ /* DROP THROUGH TO COMMON_HEX */ COMMON_HEX: radix = 16; if (flags & FL_ALTERNATE) { /* alternate form means '0x' prefix */ prefix[0] = _T('0'); prefix[1] = (TCHAR)(_T('x') - _T('a') + _T('9') + 1 + hexadd); /* 'x' or 'X' */ prefixlen = 2; } goto COMMON_INT; case _T('o'): /* unsigned octal output */ radix = 8; if (flags & FL_ALTERNATE) { /* alternate form means force a leading 0 */ flags |= FL_FORCEOCTAL; } /* DROP THROUGH to COMMON_INT */ COMMON_INT: { /* This is the general integer formatting routine. */ /* Basically, we get an argument, make it positive */ /* if necessary, and convert it according to the */ /* correct radix, setting text and textlen */ /* appropriately. */ #if _INTEGRAL_MAX_BITS >= 64 // unsigned __int64 number; /* number to convert */ __uint64_t number; /* number to convert */ int digit; /* ascii value of digit */ __int64 l; /* temp long value */ #else /* _INTEGRAL_MAX_BITS >= 64 */ unsigned long number; /* number to convert */ int digit; /* ascii value of digit */ long l; /* temp long value */ #endif /* _INTEGRAL_MAX_BITS >= 64 */ /* 1. read argument into l, sign extend as needed */ #if _INTEGRAL_MAX_BITS >= 64 if (flags & FL_I64) l = get_int64_arg(&argptr); else #endif /* _INTEGRAL_MAX_BITS >= 64 */ if (flags & FL_LONGLONG) l = get_long_long_arg(&argptr); else #if !LONG_IS_INT if (flags & FL_LONG) l = get_long_arg(&argptr); else #endif /* !LONG_IS_INT */ #if !SHORT_IS_INT if (flags & FL_SHORT) { if (flags & FL_SIGNED) l = (short) get_int_arg(&argptr); /* sign extend */ else l = (unsigned short) get_int_arg(&argptr); /* zero-extend*/ } else #endif /* !SHORT_IS_INT */ { if (flags & FL_SIGNED) l = get_int_arg(&argptr); /* sign extend */ else l = (unsigned int) get_int_arg(&argptr); /* zero-extend*/ } /* 2. check for negative; copy into number */ if ( (flags & FL_SIGNED) && l < 0) { number = -l; flags |= FL_NEGATIVE; /* remember negative sign */ } else { number = l; } #if _INTEGRAL_MAX_BITS >= 64 if ( (flags & FL_I64) == 0 && (flags & FL_LONGLONG) == 0 ) { /* * Unless printing a full 64-bit value, insure values * here are not in cananical longword format to prevent * the sign extended upper 32-bits from being printed. */ number &= 0xffffffff; } #endif /* _INTEGRAL_MAX_BITS >= 64 */ /* 3. check precision value for default; non-default */ /* turns off 0 flag, according to ANSI. */ if (precision < 0) precision = 1; /* default precision */ else { flags &= ~FL_LEADZERO; if (precision > MAXPRECISION) precision = MAXPRECISION; } /* 4. Check if data is 0; if so, turn off hex prefix */ if (number == 0) prefixlen = 0; /* 5. Convert data to ASCII -- note if precision is zero */ /* and number is zero, we get no digits at all. */ char *sz; sz = &buffer.sz[BUFFERSIZE-1]; /* last digit at end of buffer */ while (precision-- > 0 || number != 0) { digit = (int)(number % radix) + '0'; number /= radix; /* reduce number */ if (digit > '9') { /* a hex digit, make it a letter */ digit += hexadd; } *sz-- = (char)digit; /* store the digit */ } textlen = (int)((char *)&buffer.sz[BUFFERSIZE-1] - sz); /* compute length of number */ ++sz; /* text points to first digit now */ /* 6. Force a leading zero if FORCEOCTAL flag set */ if ((flags & FL_FORCEOCTAL) && (textlen == 0 || sz[0] != '0')) { *--sz = '0'; ++textlen; /* add a zero */ } text.sz = sz; } break; } /* At this point, we have done the specific conversion, and */ /* 'text' points to text to print; 'textlen' is length. Now we */ /* justify it, put on prefixes, leading zeros, and then */ /* print it. */ if (!no_output) { int padding; /* amount of padding, negative means zero */ if (flags & FL_SIGNED) { if (flags & FL_NEGATIVE) { /* prefix is a '-' */ prefix[0] = _T('-'); prefixlen = 1; } else if (flags & FL_SIGN) { /* prefix is '+' */ prefix[0] = _T('+'); prefixlen = 1; } else if (flags & FL_SIGNSP) { /* prefix is ' ' */ prefix[0] = _T(' '); prefixlen = 1; } } /* calculate amount of padding -- might be negative, */ /* but this will just mean zero */ padding = fldwidth - textlen - prefixlen; /* put out the padding, prefix, and text, in the correct order */ if (!(flags & (FL_LEFT | FL_LEADZERO))) { /* pad on left with blanks */ WRITE_MULTI_CHAR(_T(' '), padding, &charsout); } /* write prefix */ WRITE_STRING(prefix, prefixlen, &charsout); if ((flags & FL_LEADZERO) && !(flags & FL_LEFT)) { /* write leading zeros */ WRITE_MULTI_CHAR(_T('0'), padding, &charsout); } /* write text */ #ifndef _UNICODE if (bufferiswide && (textlen > 0)) { charsout = -1; } else { WRITE_STRING(text.sz, textlen, &charsout); } #else /* _UNICODE */ if (!bufferiswide && textlen > 0) { char *p; int retval = 0 int count; p = text.sz; count = textlen; while (count-- > 0) { retval = _MBTOWC(&wchar, p, MB_CUR_MAX); if (retval <= 0) { charsout = -1; break; } WRITE_CHAR(wchar, &charsout); p += retval; } } else { WRITE_STRING(text.wz, textlen, &charsout); } #endif /* _UNICODE */ if (charsout >= 0 && (flags & FL_LEFT)) { /* pad on right with blanks */ WRITE_MULTI_CHAR(_T(' '), padding, &charsout); } /* we're done! */ }
static hb_buffer_t *tx3g_decode_to_utf8( hb_buffer_t *in ) { uint8_t *pos = in->data; uint8_t *end = in->data + in->size; uint16_t numStyleRecords = 0; uint8_t *startStyle; uint8_t *endStyle; /* * Parse the packet as a TX3G TextSample. * * Look for a single StyleBox ('styl') and read all contained StyleRecords. * Ignore all other box types. * * NOTE: Buffer overflows on read are not checked. */ uint16_t textLength = READ_U16(); uint8_t *text = READ_ARRAY(textLength); startStyle = calloc( textLength, 1 ); endStyle = calloc( textLength, 1 ); while ( pos < end ) { /* * Read TextSampleModifierBox */ uint32_t size = READ_U32(); if ( size == 0 ) { size = pos - end; // extends to end of packet } if ( size == 1 ) { hb_log( "dectx3gsub: TextSampleModifierBox has unsupported large size" ); break; } uint32_t type = READ_U32(); if ( type == FOURCC("uuid") ) { hb_log( "dectx3gsub: TextSampleModifierBox has unsupported extended type" ); break; } if ( type == FOURCC("styl") ) { // Found a StyleBox. Parse the contained StyleRecords if ( numStyleRecords != 0 ) { hb_log( "dectx3gsub: found additional StyleBoxes on subtitle; skipping" ); SKIP_ARRAY(size); continue; } numStyleRecords = READ_U16(); int i; for (i=0; i<numStyleRecords; i++) { StyleRecord curRecord; curRecord.startChar = READ_U16(); curRecord.endChar = READ_U16(); curRecord.fontID = READ_U16(); curRecord.faceStyleFlags = READ_U8(); curRecord.fontSize = READ_U8(); curRecord.textColorRGBA = READ_U32(); startStyle[curRecord.startChar] |= curRecord.faceStyleFlags; endStyle[curRecord.endChar] |= curRecord.faceStyleFlags; } } else { // Found some other kind of TextSampleModifierBox. Skip it. SKIP_ARRAY(size); } } /* * Copy text to output buffer, and add HTML markup for the style records */ int maxOutputSize = textLength + (numStyleRecords * NUM_FACE_STYLE_FLAGS * (MAX_OPEN_TAG_SIZE + MAX_CLOSE_TAG_SIZE)); hb_buffer_t *out = hb_buffer_init( maxOutputSize ); if ( out == NULL ) goto fail; uint8_t *dst = out->data; int charIndex = 0; for ( pos = text, end = text + textLength; pos < end; pos++ ) { if (IS_10xxxxxx(*pos)) { // Is a non-first byte of a multi-byte UTF-8 character WRITE_CHAR(*pos); continue; // ...without incrementing 'charIndex' } uint8_t plusStyles = startStyle[charIndex]; uint8_t minusStyles = endStyle[charIndex]; if (minusStyles & UNDERLINE) WRITE_END_TAG('u'); if (minusStyles & ITALIC) WRITE_END_TAG('i'); if (minusStyles & BOLD) WRITE_END_TAG('b'); if (plusStyles & BOLD) WRITE_START_TAG('b'); if (plusStyles & ITALIC) WRITE_START_TAG('i'); if (plusStyles & UNDERLINE) WRITE_START_TAG('u'); WRITE_CHAR(*pos); charIndex++; } // Trim output buffer to the actual amount of data written out->size = dst - out->data; // Copy metadata from the input packet to the output packet out->s.start = in->s.start; out->s.stop = in->s.stop; fail: free( startStyle ); free( endStyle ); return out; }
/** * Format a string representation of the elements of @p value using @p fmt, * writing the result to @p outp. * * @param value The value to be formatted. * @param fmt The format string. * @param[out] outp On success, the string will be written to this * buffer. This argment may be NULL if the value is * not desired. * @param[in,out] olen The capacity of @p outp. On success, will be set * to the actual number of bytes required for the * requested string encoding (including a trailing * NUL). * @param ap Argument list. * * @par Format Strings * * Value format strings are similar, but not identical to, those used * by printf(3). * * Format specifier format: * %[repeat][flags][width][.precision][length modifier][specifier] * * The format specifier is interpreted as an encoding directive for an * individual value element; each format specifier will fetch the next element * from the value, encode the element as the appropriate type based on the * length modifiers and specifier, and then format the result as a string. * * For example, given a string value of '0x000F', and a format specifier of * '%#hhx', the value will be asked to encode its first element as * BHND_NVRAM_TYPE_UINT8. String formatting will then be applied to the 8-bit * unsigned integer representation, producing a string value of "0xF". * * Repeat: * - [digits] Repeatedly apply the format specifier to the input * value's elements up to `digits` times. The delimiter * must be passed as a string in the next variadic * argument. * - [] Repeatedly apply the format specifier to the input * value's elements until all elements have been. The * processed. The delimiter must be passed as a string in * the next variadic argument. * - [*] Repeatedly apply the format specifier to the input * value's elements. The repeat count is read from the * next variadic argument as a size_t value * * Flags: * - '#' use alternative form (e.g. 0x/0X prefixing of hex * strings). * - '0' zero padding * - '-' left adjust padding * - '+' include a sign character * - ' ' include a space in place of a sign character for * positive numbers. * * Width/Precision: * - digits minimum field width. * - * read the minimum field width from the next variadic * argument as a ssize_t value. A negative value enables * left adjustment. * - .digits field precision. * - .* read the field precision from the next variadic argument * as a ssize_t value. A negative value enables left * adjustment. * * Length Modifiers: * - 'hh', 'I8' Convert the value to an 8-bit signed or unsigned * integer. * - 'h', 'I16' Convert the value to an 16-bit signed or unsigned * integer. * - 'l', 'I32' Convert the value to an 32-bit signed or unsigned * integer. * - 'll', 'j', 'I64' Convert the value to an 64-bit signed or unsigned * integer. * * Data Specifiers: * - 'd', 'i' Convert and format as a signed decimal integer. * - 'u' Convert and format as an unsigned decimal integer. * - 'o' Convert and format as an unsigned octal integer. * - 'x' Convert and format as an unsigned hexadecimal integer, * using lowercase hex digits. * - 'X' Convert and format as an unsigned hexadecimal integer, * using uppercase hex digits. * - 's' Convert and format as a string. * - '%' Print a literal '%' character. * * @retval 0 success * @retval EINVAL If @p fmt contains unrecognized format string * specifiers. * @retval ENOMEM If the @p outp is non-NULL, and the provided @p olen * is too small to hold the encoded value. * @retval EFTYPE If value coercion from @p value to a single string * value via @p fmt is unsupported. * @retval ERANGE If value coercion of @p value would overflow (or * underflow) the representation defined by @p fmt. */ int bhnd_nvram_val_vprintf(bhnd_nvram_val *value, const char *fmt, char *outp, size_t *olen, va_list ap) { const void *elem; size_t elen; size_t limit, nbytes; int error; elem = NULL; /* Determine output byte limit */ nbytes = 0; if (outp != NULL) limit = *olen; else limit = 0; #define WRITE_CHAR(_c) do { \ if (limit > nbytes) \ *(outp + nbytes) = _c; \ \ if (nbytes == SIZE_MAX) \ return (EFTYPE); \ nbytes++; \ } while (0) /* Encode string value as per the format string */ for (const char *p = fmt; *p != '\0'; p++) { const char *delim; size_t precision, width, delim_len; u_long repeat, bits; bool alt_form, ladjust, have_precision; char padc, signc, lenc; padc = ' '; signc = '\0'; lenc = '\0'; delim = ""; delim_len = 0; ladjust = false; alt_form = false; have_precision = false; precision = 1; bits = 32; width = 0; repeat = 1; /* Copy all input to output until we hit a format specifier */ if (*p != '%') { WRITE_CHAR(*p); continue; } /* Hit '%' -- is this followed by an escaped '%' literal? */ p++; if (*p == '%') { WRITE_CHAR('%'); p++; continue; } /* Parse repeat specifier */ if (*p == '[') { p++; /* Determine repeat count */ if (*p == ']') { /* Repeat consumes all input */ repeat = bhnd_nvram_val_nelem(value); } else if (*p == '*') { /* Repeat is supplied as an argument */ repeat = va_arg(ap, size_t); p++; } else { char *endp; /* Repeat specified as argument */ repeat = strtoul(p, &endp, 10); if (p == endp) { BHND_NV_LOG("error parsing repeat " "count at '%s'", p); return (EINVAL); } /* Advance past repeat count */ p = endp; } /* Advance past terminating ']' */ if (*p != ']') { BHND_NV_LOG("error parsing repeat count at " "'%s'", p); return (EINVAL); } p++; delim = va_arg(ap, const char *); delim_len = strlen(delim); } /* Parse flags */ while (*p != '\0') { const char *np; bool stop; stop = false; np = p+1; switch (*p) { case '#': alt_form = true; break; case '0': padc = '0'; break; case '-': ladjust = true; break; case ' ': /* Must not override '+' */ if (signc != '+') signc = ' '; break; case '+': signc = '+'; break; default: /* Non-flag character */ stop = true; break; } if (stop) break; else p = np; } /* Parse minimum width */ if (*p == '*') { ssize_t arg; /* Width is supplied as an argument */ arg = va_arg(ap, int); /* Negative width argument is interpreted as * '-' flag followed by positive width */ if (arg < 0) { ladjust = true; arg = -arg; } width = arg; p++; } else if (bhnd_nv_isdigit(*p)) {