Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 39f84ce4 in mainline


Ignore:
Timestamp:
2018-06-13T17:11:44Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
f4aa1c8
Parents:
5a6c28d1
git-author:
Jiri Svoboda <jiri@…> (2018-06-12 18:11:08)
git-committer:
Jiri Svoboda <jiri@…> (2018-06-13 17:11:44)
Message:

Add range support to scanf's set conversion.

Location:
uspace/lib/c
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/stdio/scanf.c

    r5a6c28d1 r39f84ce4  
    886886/** Determine if character is in scanset.
    887887 *
     888 * Note that we support ranges, although that is a GNU extension.
     889 *
    888890 * @param c Character
    889891 * @param scanset Pointer to scanset
     
    894896        const char *p = scanset;
    895897        bool inverted = false;
     898        char startc;
     899        char endc;
    896900
    897901        /* Inverted scanset */
     
    901905        }
    902906
    903         /* ']' character in scanset */
     907        /*
     908         * Either ']' or '-' at beginning or after '^' loses special meaning.
     909         * However, '-' after ']' (or vice versa) does not.
     910         */
    904911        if (*p == ']') {
     912                /* ']' character in scanset */
    905913                if (c == ']')
    906914                        return !inverted;
    907915                ++p;
     916        } else if (*p == '-') {
     917                /* '-' character in scanset */
     918                if (c == '-')
     919                        return !inverted;
     920                ++p;
    908921        }
    909922
    910923        /* Remaining characters */
    911924        while (*p != '\0' && *p != ']') {
     925                /* '-' is a range unless it's the last character in scanset */
     926                if (*p == '-' && p[1] != ']' && p[1] != '\0') {
     927                        startc = p[-1];
     928                        endc = p[1];
     929
     930                        if (c >= startc && c <= endc)
     931                                return !inverted;
     932
     933                        p += 2;
     934                        continue;
     935                }
     936
    912937                if (*p == c)
    913938                        return !inverted;
  • uspace/lib/c/test/stdio/scanf.c

    r5a6c28d1 r39f84ce4  
    781781}
    782782
    783 PCUT_TEST(set_negated)
     783PCUT_TEST(set_inverted)
    784784{
    785785        int rc;
     
    825825        PCUT_ASSERT_TRUE(chars[1] == 'b');
    826826        PCUT_ASSERT_TRUE(chars[2] == 'c');
     827        PCUT_ASSERT_TRUE(chars[3] == '\0');
     828        PCUT_ASSERT_TRUE(chars[4] == 'X');
     829}
     830
     831PCUT_TEST(set_with_leading_dash)
     832{
     833        int rc;
     834        char chars[chars_size];
     835
     836        /* Set conversion with leading '-' in scanset */
     837        memset(chars, 'X', chars_size);
     838        rc = sscanf("a-bc[", "%[-abc]", chars);
     839        PCUT_ASSERT_INT_EQUALS(1, rc);
     840        PCUT_ASSERT_TRUE(chars[0] == 'a');
     841        PCUT_ASSERT_TRUE(chars[1] == '-');
     842        PCUT_ASSERT_TRUE(chars[2] == 'b');
     843        PCUT_ASSERT_TRUE(chars[3] == 'c');
     844        PCUT_ASSERT_TRUE(chars[4] == '\0');
     845        PCUT_ASSERT_TRUE(chars[5] == 'X');
     846}
     847
     848PCUT_TEST(set_with_trailing_dash)
     849{
     850        int rc;
     851        char chars[chars_size];
     852
     853        /* Set conversion with trailing '-' in scanset */
     854        memset(chars, 'X', chars_size);
     855        rc = sscanf("a-bc]", "%[abc-]", chars);
     856        PCUT_ASSERT_INT_EQUALS(1, rc);
     857        PCUT_ASSERT_TRUE(chars[0] == 'a');
     858        PCUT_ASSERT_TRUE(chars[1] == '-');
     859        PCUT_ASSERT_TRUE(chars[2] == 'b');
     860        PCUT_ASSERT_TRUE(chars[3] == 'c');
     861        PCUT_ASSERT_TRUE(chars[4] == '\0');
     862        PCUT_ASSERT_TRUE(chars[5] == 'X');
     863}
     864
     865PCUT_TEST(set_inverted_with_leading_dash)
     866{
     867        int rc;
     868        char chars[chars_size];
     869
     870        /* Set conversion with leading '-' in inverted scanset */
     871        memset(chars, 'X', chars_size);
     872        rc = sscanf("def-", "%[^-abc]", chars);
     873        PCUT_ASSERT_INT_EQUALS(1, rc);
     874        PCUT_ASSERT_TRUE(chars[0] == 'd');
     875        PCUT_ASSERT_TRUE(chars[1] == 'e');
     876        PCUT_ASSERT_TRUE(chars[2] == 'f');
     877        PCUT_ASSERT_TRUE(chars[3] == '\0');
     878        PCUT_ASSERT_TRUE(chars[4] == 'X');
     879}
     880
     881PCUT_TEST(set_inverted_with_only_dash)
     882{
     883        int rc;
     884        char chars[chars_size];
     885
     886        /*
     887         * ']' after '^' in scanset does not lose meaning of scanset
     888         * delimiter
     889         */
     890        memset(chars, 'X', chars_size);
     891        rc = sscanf("abc-", "%[^-]", chars);
     892        PCUT_ASSERT_INT_EQUALS(1, rc);
     893        PCUT_ASSERT_TRUE(chars[0] == 'a');
     894        PCUT_ASSERT_TRUE(chars[1] == 'b');
     895        PCUT_ASSERT_TRUE(chars[2] == 'c');
     896        PCUT_ASSERT_TRUE(chars[3] == '\0');
     897        PCUT_ASSERT_TRUE(chars[4] == 'X');
     898}
     899
     900PCUT_TEST(set_inverted_with_dash_caret)
     901{
     902        int rc;
     903        char chars[chars_size];
     904
     905        /* '^' after '-' in scanset does not have special meaning */
     906        memset(chars, 'X', chars_size);
     907        rc = sscanf("-^a", "%[-^a]", chars);
     908        PCUT_ASSERT_INT_EQUALS(1, rc);
     909        PCUT_ASSERT_TRUE(chars[0] == '-');
     910        PCUT_ASSERT_TRUE(chars[1] == '^');
     911        PCUT_ASSERT_TRUE(chars[2] == 'a');
    827912        PCUT_ASSERT_TRUE(chars[3] == '\0');
    828913        PCUT_ASSERT_TRUE(chars[4] == 'X');
Note: See TracChangeset for help on using the changeset viewer.