From 781d1cbebf2e5f179dc9277b9aae1a06a4ff9f79 Mon Sep 17 00:00:00 2001 From: Sahin Yort Date: Mon, 15 May 2023 12:15:55 -0700 Subject: [PATCH] feat: implement chr, ord, and hex (#425) --- docs/BUILD.bazel | 5 + docs/strings.md | 86 ++++ lib/BUILD.bazel | 6 + lib/private/base64.bzl | 550 +----------------------- lib/private/docs/BUILD.bazel | 9 + lib/private/strings.bzl | 586 ++++++++++++++++++++++++++ lib/private/{base64.py => strings.py} | 2 +- lib/strings.bzl | 9 + lib/tests/BUILD.bazel | 3 + lib/tests/base64_tests.bzl | 3 +- lib/tests/strings_tests.bzl | 65 +++ 11 files changed, 784 insertions(+), 540 deletions(-) create mode 100644 docs/strings.md create mode 100644 lib/private/strings.bzl rename lib/private/{base64.py => strings.py} (87%) create mode 100644 lib/strings.bzl create mode 100644 lib/tests/strings_tests.bzl diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index a943ed56a..a582123c6 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -133,4 +133,9 @@ stardoc_with_diff_test( bzl_library_target = "//lib:bazelrc_presets", ) +stardoc_with_diff_test( + name = "strings", + bzl_library_target = "//lib:strings", +) + update_docs() diff --git a/docs/strings.md b/docs/strings.md new file mode 100644 index 000000000..e16ae88d4 --- /dev/null +++ b/docs/strings.md @@ -0,0 +1,86 @@ + + +Utilities for strings + + + +## chr + +
+chr(i)
+
+ +returns a string encoding a codepoint + +chr returns a string that encodes the single Unicode code +point whose value is specified by the integer `i` + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| i | position of the character | none | + +**RETURNS** + +unicode string of the position + + + + +## hex + +
+hex(number)
+
+ +Format integer to hexdecimal representation + +Args: + number: number to format + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| number |

-

| none | + +**RETURNS** + +hexdecimal representation of the number argument + + + + +## ord + +
+ord(c)
+
+ +returns the codepoint of a character + +ord(c) returns the integer value of the sole Unicode code point +encoded by the string `c`. + +If `c` does not encode exactly one Unicode code point, `ord` fails. +Each invalid code within the string is treated as if it encodes the +Unicode replacement character, U+FFFD. + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| c | character whose codepoint to be returned. | none | + +**RETURNS** + +codepoint of `c` argument. + + diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel index 54194fa0f..0515bdd82 100644 --- a/lib/BUILD.bazel +++ b/lib/BUILD.bazel @@ -252,3 +252,9 @@ bzl_library( srcs = ["bazelrc_presets.bzl"], deps = [":write_source_files"], ) + +bzl_library( + name = "strings", + srcs = ["strings.bzl"], + deps = ["//lib/private/docs:strings"], +) \ No newline at end of file diff --git a/lib/private/base64.bzl b/lib/private/base64.bzl index 8059bf09c..59916d0f6 100644 --- a/lib/private/base64.bzl +++ b/lib/private/base64.bzl @@ -6,6 +6,8 @@ Implementation based on https://gist.github.com/trondhumbor/ce57c0c2816bb45a8fbb the subset of python available in Starlark. """ +load(":strings.bzl", "ord", "chr") + def decode(data): """Decode a Base64 encoded string. @@ -31,7 +33,7 @@ def decode(data): outstring = "" for chunk in eight_chunks: - outstring += _int_to_char(int(chunk, 2)) + outstring += chr(int(chunk, 2)) return outstring if padding == 0 else outstring[:-padding] @@ -56,7 +58,7 @@ def encode(data): binstring = "" for chunk in three_chunks: for i in range(len(chunk)): - binstring += _int_to_binary(_char_to_int(chunk[i])) + binstring += _int_to_binary(ord(chunk[i])) six_chunks = _chunk(binstring, 6) @@ -66,548 +68,13 @@ def encode(data): return outstring if padding == 0 else outstring[:-padding] + "=" * padding -def _char_to_int(c): - if len(c) != 1: - fail("expected a string with a single character") - return CHAR_TO_INT.get(c) - -def _int_to_binary(i, digits = 8): - if i < 0 or i > 255: - fail("expected a int between 0 and 255 (inclusive)") - if digits < 1 or digits > 8: - fail("expected digits to be between 1 and 8 (inclusive)") - return INT_TO_BINARY[i][8 - digits:] - -def _int_to_char(i): - if i < 0 or i > 255: - fail("expected a int between 0 and 255 (inclusive)") - return INT_TO_CHAR[i] - def _chunk(data, length): return [data[i:i + length] for i in range(0, len(data), length)] BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" # Starlark support octal values that we can leverage for this conversion. -# Generated by lib/private/base64.py utility script. -CHAR_TO_INT = { - "\0": 0, - "\1": 1, - "\2": 2, - "\3": 3, - "\4": 4, - "\5": 5, - "\6": 6, - "\7": 7, - "\10": 8, - "\11": 9, - "\12": 10, - "\13": 11, - "\14": 12, - "\15": 13, - "\16": 14, - "\17": 15, - "\20": 16, - "\21": 17, - "\22": 18, - "\23": 19, - "\24": 20, - "\25": 21, - "\26": 22, - "\27": 23, - "\30": 24, - "\31": 25, - "\32": 26, - "\33": 27, - "\34": 28, - "\35": 29, - "\36": 30, - "\37": 31, - "\40": 32, - "\41": 33, - "\42": 34, - "\43": 35, - "\44": 36, - "\45": 37, - "\46": 38, - "\47": 39, - "\50": 40, - "\51": 41, - "\52": 42, - "\53": 43, - "\54": 44, - "\55": 45, - "\56": 46, - "\57": 47, - "\60": 48, - "\61": 49, - "\62": 50, - "\63": 51, - "\64": 52, - "\65": 53, - "\66": 54, - "\67": 55, - "\70": 56, - "\71": 57, - "\72": 58, - "\73": 59, - "\74": 60, - "\75": 61, - "\76": 62, - "\77": 63, - "\100": 64, - "\101": 65, - "\102": 66, - "\103": 67, - "\104": 68, - "\105": 69, - "\106": 70, - "\107": 71, - "\110": 72, - "\111": 73, - "\112": 74, - "\113": 75, - "\114": 76, - "\115": 77, - "\116": 78, - "\117": 79, - "\120": 80, - "\121": 81, - "\122": 82, - "\123": 83, - "\124": 84, - "\125": 85, - "\126": 86, - "\127": 87, - "\130": 88, - "\131": 89, - "\132": 90, - "\133": 91, - "\134": 92, - "\135": 93, - "\136": 94, - "\137": 95, - "\140": 96, - "\141": 97, - "\142": 98, - "\143": 99, - "\144": 100, - "\145": 101, - "\146": 102, - "\147": 103, - "\150": 104, - "\151": 105, - "\152": 106, - "\153": 107, - "\154": 108, - "\155": 109, - "\156": 110, - "\157": 111, - "\160": 112, - "\161": 113, - "\162": 114, - "\163": 115, - "\164": 116, - "\165": 117, - "\166": 118, - "\167": 119, - "\170": 120, - "\171": 121, - "\172": 122, - "\173": 123, - "\174": 124, - "\175": 125, - "\176": 126, - "\177": 127, - "\200": 128, - "\201": 129, - "\202": 130, - "\203": 131, - "\204": 132, - "\205": 133, - "\206": 134, - "\207": 135, - "\210": 136, - "\211": 137, - "\212": 138, - "\213": 139, - "\214": 140, - "\215": 141, - "\216": 142, - "\217": 143, - "\220": 144, - "\221": 145, - "\222": 146, - "\223": 147, - "\224": 148, - "\225": 149, - "\226": 150, - "\227": 151, - "\230": 152, - "\231": 153, - "\232": 154, - "\233": 155, - "\234": 156, - "\235": 157, - "\236": 158, - "\237": 159, - "\240": 160, - "\241": 161, - "\242": 162, - "\243": 163, - "\244": 164, - "\245": 165, - "\246": 166, - "\247": 167, - "\250": 168, - "\251": 169, - "\252": 170, - "\253": 171, - "\254": 172, - "\255": 173, - "\256": 174, - "\257": 175, - "\260": 176, - "\261": 177, - "\262": 178, - "\263": 179, - "\264": 180, - "\265": 181, - "\266": 182, - "\267": 183, - "\270": 184, - "\271": 185, - "\272": 186, - "\273": 187, - "\274": 188, - "\275": 189, - "\276": 190, - "\277": 191, - "\300": 192, - "\301": 193, - "\302": 194, - "\303": 195, - "\304": 196, - "\305": 197, - "\306": 198, - "\307": 199, - "\310": 200, - "\311": 201, - "\312": 202, - "\313": 203, - "\314": 204, - "\315": 205, - "\316": 206, - "\317": 207, - "\320": 208, - "\321": 209, - "\322": 210, - "\323": 211, - "\324": 212, - "\325": 213, - "\326": 214, - "\327": 215, - "\330": 216, - "\331": 217, - "\332": 218, - "\333": 219, - "\334": 220, - "\335": 221, - "\336": 222, - "\337": 223, - "\340": 224, - "\341": 225, - "\342": 226, - "\343": 227, - "\344": 228, - "\345": 229, - "\346": 230, - "\347": 231, - "\350": 232, - "\351": 233, - "\352": 234, - "\353": 235, - "\354": 236, - "\355": 237, - "\356": 238, - "\357": 239, - "\360": 240, - "\361": 241, - "\362": 242, - "\363": 243, - "\364": 244, - "\365": 245, - "\366": 246, - "\367": 247, - "\370": 248, - "\371": 249, - "\372": 250, - "\373": 251, - "\374": 252, - "\375": 253, - "\376": 254, - "\377": 255, -} - -INT_TO_CHAR = [ - "\0", - "\1", - "\2", - "\3", - "\4", - "\5", - "\6", - "\7", - "\10", - "\11", - "\12", - "\13", - "\14", - "\15", - "\16", - "\17", - "\20", - "\21", - "\22", - "\23", - "\24", - "\25", - "\26", - "\27", - "\30", - "\31", - "\32", - "\33", - "\34", - "\35", - "\36", - "\37", - "\40", - "\41", - "\42", - "\43", - "\44", - "\45", - "\46", - "\47", - "\50", - "\51", - "\52", - "\53", - "\54", - "\55", - "\56", - "\57", - "\60", - "\61", - "\62", - "\63", - "\64", - "\65", - "\66", - "\67", - "\70", - "\71", - "\72", - "\73", - "\74", - "\75", - "\76", - "\77", - "\100", - "\101", - "\102", - "\103", - "\104", - "\105", - "\106", - "\107", - "\110", - "\111", - "\112", - "\113", - "\114", - "\115", - "\116", - "\117", - "\120", - "\121", - "\122", - "\123", - "\124", - "\125", - "\126", - "\127", - "\130", - "\131", - "\132", - "\133", - "\134", - "\135", - "\136", - "\137", - "\140", - "\141", - "\142", - "\143", - "\144", - "\145", - "\146", - "\147", - "\150", - "\151", - "\152", - "\153", - "\154", - "\155", - "\156", - "\157", - "\160", - "\161", - "\162", - "\163", - "\164", - "\165", - "\166", - "\167", - "\170", - "\171", - "\172", - "\173", - "\174", - "\175", - "\176", - "\177", - "\200", - "\201", - "\202", - "\203", - "\204", - "\205", - "\206", - "\207", - "\210", - "\211", - "\212", - "\213", - "\214", - "\215", - "\216", - "\217", - "\220", - "\221", - "\222", - "\223", - "\224", - "\225", - "\226", - "\227", - "\230", - "\231", - "\232", - "\233", - "\234", - "\235", - "\236", - "\237", - "\240", - "\241", - "\242", - "\243", - "\244", - "\245", - "\246", - "\247", - "\250", - "\251", - "\252", - "\253", - "\254", - "\255", - "\256", - "\257", - "\260", - "\261", - "\262", - "\263", - "\264", - "\265", - "\266", - "\267", - "\270", - "\271", - "\272", - "\273", - "\274", - "\275", - "\276", - "\277", - "\300", - "\301", - "\302", - "\303", - "\304", - "\305", - "\306", - "\307", - "\310", - "\311", - "\312", - "\313", - "\314", - "\315", - "\316", - "\317", - "\320", - "\321", - "\322", - "\323", - "\324", - "\325", - "\326", - "\327", - "\330", - "\331", - "\332", - "\333", - "\334", - "\335", - "\336", - "\337", - "\340", - "\341", - "\342", - "\343", - "\344", - "\345", - "\346", - "\347", - "\350", - "\351", - "\352", - "\353", - "\354", - "\355", - "\356", - "\357", - "\360", - "\361", - "\362", - "\363", - "\364", - "\365", - "\366", - "\367", - "\370", - "\371", - "\372", - "\373", - "\374", - "\375", - "\376", - "\377", -] - +# Generated by lib/private/string.py utility script. INT_TO_BINARY = [ "00000000", "00000001", @@ -866,3 +333,10 @@ INT_TO_BINARY = [ "11111110", "11111111", ] + +def _int_to_binary(i, digits = 8): + if i < 0 or i > 255: + fail("expected a int between 0 and 255 (inclusive)") + if digits < 1 or digits > 8: + fail("expected digits to be between 1 and 8 (inclusive)") + return INT_TO_BINARY[i][8 - digits:] \ No newline at end of file diff --git a/lib/private/docs/BUILD.bazel b/lib/private/docs/BUILD.bazel index 0e07499c8..f0b014721 100644 --- a/lib/private/docs/BUILD.bazel +++ b/lib/private/docs/BUILD.bazel @@ -227,6 +227,9 @@ bzl_library( bzl_library( name = "base64", srcs = ["//lib/private:base64.bzl"], + deps = [ + ":strings" + ] ) bzl_library( @@ -243,3 +246,9 @@ bzl_library( name = "coreutils_toolchain", srcs = ["//lib/private:coreutils_toolchain.bzl"], ) + + +bzl_library( + name = "strings", + srcs = ["//lib/private:strings.bzl"], +) diff --git a/lib/private/strings.bzl b/lib/private/strings.bzl new file mode 100644 index 000000000..dd67a8b4c --- /dev/null +++ b/lib/private/strings.bzl @@ -0,0 +1,586 @@ +"String utilities" + +CHAR_TO_INT = { + "\0": 0, + "\1": 1, + "\2": 2, + "\3": 3, + "\4": 4, + "\5": 5, + "\6": 6, + "\7": 7, + "\10": 8, + "\11": 9, + "\12": 10, + "\13": 11, + "\14": 12, + "\15": 13, + "\16": 14, + "\17": 15, + "\20": 16, + "\21": 17, + "\22": 18, + "\23": 19, + "\24": 20, + "\25": 21, + "\26": 22, + "\27": 23, + "\30": 24, + "\31": 25, + "\32": 26, + "\33": 27, + "\34": 28, + "\35": 29, + "\36": 30, + "\37": 31, + "\40": 32, + "\41": 33, + "\42": 34, + "\43": 35, + "\44": 36, + "\45": 37, + "\46": 38, + "\47": 39, + "\50": 40, + "\51": 41, + "\52": 42, + "\53": 43, + "\54": 44, + "\55": 45, + "\56": 46, + "\57": 47, + "\60": 48, + "\61": 49, + "\62": 50, + "\63": 51, + "\64": 52, + "\65": 53, + "\66": 54, + "\67": 55, + "\70": 56, + "\71": 57, + "\72": 58, + "\73": 59, + "\74": 60, + "\75": 61, + "\76": 62, + "\77": 63, + "\100": 64, + "\101": 65, + "\102": 66, + "\103": 67, + "\104": 68, + "\105": 69, + "\106": 70, + "\107": 71, + "\110": 72, + "\111": 73, + "\112": 74, + "\113": 75, + "\114": 76, + "\115": 77, + "\116": 78, + "\117": 79, + "\120": 80, + "\121": 81, + "\122": 82, + "\123": 83, + "\124": 84, + "\125": 85, + "\126": 86, + "\127": 87, + "\130": 88, + "\131": 89, + "\132": 90, + "\133": 91, + "\134": 92, + "\135": 93, + "\136": 94, + "\137": 95, + "\140": 96, + "\141": 97, + "\142": 98, + "\143": 99, + "\144": 100, + "\145": 101, + "\146": 102, + "\147": 103, + "\150": 104, + "\151": 105, + "\152": 106, + "\153": 107, + "\154": 108, + "\155": 109, + "\156": 110, + "\157": 111, + "\160": 112, + "\161": 113, + "\162": 114, + "\163": 115, + "\164": 116, + "\165": 117, + "\166": 118, + "\167": 119, + "\170": 120, + "\171": 121, + "\172": 122, + "\173": 123, + "\174": 124, + "\175": 125, + "\176": 126, + "\177": 127, + "\200": 128, + "\201": 129, + "\202": 130, + "\203": 131, + "\204": 132, + "\205": 133, + "\206": 134, + "\207": 135, + "\210": 136, + "\211": 137, + "\212": 138, + "\213": 139, + "\214": 140, + "\215": 141, + "\216": 142, + "\217": 143, + "\220": 144, + "\221": 145, + "\222": 146, + "\223": 147, + "\224": 148, + "\225": 149, + "\226": 150, + "\227": 151, + "\230": 152, + "\231": 153, + "\232": 154, + "\233": 155, + "\234": 156, + "\235": 157, + "\236": 158, + "\237": 159, + "\240": 160, + "\241": 161, + "\242": 162, + "\243": 163, + "\244": 164, + "\245": 165, + "\246": 166, + "\247": 167, + "\250": 168, + "\251": 169, + "\252": 170, + "\253": 171, + "\254": 172, + "\255": 173, + "\256": 174, + "\257": 175, + "\260": 176, + "\261": 177, + "\262": 178, + "\263": 179, + "\264": 180, + "\265": 181, + "\266": 182, + "\267": 183, + "\270": 184, + "\271": 185, + "\272": 186, + "\273": 187, + "\274": 188, + "\275": 189, + "\276": 190, + "\277": 191, + "\300": 192, + "\301": 193, + "\302": 194, + "\303": 195, + "\304": 196, + "\305": 197, + "\306": 198, + "\307": 199, + "\310": 200, + "\311": 201, + "\312": 202, + "\313": 203, + "\314": 204, + "\315": 205, + "\316": 206, + "\317": 207, + "\320": 208, + "\321": 209, + "\322": 210, + "\323": 211, + "\324": 212, + "\325": 213, + "\326": 214, + "\327": 215, + "\330": 216, + "\331": 217, + "\332": 218, + "\333": 219, + "\334": 220, + "\335": 221, + "\336": 222, + "\337": 223, + "\340": 224, + "\341": 225, + "\342": 226, + "\343": 227, + "\344": 228, + "\345": 229, + "\346": 230, + "\347": 231, + "\350": 232, + "\351": 233, + "\352": 234, + "\353": 235, + "\354": 236, + "\355": 237, + "\356": 238, + "\357": 239, + "\360": 240, + "\361": 241, + "\362": 242, + "\363": 243, + "\364": 244, + "\365": 245, + "\366": 246, + "\367": 247, + "\370": 248, + "\371": 249, + "\372": 250, + "\373": 251, + "\374": 252, + "\375": 253, + "\376": 254, + "\377": 255, +} + +INT_TO_CHAR = [ + "\0", + "\1", + "\2", + "\3", + "\4", + "\5", + "\6", + "\7", + "\10", + "\11", + "\12", + "\13", + "\14", + "\15", + "\16", + "\17", + "\20", + "\21", + "\22", + "\23", + "\24", + "\25", + "\26", + "\27", + "\30", + "\31", + "\32", + "\33", + "\34", + "\35", + "\36", + "\37", + "\40", + "\41", + "\42", + "\43", + "\44", + "\45", + "\46", + "\47", + "\50", + "\51", + "\52", + "\53", + "\54", + "\55", + "\56", + "\57", + "\60", + "\61", + "\62", + "\63", + "\64", + "\65", + "\66", + "\67", + "\70", + "\71", + "\72", + "\73", + "\74", + "\75", + "\76", + "\77", + "\100", + "\101", + "\102", + "\103", + "\104", + "\105", + "\106", + "\107", + "\110", + "\111", + "\112", + "\113", + "\114", + "\115", + "\116", + "\117", + "\120", + "\121", + "\122", + "\123", + "\124", + "\125", + "\126", + "\127", + "\130", + "\131", + "\132", + "\133", + "\134", + "\135", + "\136", + "\137", + "\140", + "\141", + "\142", + "\143", + "\144", + "\145", + "\146", + "\147", + "\150", + "\151", + "\152", + "\153", + "\154", + "\155", + "\156", + "\157", + "\160", + "\161", + "\162", + "\163", + "\164", + "\165", + "\166", + "\167", + "\170", + "\171", + "\172", + "\173", + "\174", + "\175", + "\176", + "\177", + "\200", + "\201", + "\202", + "\203", + "\204", + "\205", + "\206", + "\207", + "\210", + "\211", + "\212", + "\213", + "\214", + "\215", + "\216", + "\217", + "\220", + "\221", + "\222", + "\223", + "\224", + "\225", + "\226", + "\227", + "\230", + "\231", + "\232", + "\233", + "\234", + "\235", + "\236", + "\237", + "\240", + "\241", + "\242", + "\243", + "\244", + "\245", + "\246", + "\247", + "\250", + "\251", + "\252", + "\253", + "\254", + "\255", + "\256", + "\257", + "\260", + "\261", + "\262", + "\263", + "\264", + "\265", + "\266", + "\267", + "\270", + "\271", + "\272", + "\273", + "\274", + "\275", + "\276", + "\277", + "\300", + "\301", + "\302", + "\303", + "\304", + "\305", + "\306", + "\307", + "\310", + "\311", + "\312", + "\313", + "\314", + "\315", + "\316", + "\317", + "\320", + "\321", + "\322", + "\323", + "\324", + "\325", + "\326", + "\327", + "\330", + "\331", + "\332", + "\333", + "\334", + "\335", + "\336", + "\337", + "\340", + "\341", + "\342", + "\343", + "\344", + "\345", + "\346", + "\347", + "\350", + "\351", + "\352", + "\353", + "\354", + "\355", + "\356", + "\357", + "\360", + "\361", + "\362", + "\363", + "\364", + "\365", + "\366", + "\367", + "\370", + "\371", + "\372", + "\373", + "\374", + "\375", + "\376", + "\377", +] + +def ord(c): + """returns the codepoint of a character + + ord(c) returns the integer value of the sole Unicode code point + encoded by the string `c`. + + If `c` does not encode exactly one Unicode code point, `ord` fails. + Each invalid code within the string is treated as if it encodes the + Unicode replacement character, U+FFFD. + + Args: + c: character whose codepoint to be returned. + + Returns: + codepoint of `c` argument. + """ + if len(c) != 1: + fail("expected a string with a single character") + return CHAR_TO_INT.get(c) + +def chr(i): + """returns a string encoding a codepoint + + chr returns a string that encodes the single Unicode code + point whose value is specified by the integer `i` + + Args: + i: position of the character + + Returns: + unicode string of the position + """ + if i < 0 or i > 255: + fail("expected a int between 0 and 255 (inclusive)") + return INT_TO_CHAR[i] + +def _to_char(n): + alpha = "0123456789abcdef" + return alpha[n] + +def hex(number): + """Format integer to hexdecimal representation + + Args: + number: number to format + + Returns: + hexdecimal representation of the number argument + """ + + hex_string = "" + is_signed = number < 0 + r = number * -1 if is_signed else number + for _ in range(1000000): + if r > 0: + rem = r % 16 + hex_string = _to_char(rem) + hex_string + r //= 16 + else: + break + + if not hex_string: + hex_string = "0" + + return "{}0x{}".format("-" if is_signed else "", hex_string) + diff --git a/lib/private/base64.py b/lib/private/strings.py similarity index 87% rename from lib/private/base64.py rename to lib/private/strings.py index ec751d2f4..4ee2812ab 100644 --- a/lib/private/base64.py +++ b/lib/private/strings.py @@ -1,4 +1,4 @@ -# python utility to seed the starlark constants in base64.bzl +# python utility to seed the starlark constants in strings.bzl print("") print("CHAR_TO_INT = {") diff --git a/lib/strings.bzl b/lib/strings.bzl new file mode 100644 index 000000000..804a72292 --- /dev/null +++ b/lib/strings.bzl @@ -0,0 +1,9 @@ + + +"Utilities for strings" + +load("//lib/private:strings.bzl", _chr = "chr", _ord = "ord", _hex = "hex") + +chr = _chr +ord = _ord +hex = _hex diff --git a/lib/tests/BUILD.bazel b/lib/tests/BUILD.bazel index 9e75035bb..192c85356 100644 --- a/lib/tests/BUILD.bazel +++ b/lib/tests/BUILD.bazel @@ -9,6 +9,7 @@ load(":utils_test.bzl", "utils_test_suite") load(":paths_test.bzl", "paths_test_suite") load(":glob_match_test.bzl", "glob_match_test_suite") load(":base64_tests.bzl", "base64_test_suite") +load(":strings_tests.bzl", "strings_test_suite") config_setting( name = "experimental_allow_unresolved_symlinks", @@ -26,6 +27,8 @@ glob_match_test_suite() base64_test_suite() +strings_test_suite() + write_file( name = "gen_template", out = "template.txt", diff --git a/lib/tests/base64_tests.bzl b/lib/tests/base64_tests.bzl index 0d8397405..dc827bed8 100644 --- a/lib/tests/base64_tests.bzl +++ b/lib/tests/base64_tests.bzl @@ -1,7 +1,8 @@ """unit tests for base64""" load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") -load("//lib/private:base64.bzl", "INT_TO_CHAR", "decode", "encode") +load("//lib/private:base64.bzl", "decode", "encode") +load("//lib/private:strings.bzl", "INT_TO_CHAR") def _base64_test_impl(ctx): env = unittest.begin(ctx) diff --git a/lib/tests/strings_tests.bzl b/lib/tests/strings_tests.bzl new file mode 100644 index 000000000..ad5e30cda --- /dev/null +++ b/lib/tests/strings_tests.bzl @@ -0,0 +1,65 @@ +"""unit tests for string""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//lib/private:strings.bzl", "ord", "chr", "hex") + +def _ord_test_impl(ctx): + env = unittest.begin(ctx) + + asserts.equals(env, ord("a"), 97) + asserts.equals(env, ord("b"), 98) + asserts.equals(env, ord("/"), 47) + asserts.equals(env, ord("c"), 99) + asserts.equals(env, ord("x"), 120) + asserts.equals(env, ord("@"), 64) + asserts.equals(env, ord("%"), 37) + asserts.equals(env, ord("$"), 36) + asserts.equals(env, ord("+"), 43) + + return unittest.end(env) + +ord_test = unittest.make(_ord_test_impl) + + +def _chr_test_impl(ctx): + env = unittest.begin(ctx) + + asserts.equals(env, chr(97), "a") + asserts.equals(env, chr(98), "b") + asserts.equals(env, chr(47), "/") + asserts.equals(env, chr(99), "c") + asserts.equals(env, chr(120), "x") + asserts.equals(env, chr(64), "@") + asserts.equals(env, chr(37), "%") + asserts.equals(env, chr(36), "$") + asserts.equals(env, chr(43), "+") + + return unittest.end(env) + +chr_test = unittest.make(_chr_test_impl) + + +def _hex_test_impl(ctx): + env = unittest.begin(ctx) + + asserts.equals(env, hex(1111), "0x457") + asserts.equals(env, hex(97), "0x61") + asserts.equals(env, hex(1000000000000), "0xe8d4a51000") + asserts.equals(env, hex(1), "0x1") + # https://en.wikipedia.org/wiki/Signed_zero + asserts.equals(env, hex(0), "0x0") + asserts.equals(env, hex(-0), "0x0") + asserts.equals(env, hex(-1234), "-0x4d2") + asserts.equals(env, hex(-99999999), "-0x5f5e0ff") + + return unittest.end(env) + +hex_test = unittest.make(_hex_test_impl) + +def strings_test_suite(): + unittest.suite( + "strings_tests", + ord_test, + chr_test, + hex_test + )