Program operation checklist

  1. Does the program display translatable messages to the user, either directly or indirectly? An example of indirect messages are those that are stored in libraries.

    If yes:

    • Are these messages externalized from the program by way of the message facility subroutines?
    • Have you provided message source files for all such messages?
    • What is the locale under which the program runs?
      • If it runs in the locale determined by the locale environment variables, did you invoke the setlocale subroutine in the following manner?
        setlocale(LC_ALL, "")
        Note: The locale categories, in their predefined hierarchical order, are: LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, and LC_TIME.
      • If the program runs in the "C" locale, except for displaying messages in the locale specified by the locale environment variables, did you invoke the setlocale subroutine in the following manner?
        setlocale(LC_MESSAGES, "")
      • After invoking the setlocale subroutine, did you invoke the catopen subroutine in the following manner?
        catopen(catalog_name, NL_CAT_LOCALE)
      • Did you invoke the catopen subroutine with the proper catalog name?
      • See the Message facility for more information about translatable messages.
  2. Does the program compare text strings?

    If yes:

    • Are the strings compared to check equality only?

      If yes:

      • Use the strcmp or strncmp subroutine.
      • Do not use the strcoll or strxfrm subroutine.
    • Are the strings compared to see which one sorts before the other, as defined in the current locale?

      If yes:

      • Invoke the setlocale subroutine in the following manner:
        setlocale(LC_ALL, "")
      • Use the strcoll, strxfrm, wcscoll, or wcsxfrm subroutine.
      • Do not use the strxfrm or strncmp subroutine.
  3. Does the program parse path names of files?

    If yes:

    • If looking for / (slash), use the strchr subroutine.
    • If looking for characters, be aware that the file names can include multibyte characters. In such cases, invoke the setlocale subroutine in the following manner and then use appropriate search subroutines:
      setlocale(LC_ALL, "")
  4. Does the program use system names, such as node names, user names, printer names, and queue names?

    If yes:

    • System names can have multibyte characters.
    • To identify a multibyte character, first invoke the setlocale subroutine in the following manner and then use appropriate subroutines in the library.
      setlocale(LC_ALL, "")
  5. Does the program use character class properties, such as uppercase, lowercase, and alphabetic?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Do not make assumptions about character properties. Always use system subroutines to determine character properties.
    • Are the characters restricted to single-byte code sets?

      If yes:

      • Use one of the ctype subroutines: isalnum, isalpha, iscntrl, isdigit, isgraph, isprint, isspace, or isxdigit.

        If not, the characters may be multibyte characters:

      • Use the iswalnum, iswalpha, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct, iswspace, iswupper, or iswxdigit subroutine.
  6. Does the program convert the case (upper or lower) of characters?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Are the characters restricted to single-byte code sets?

      If yes:

      • Use these conv subroutines: _tolower, _toupper, tolower, or toupper.
      If not, the characters may be multibyte characters:
      • Use the towlower or towupper subroutine.
  7. Does the program keep track of cursor movement on a tty terminal?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • You may need to determine the display column width of characters. Use the wcwidth or wcswidth subroutine.
  8. Does the program perform character I/O?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Are the characters restricted to single-byte code sets?

      If yes:

      • Use following subroutine families:
        • fgetc, getc, getchar, getw
        • fgets, gets
        • fputc, putc, putchar, putw
        • printf, scanf
      If not:
      • Use following subroutine families:
        • fgetwc, getwc, getwchar
        • fgetws, getws
        • fputwc, putwc, putwchar
  9. Does the program step through an array of characters?

    If yes:

    • Is the array limited to single-byte characters only?

      If yes:

      • Does not require setlocale(LC_ALL, "")
      • If p is the pointer to this array of single-byte characters, step through this array using p++.
    If not:
    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Use the mblen or wcslen subroutine.
  10. Does the program need to know the maximum number of bytes used to encode a character within the code set?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Use the MB_CUR_MAX macro.
  11. Does the program format date or time numeric quantities?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Use the nl_langinfo or localeconv subroutine to obtain the locale-specific information.
    • Use the strftime or strptime subroutine.
  12. Does the program format numeric quantities?

    If yes:

    • Invoke the
      setlocale
      subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Use the nl_langinfo or localeconv subroutine to obtain the locale-specific information.
    • Use the following pair of subroutines, as needed: printf, scanf.
  13. Does the program format monetary quantities?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Use the nl_langinfo or localeconv subroutine to obtain the locale-specific information.
    • Use the strfmon subroutine to format monetary quantities.
  14. Does the program search for strings or locate characters?

    If yes:

    • Are you looking for single-byte characters in single-byte text?
      • Does not require setlocale(LC_ALL, "")
      • Use standard libc string subroutines such as the strchr subroutine.
    • Are you looking for characters in the range 0x00-0x3F (the unique code-point range)?
    • Does not require setlocale(LC_ALL, "")
    • Use standard libc string subroutines such as the strchr, strcspn, strpbrk, strrchr, strspn, strstr, strtok, and memchr subroutines.
    • Are you looking for characters in the range 0x00-0xFF?
    • Invoke the setlocale subroutine in the following manner:
      setlocale(LC_ALL, "")
    • Two methods are available:

      Use the mblen subroutine to skip multibyte characters. Then, on encountering single-byte characters, check for equality. See checklist item 2.

      OR

      Convert the search character and the searched string to wide character form, and then use wide character search subroutines.

  15. Does the program perform regular-expression pattern matching?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
       setlocale(LC_ALL, "")
    • Use the regcomp, regexec, or regerror subroutine.
  16. Does the program ask the user for affirmative/negative responses?

    If yes:

    • Invoke the setlocale subroutine in the following manner:
       setlocale(LC_ALL, "")
    • Put the prompt in the message catalog. Use the catopen and catgets subroutines to retrieve the catalog and display the prompt.
    • Use the rpmatch subroutine to match the user's response.
  17. Does the program use special box-drawing characters?

    If yes:

    • Do not use code set-specific box-drawing characters.
    • Instead use the box-drawing characters and attributes specified in the terminfo file.
  18. Does the program perform culture-specific or locale-specific processing that is not addressed here?

    If yes:

    • Externalize the culture-specific modules. Do not make them part of the executable program.
    • Load the modules at run time using subroutines provided by the system, such as the load subroutine.
    • If the system does not provide such facilities, link them statically but provide them in a modular fashion.