2828// tested in the unix "coverage" build, without bringing in "our" os module
2929
3030#include <stdlib.h>
31+ #include <stdarg.h>
3132#include <string.h>
3233
3334#include "shared-bindings/os/__init__.h"
3637#include "py/gc.h"
3738#include "py/misc.h"
3839#include "py/mpstate.h"
40+ #include "py/mpprint.h"
3941#include "py/objstr.h"
4042#include "py/parsenum.h"
4143#include "py/runtime.h"
@@ -311,42 +313,70 @@ STATIC os_getenv_err_t os_getenv_buf_terminated(const char *key, char *value, si
311313 return result ;
312314}
313315
314- os_getenv_err_t common_hal_os_getenv_str (const char * key , char * value , size_t value_len ) {
315- bool quoted ;
316- os_getenv_err_t result = os_getenv_buf_terminated (key , value , value_len , & quoted );
317- if (result == GETENV_OK && !quoted ) {
318- result = GETENV_ERR_UNEXPECTED | value [0 ];
319- }
320- return result ;
316+ STATIC void print_dont_raise (const mp_obj_type_t * exc_type , const compressed_string_t * fmt , ...) {
317+ va_list argptr ;
318+ va_start (argptr ,fmt );
319+ mp_vcprintf (& mp_plat_print , fmt , argptr );
320+ mp_printf (& mp_plat_print , "\n" );
321+ va_end (argptr );
321322}
322323
323- STATIC void throw_getenv_error (os_getenv_err_t error ) {
324+ STATIC void handle_getenv_error (os_getenv_err_t error , void ( * handle )( const mp_obj_type_t * exc_type , const compressed_string_t * fmt , ...) ) {
324325 if (error == GETENV_OK ) {
325326 return ;
326327 }
327328 if (error & GETENV_ERR_UNEXPECTED ) {
328329 byte character = (error & 0xff );
329- mp_print_t print ;
330+ char buf [ 8 ] ;
330331 vstr_t vstr ;
331- vstr_init_print (& vstr , 8 + 4 + 1 , & print );
332+ vstr_init_fixed_buf (& vstr , sizeof (buf ), buf );
333+ mp_print_t print = { .data = & vstr , .print_strn = (mp_print_strn_t )vstr_add_strn };
334+
332335 if (character ) {
333336 mp_str_print_quoted (& print , & character , 1 , true);
334337 } else {
335338 mp_str_print_quoted (& print , (byte * )"EOF" , 3 , true);
336339 }
337- mp_raise_ValueError_varg (translate ("Invalid byte %.*s" ),
338- vstr .len , vstr .buf );
340+ handle (& mp_type_ValueError , translate ("Invalid byte %.*s" ), vstr .len , vstr .buf );
341+ } else {
342+ switch (error ) {
343+ case GETENV_ERR_OPEN :
344+ handle (& mp_type_ValueError , translate ("%S" ), translate ("File not found" ));
345+ break ;
346+ case GETENV_ERR_UNICODE :
347+ handle (& mp_type_ValueError , translate ("%S" ), translate ("Invalid unicode escape" ));
348+ break ;
349+ case GETENV_ERR_NOT_FOUND :
350+ handle (& mp_type_ValueError , translate ("%S" ), translate ("Key not found" ));
351+ break ;
352+ default :
353+ handle (& mp_type_RuntimeError , translate ("%S" ), translate ("Internal error" ));
354+ break ;
355+ }
339356 }
340- switch (error ) {
341- case GETENV_ERR_OPEN :
342- mp_raise_ValueError (translate ("File not found" ));
343- case GETENV_ERR_UNICODE :
344- mp_raise_ValueError (translate ("Invalid unicode escape" ));
345- case GETENV_ERR_NOT_FOUND :
346- mp_raise_ValueError (translate ("Key not found" ));
347- default :
348- mp_raise_RuntimeError (translate ("Internal error" ));
357+ }
358+
359+ STATIC void common_hal_os_getenv_showerr (const char * key , os_getenv_err_t result ) {
360+ if (result != GETENV_OK && result != GETENV_ERR_OPEN && result != GETENV_ERR_NOT_FOUND ) {
361+ mp_cprintf (& mp_plat_print , translate ("An error occurred while retrieving '%s':\n" ), key );
362+ handle_getenv_error (result , print_dont_raise );
363+ }
364+ }
365+
366+ STATIC
367+ os_getenv_err_t common_hal_os_getenv_str_inner (const char * key , char * value , size_t value_len ) {
368+ bool quoted ;
369+ os_getenv_err_t result = os_getenv_buf_terminated (key , value , value_len , & quoted );
370+ if (result == GETENV_OK && !quoted ) {
371+ result = GETENV_ERR_UNEXPECTED | value [0 ];
349372 }
373+ return result ;
374+ }
375+
376+ os_getenv_err_t common_hal_os_getenv_str (const char * key , char * value , size_t value_len ) {
377+ os_getenv_err_t result = common_hal_os_getenv_str_inner (key , value , value_len );
378+ common_hal_os_getenv_showerr (key , result );
379+ return result ;
350380}
351381
352382mp_obj_t common_hal_os_getenv_path (const char * path , const char * key , mp_obj_t default_ ) {
@@ -358,7 +388,7 @@ mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t d
358388 if (result == GETENV_ERR_NOT_FOUND || result == GETENV_ERR_OPEN ) {
359389 return default_ ;
360390 }
361- throw_getenv_error (result );
391+ handle_getenv_error (result , mp_raise_msg_varg );
362392
363393 if (quoted ) {
364394 return mp_obj_new_str_from_vstr (& mp_type_str , & buf );
@@ -371,7 +401,7 @@ mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_) {
371401 return common_hal_os_getenv_path (GETENV_PATH , key , default_ );
372402}
373403
374- os_getenv_err_t common_hal_os_getenv_int (const char * key , mp_int_t * value ) {
404+ STATIC os_getenv_err_t common_hal_os_getenv_int_inner (const char * key , mp_int_t * value ) {
375405 char buf [16 ];
376406 bool quoted ;
377407 os_getenv_err_t result = os_getenv_buf_terminated (key , buf , sizeof (buf ), & quoted );
@@ -389,3 +419,9 @@ os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value) {
389419 * value = (mp_int_t )num ;
390420 return GETENV_OK ;
391421}
422+
423+ os_getenv_err_t common_hal_os_getenv_int (const char * key , mp_int_t * value ) {
424+ os_getenv_err_t result = common_hal_os_getenv_int_inner (key , value );
425+ common_hal_os_getenv_showerr (key , result );
426+ return result ;
427+ }
0 commit comments