microPython的源码解析之 objstrunicode.c

MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.


microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit


代码是一个C语言编写的微Python(MicroPython)字符串处理模块的一部分。它包含了字符串的打印、一元操作、索引和迭代等功能。代码中的注释已经翻译成中文,并补充了一些解释性的注释,以便更好地理解代码的功能和实现方式。

#include <string.h>
#include <assert.h>

#include "py/objstr.h"
#include "py/objlist.h"
#include "py/runtime.h"

#if MICROPY_PY_BUILTINS_STR_UNICODE

// 创建字符串迭代器对象
static mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf);

/******************************************************************************/
/* 字符串处理函数                                                      */

// 打印带引号的字符串,用于输出JSON格式的字符串
static void uni_print_quoted(const mp_print_t *print, const byte *str_data, uint str_len) {
   
    // 检查字符串中是否包含单引号和双引号,以便决定使用哪种引号包围字符串
    bool has_single_quote = false;
    bool has_double_quote = false;
    for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
   
        if (*s == '\'') {
   
            has_single_quote = true;
        } else if (*s == '"') {
   
            has_double_quote = true;
        }
    }
    // 选择引号类型
    unichar quote_char = '\'';
    if (has_single_quote && !has_double_quote) {
   
        quote_char = '"';
    }
    mp_printf(print, "%c", quote_char); // 打印引号
    const byte *s = str_data, *top = str_data + str_len;
    while (s < top) {
   
        unichar ch;
        ch = utf8_get_char(s);
        s = utf8_next_char(s);
        // 根据字符类型进行转义打印
        if (ch == quote_char) {
   
            mp_printf(print, "\\%c", quote_char);
        } else if (ch == '\\') {
   
            mp_print_str(print, "\\\\");
        } else if (32 <= ch && ch <= 126) {
   
            mp_printf(print, "%c", ch);
        } else if (ch == '\n') {
   
            mp_print_str(print, "\\n");
        } else if (ch == '\r') {
   
            mp_print_str(print, "\\r");
        } else if (ch == '\t') {
   
            mp_print_str(print, "\\t");
        } else if (ch < 0x100) {
   
            mp_printf(print, "\\x%02x", ch);
        } else if (ch < 0x10000) {
   
            mp_printf(print, "\\u%04x", ch);
        } else {
   
            mp_printf(print, "\\U%08x", ch);
        }
    }
    mp_printf(print, "%c", quote_char); // 打印结束引号
}

// 打印字符串,根据不同的打印类型进行处理
static void uni_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
   
    GET_STR_DATA_LEN(self_in, str_data, str_len);
    #if MICROPY_PY_JSON
    if (kind == PRINT_JSON) {
   
        mp_str_print_json(print, str_data, str_len);
        return;
    }
    #endif
    if (kind == PRINT_STR) {
   
        print->print_strn(print->data, (const char *)str_data, str_len);
    } else {
   
        uni_print_quoted(print, str_data, str_len);
    }
}

// 一元操作函数,处理如布尔值、长度等操作
static mp_obj_t uni_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
   
    GET_STR_DATA_LEN(self_in, str_data, str_len);
    switch (op) {
   
        case MP_UNARY_OP_BOOL:
            return mp_obj_new_bool(str_len != 0);
        case MP_UNARY_OP_LEN:
            return MP_OBJ_NEW_SMALL_INT(utf8_charlen(str_data, str_len));
        default:
            return MP_OBJ_NULL; // 操作不支持
    }
}

// 将索引值转换为指向其首字节的指针
const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len,
    mp_obj_t index, bool is_slice) {
   
    // 处理字节对象
    if (type == &mp_type_bytes
        #if MICROPY_PY_BUILTINS_BYTEARRAY
        || type == &mp_type_bytearray
        #endif
        ) {
   
        // 从objstr.c:str_index_to_ptr()中复制的代码
        size_t index_val = mp_get_index(type, self_len, index, is_slice);
        return self_data + index_val;
    }

    mp_int_t i;
    // 从mp_get_index复制的代码,获取索引的整数值
    if (mp_obj_is_small_int(index)) {
   
        i = MP_OBJ_SMALL_INT_VALUE(index);
    } else if (!mp_obj_get_int_maybe(index, &i)) {
   
        mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("字符串索引必须是整数,而不是 %s"), mp_obj_get_type_str(index));
    }
    const byte *s, *top = self_data + self_len;
    if (i < 0) {
   
        // 处理负索引
        for (s 
  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openwin_top

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值