From c96dc26792905dc43280587fcdf5ae5af024b286 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Sun, 11 Feb 2024 20:51:35 +0300 Subject: [PATCH 01/10] Generate TZ.h from zoneinfo (#9084) * Generate TZ.h from zoneinfo Using tzdata pypi package that ships zoneinfo blobs Can't use raw data package from IANA, need it built first Minor tweaks to Espurna script that generated .md More data than the original, not limited to ZONE/... Zoneinfo source can be overwritten using path args, if needed (but, probably not needed, since it would always be preferable to pull the latest version) Also, allow to override certain names and tz strings independent of tzdata values (resolves #9007) --- cores/esp8266/TZ.h | 247 +++++++++++++++++++++++++++++++---------- package/README.md | 6 +- tools/TZupdate.sh | 72 ------------ tools/format_tzdata.py | 173 +++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+), 134 deletions(-) delete mode 100755 tools/TZupdate.sh create mode 100755 tools/format_tzdata.py diff --git a/cores/esp8266/TZ.h b/cores/esp8266/TZ.h index b0fb312ba3..478abb16c0 100644 --- a/cores/esp8266/TZ.h +++ b/cores/esp8266/TZ.h @@ -1,22 +1,16 @@ +// ! ! ! DO NOT EDIT, AUTOMATICALLY GENERATED ! ! ! +// File created 2024-02-05 00:00:00.000000+00:00 +// Based on IANA database 2023d +// Re-run /tools/tools/format_tzdata.py to update -// autogenerated from https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv -// by script /tools/TZupdate.sh -// Mon Mar 20 22:00:17 UTC 2023 -// -// This database is autogenerated from IANA timezone database -// https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv -// (using https://www.iana.org/time-zones) -// and can be updated on demand in this repository -// or by yourself using the above script - -#ifndef TZDB_H -#define TZDB_H +#pragma once #define TZ_Africa_Abidjan PSTR("GMT0") #define TZ_Africa_Accra PSTR("GMT0") #define TZ_Africa_Addis_Ababa PSTR("EAT-3") #define TZ_Africa_Algiers PSTR("CET-1") #define TZ_Africa_Asmara PSTR("EAT-3") +#define TZ_Africa_Asmera PSTR("EAT-3") #define TZ_Africa_Bamako PSTR("GMT0") #define TZ_Africa_Bangui PSTR("WAT-1") #define TZ_Africa_Banjul PSTR("GMT0") @@ -24,7 +18,7 @@ #define TZ_Africa_Blantyre PSTR("CAT-2") #define TZ_Africa_Brazzaville PSTR("WAT-1") #define TZ_Africa_Bujumbura PSTR("CAT-2") -#define TZ_Africa_Cairo PSTR("EET-2") +#define TZ_Africa_Cairo PSTR("EET-2EEST,M4.5.5/0,M10.5.4/24") #define TZ_Africa_Casablanca PSTR("<+01>-1") #define TZ_Africa_Ceuta PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Africa_Conakry PSTR("GMT0") @@ -61,6 +55,7 @@ #define TZ_Africa_Ouagadougou PSTR("GMT0") #define TZ_Africa_PortomNovo PSTR("WAT-1") #define TZ_Africa_Sao_Tome PSTR("GMT0") +#define TZ_Africa_Timbuktu PSTR("GMT0") #define TZ_Africa_Tripoli PSTR("EET-2") #define TZ_Africa_Tunis PSTR("CET-1") #define TZ_Africa_Windhoek PSTR("CAT-2") @@ -71,6 +66,7 @@ #define TZ_America_Araguaina PSTR("<-03>3") #define TZ_America_Argentina_Buenos_Aires PSTR("<-03>3") #define TZ_America_Argentina_Catamarca PSTR("<-03>3") +#define TZ_America_Argentina_ComodRivadavia PSTR("<-03>3") #define TZ_America_Argentina_Cordoba PSTR("<-03>3") #define TZ_America_Argentina_Jujuy PSTR("<-03>3") #define TZ_America_Argentina_La_Rioja PSTR("<-03>3") @@ -84,6 +80,7 @@ #define TZ_America_Aruba PSTR("AST4") #define TZ_America_Asuncion PSTR("<-04>4<-03>,M10.1.0/0,M3.4.0/0") #define TZ_America_Atikokan PSTR("EST5") +#define TZ_America_Atka PSTR("HST10HDT,M3.2.0,M11.1.0") #define TZ_America_Bahia PSTR("<-03>3") #define TZ_America_Bahia_Banderas PSTR("CST6") #define TZ_America_Barbados PSTR("AST4") @@ -93,14 +90,19 @@ #define TZ_America_Boa_Vista PSTR("<-04>4") #define TZ_America_Bogota PSTR("<-05>5") #define TZ_America_Boise PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_America_Buenos_Aires PSTR("<-03>3") #define TZ_America_Cambridge_Bay PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Campo_Grande PSTR("<-04>4") #define TZ_America_Cancun PSTR("EST5") #define TZ_America_Caracas PSTR("<-04>4") +#define TZ_America_Catamarca PSTR("<-03>3") #define TZ_America_Cayenne PSTR("<-03>3") #define TZ_America_Cayman PSTR("EST5") #define TZ_America_Chicago PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Chihuahua PSTR("CST6") +#define TZ_America_Ciudad_Juarez PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_America_Coral_Harbour PSTR("EST5") +#define TZ_America_Cordoba PSTR("<-03>3") #define TZ_America_Costa_Rica PSTR("CST6") #define TZ_America_Creston PSTR("MST7") #define TZ_America_Cuiaba PSTR("<-04>4") @@ -114,10 +116,12 @@ #define TZ_America_Edmonton PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Eirunepe PSTR("<-05>5") #define TZ_America_El_Salvador PSTR("CST6") -#define TZ_America_Fortaleza PSTR("<-03>3") +#define TZ_America_Ensenada PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_America_Fort_Nelson PSTR("MST7") +#define TZ_America_Fort_Wayne PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Fortaleza PSTR("<-03>3") #define TZ_America_Glace_Bay PSTR("AST4ADT,M3.2.0,M11.1.0") -#define TZ_America_Godthab PSTR("<-02>2") +#define TZ_America_Godthab PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") #define TZ_America_Goose_Bay PSTR("AST4ADT,M3.2.0,M11.1.0") #define TZ_America_Grand_Turk PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Grenada PSTR("AST4") @@ -136,16 +140,20 @@ #define TZ_America_Indiana_Vevay PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Indiana_Vincennes PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Indiana_Winamac PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Indianapolis PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Inuvik PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Iqaluit PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Jamaica PSTR("EST5") +#define TZ_America_Jujuy PSTR("<-03>3") #define TZ_America_Juneau PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_Kentucky_Louisville PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Kentucky_Monticello PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Knox_IN PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Kralendijk PSTR("AST4") #define TZ_America_La_Paz PSTR("<-04>4") #define TZ_America_Lima PSTR("<-05>5") #define TZ_America_Los_Angeles PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_America_Louisville PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Lower_Princes PSTR("AST4") #define TZ_America_Maceio PSTR("<-03>3") #define TZ_America_Managua PSTR("CST6") @@ -154,6 +162,7 @@ #define TZ_America_Martinique PSTR("AST4") #define TZ_America_Matamoros PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Mazatlan PSTR("MST7") +#define TZ_America_Mendoza PSTR("<-03>3") #define TZ_America_Menominee PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Merida PSTR("CST6") #define TZ_America_Metlakatla PSTR("AKST9AKDT,M3.2.0,M11.1.0") @@ -172,7 +181,7 @@ #define TZ_America_North_Dakota_Beulah PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_North_Dakota_Center PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_North_Dakota_New_Salem PSTR("CST6CDT,M3.2.0,M11.1.0") -#define TZ_America_Nuuk PSTR("<-02>2") +#define TZ_America_Nuuk PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") #define TZ_America_Ojinaga PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Panama PSTR("EST5") #define TZ_America_Pangnirtung PSTR("EST5EDT,M3.2.0,M11.1.0") @@ -180,6 +189,7 @@ #define TZ_America_Phoenix PSTR("MST7") #define TZ_America_PortmaumPrince PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Port_of_Spain PSTR("AST4") +#define TZ_America_Porto_Acre PSTR("<-05>5") #define TZ_America_Porto_Velho PSTR("<-04>4") #define TZ_America_Puerto_Rico PSTR("AST4") #define TZ_America_Punta_Arenas PSTR("<-03>3") @@ -189,11 +199,14 @@ #define TZ_America_Regina PSTR("CST6") #define TZ_America_Resolute PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Rio_Branco PSTR("<-05>5") +#define TZ_America_Rosario PSTR("<-03>3") +#define TZ_America_Santa_Isabel PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_America_Santarem PSTR("<-03>3") #define TZ_America_Santiago PSTR("<-04>4<-03>,M9.1.6/24,M4.1.6/24") #define TZ_America_Santo_Domingo PSTR("AST4") #define TZ_America_Sao_Paulo PSTR("<-03>3") -#define TZ_America_Scoresbysund PSTR("<-01>1<+00>,M3.5.0/0,M10.5.0/1") +#define TZ_America_Scoresbysund PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") +#define TZ_America_Shiprock PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Sitka PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_St_Barthelemy PSTR("AST4") #define TZ_America_St_Johns PSTR("NST3:30NDT,M3.2.0,M11.1.0") @@ -209,11 +222,12 @@ #define TZ_America_Toronto PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Tortola PSTR("AST4") #define TZ_America_Vancouver PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_America_Virgin PSTR("AST4") #define TZ_America_Whitehorse PSTR("MST7") #define TZ_America_Winnipeg PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Yakutat PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_Yellowknife PSTR("MST7MDT,M3.2.0,M11.1.0") -#define TZ_Antarctica_Casey PSTR("<+11>-11") +#define TZ_Antarctica_Casey PSTR("<+08>-8") #define TZ_Antarctica_Davis PSTR("<+07>-7") #define TZ_Antarctica_DumontDUrville PSTR("<+10>-10") #define TZ_Antarctica_Macquarie PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") @@ -221,9 +235,10 @@ #define TZ_Antarctica_McMurdo PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Antarctica_Palmer PSTR("<-03>3") #define TZ_Antarctica_Rothera PSTR("<-03>3") +#define TZ_Antarctica_South_Pole PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Antarctica_Syowa PSTR("<+03>-3") #define TZ_Antarctica_Troll PSTR("<+00>0<+02>-2,M3.5.0/1,M10.5.0/3") -#define TZ_Antarctica_Vostok PSTR("<+06>-6") +#define TZ_Antarctica_Vostok PSTR("<+05>-5") #define TZ_Arctic_Longyearbyen PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Asia_Aden PSTR("<+03>-3") #define TZ_Asia_Almaty PSTR("<+06>-6") @@ -232,6 +247,7 @@ #define TZ_Asia_Aqtau PSTR("<+05>-5") #define TZ_Asia_Aqtobe PSTR("<+05>-5") #define TZ_Asia_Ashgabat PSTR("<+05>-5") +#define TZ_Asia_Ashkhabad PSTR("<+05>-5") #define TZ_Asia_Atyrau PSTR("<+05>-5") #define TZ_Asia_Baghdad PSTR("<+03>-3") #define TZ_Asia_Bahrain PSTR("<+03>-3") @@ -241,9 +257,13 @@ #define TZ_Asia_Beirut PSTR("EET-2EEST,M3.5.0/0,M10.5.0/0") #define TZ_Asia_Bishkek PSTR("<+06>-6") #define TZ_Asia_Brunei PSTR("<+08>-8") +#define TZ_Asia_Calcutta PSTR("IST-5:30") #define TZ_Asia_Chita PSTR("<+09>-9") #define TZ_Asia_Choibalsan PSTR("<+08>-8") +#define TZ_Asia_Chongqing PSTR("CST-8") +#define TZ_Asia_Chungking PSTR("CST-8") #define TZ_Asia_Colombo PSTR("<+0530>-5:30") +#define TZ_Asia_Dacca PSTR("<+06>-6") #define TZ_Asia_Damascus PSTR("<+03>-3") #define TZ_Asia_Dhaka PSTR("<+06>-6") #define TZ_Asia_Dili PSTR("<+09>-9") @@ -251,24 +271,29 @@ #define TZ_Asia_Dushanbe PSTR("<+05>-5") #define TZ_Asia_Famagusta PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Asia_Gaza PSTR("EET-2EEST,M3.4.4/50,M10.4.4/50") +#define TZ_Asia_Harbin PSTR("CST-8") #define TZ_Asia_Hebron PSTR("EET-2EEST,M3.4.4/50,M10.4.4/50") #define TZ_Asia_Ho_Chi_Minh PSTR("<+07>-7") #define TZ_Asia_Hong_Kong PSTR("HKT-8") #define TZ_Asia_Hovd PSTR("<+07>-7") #define TZ_Asia_Irkutsk PSTR("<+08>-8") +#define TZ_Asia_Istanbul PSTR("<+03>-3") #define TZ_Asia_Jakarta PSTR("WIB-7") #define TZ_Asia_Jayapura PSTR("WIT-9") #define TZ_Asia_Jerusalem PSTR("IST-2IDT,M3.4.4/26,M10.5.0") #define TZ_Asia_Kabul PSTR("<+0430>-4:30") #define TZ_Asia_Kamchatka PSTR("<+12>-12") #define TZ_Asia_Karachi PSTR("PKT-5") +#define TZ_Asia_Kashgar PSTR("<+06>-6") #define TZ_Asia_Kathmandu PSTR("<+0545>-5:45") +#define TZ_Asia_Katmandu PSTR("<+0545>-5:45") #define TZ_Asia_Khandyga PSTR("<+09>-9") #define TZ_Asia_Kolkata PSTR("IST-5:30") #define TZ_Asia_Krasnoyarsk PSTR("<+07>-7") #define TZ_Asia_Kuala_Lumpur PSTR("<+08>-8") #define TZ_Asia_Kuching PSTR("<+08>-8") #define TZ_Asia_Kuwait PSTR("<+03>-3") +#define TZ_Asia_Macao PSTR("CST-8") #define TZ_Asia_Macau PSTR("CST-8") #define TZ_Asia_Magadan PSTR("<+11>-11") #define TZ_Asia_Makassar PSTR("WITA-8") @@ -283,8 +308,11 @@ #define TZ_Asia_Pontianak PSTR("WIB-7") #define TZ_Asia_Pyongyang PSTR("KST-9") #define TZ_Asia_Qatar PSTR("<+03>-3") +#define TZ_Asia_Qostanay PSTR("<+06>-6") #define TZ_Asia_Qyzylorda PSTR("<+05>-5") +#define TZ_Asia_Rangoon PSTR("<+0630>-6:30") #define TZ_Asia_Riyadh PSTR("<+03>-3") +#define TZ_Asia_Saigon PSTR("<+07>-7") #define TZ_Asia_Sakhalin PSTR("<+11>-11") #define TZ_Asia_Samarkand PSTR("<+05>-5") #define TZ_Asia_Seoul PSTR("KST-9") @@ -295,10 +323,14 @@ #define TZ_Asia_Tashkent PSTR("<+05>-5") #define TZ_Asia_Tbilisi PSTR("<+04>-4") #define TZ_Asia_Tehran PSTR("<+0330>-3:30") +#define TZ_Asia_Tel_Aviv PSTR("IST-2IDT,M3.4.4/26,M10.5.0") +#define TZ_Asia_Thimbu PSTR("<+06>-6") #define TZ_Asia_Thimphu PSTR("<+06>-6") #define TZ_Asia_Tokyo PSTR("JST-9") #define TZ_Asia_Tomsk PSTR("<+07>-7") +#define TZ_Asia_Ujung_Pandang PSTR("WITA-8") #define TZ_Asia_Ulaanbaatar PSTR("<+08>-8") +#define TZ_Asia_Ulan_Bator PSTR("<+08>-8") #define TZ_Asia_Urumqi PSTR("<+06>-6") #define TZ_Asia_UstmNera PSTR("<+10>-10") #define TZ_Asia_Vientiane PSTR("<+07>-7") @@ -311,28 +343,99 @@ #define TZ_Atlantic_Bermuda PSTR("AST4ADT,M3.2.0,M11.1.0") #define TZ_Atlantic_Canary PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Cape_Verde PSTR("<-01>1") +#define TZ_Atlantic_Faeroe PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Faroe PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_Atlantic_Jan_Mayen PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Atlantic_Madeira PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Reykjavik PSTR("GMT0") #define TZ_Atlantic_South_Georgia PSTR("<-02>2") -#define TZ_Atlantic_Stanley PSTR("<-03>3") #define TZ_Atlantic_St_Helena PSTR("GMT0") +#define TZ_Atlantic_Stanley PSTR("<-03>3") +#define TZ_Australia_ACT PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Adelaide PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Brisbane PSTR("AEST-10") #define TZ_Australia_Broken_Hill PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Canberra PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Currie PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Darwin PSTR("ACST-9:30") #define TZ_Australia_Eucla PSTR("<+0845>-8:45") #define TZ_Australia_Hobart PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_LHI PSTR("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0") #define TZ_Australia_Lindeman PSTR("AEST-10") #define TZ_Australia_Lord_Howe PSTR("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0") #define TZ_Australia_Melbourne PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_NSW PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_North PSTR("ACST-9:30") #define TZ_Australia_Perth PSTR("AWST-8") +#define TZ_Australia_Queensland PSTR("AEST-10") +#define TZ_Australia_South PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Sydney PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Tasmania PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Victoria PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_West PSTR("AWST-8") +#define TZ_Australia_Yancowinna PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") +#define TZ_Brazil_Acre PSTR("<-05>5") +#define TZ_Brazil_DeNoronha PSTR("<-02>2") +#define TZ_Brazil_East PSTR("<-03>3") +#define TZ_Brazil_West PSTR("<-04>4") +#define TZ_CET PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_CST6CDT PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_Canada_Atlantic PSTR("AST4ADT,M3.2.0,M11.1.0") +#define TZ_Canada_Central PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_Canada_Eastern PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_Canada_Mountain PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_Canada_Newfoundland PSTR("NST3:30NDT,M3.2.0,M11.1.0") +#define TZ_Canada_Pacific PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_Canada_Saskatchewan PSTR("CST6") +#define TZ_Canada_Yukon PSTR("MST7") +#define TZ_Chile_Continental PSTR("<-04>4<-03>,M9.1.6/24,M4.1.6/24") +#define TZ_Chile_EasterIsland PSTR("<-06>6<-05>,M9.1.6/22,M4.1.6/22") +#define TZ_Cuba PSTR("CST5CDT,M3.2.0/0,M11.1.0/1") +#define TZ_EET PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_EST PSTR("EST5") +#define TZ_EST5EDT PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_Egypt PSTR("EET-2EEST,M4.5.5/0,M10.5.4/24") +#define TZ_Eire PSTR("IST-1GMT0,M10.5.0,M3.5.0/1") +#define TZ_Etc_GMT PSTR("GMT0") +#define TZ_Etc_GMTp0 PSTR("GMT0") +#define TZ_Etc_GMTp1 PSTR("<-01>1") +#define TZ_Etc_GMTp10 PSTR("<-10>10") +#define TZ_Etc_GMTp11 PSTR("<-11>11") +#define TZ_Etc_GMTp12 PSTR("<-12>12") +#define TZ_Etc_GMTp2 PSTR("<-02>2") +#define TZ_Etc_GMTp3 PSTR("<-03>3") +#define TZ_Etc_GMTp4 PSTR("<-04>4") +#define TZ_Etc_GMTp5 PSTR("<-05>5") +#define TZ_Etc_GMTp6 PSTR("<-06>6") +#define TZ_Etc_GMTp7 PSTR("<-07>7") +#define TZ_Etc_GMTp8 PSTR("<-08>8") +#define TZ_Etc_GMTp9 PSTR("<-09>9") +#define TZ_Etc_GMTm0 PSTR("GMT0") +#define TZ_Etc_GMTm1 PSTR("<+01>-1") +#define TZ_Etc_GMTm10 PSTR("<+10>-10") +#define TZ_Etc_GMTm11 PSTR("<+11>-11") +#define TZ_Etc_GMTm12 PSTR("<+12>-12") +#define TZ_Etc_GMTm13 PSTR("<+13>-13") +#define TZ_Etc_GMTm14 PSTR("<+14>-14") +#define TZ_Etc_GMTm2 PSTR("<+02>-2") +#define TZ_Etc_GMTm3 PSTR("<+03>-3") +#define TZ_Etc_GMTm4 PSTR("<+04>-4") +#define TZ_Etc_GMTm5 PSTR("<+05>-5") +#define TZ_Etc_GMTm6 PSTR("<+06>-6") +#define TZ_Etc_GMTm7 PSTR("<+07>-7") +#define TZ_Etc_GMTm8 PSTR("<+08>-8") +#define TZ_Etc_GMTm9 PSTR("<+09>-9") +#define TZ_Etc_GMT0 PSTR("GMT0") +#define TZ_Etc_Greenwich PSTR("GMT0") +#define TZ_Etc_UCT PSTR("UTC0") +#define TZ_Etc_UTC PSTR("UTC0") +#define TZ_Etc_Universal PSTR("UTC0") +#define TZ_Etc_Zulu PSTR("UTC0") #define TZ_Europe_Amsterdam PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Andorra PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Astrakhan PSTR("<+04>-4") #define TZ_Europe_Athens PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_Europe_Belfast PSTR("GMT0BST,M3.5.0/1,M10.5.0") #define TZ_Europe_Belgrade PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Berlin PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Bratislava PSTR("CET-1CEST,M3.5.0,M10.5.0/3") @@ -351,7 +454,8 @@ #define TZ_Europe_Jersey PSTR("GMT0BST,M3.5.0/1,M10.5.0") #define TZ_Europe_Kaliningrad PSTR("EET-2") #define TZ_Europe_Kiev PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") -#define TZ_Europe_Kirov PSTR("<+03>-3") +#define TZ_Europe_Kirov PSTR("MSK-3") +#define TZ_Europe_Kyiv PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Lisbon PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Europe_Ljubljana PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_London PSTR("GMT0BST,M3.5.0/1,M10.5.0") @@ -362,6 +466,7 @@ #define TZ_Europe_Minsk PSTR("<+03>-3") #define TZ_Europe_Monaco PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Moscow PSTR("MSK-3") +#define TZ_Europe_Nicosia PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Oslo PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Paris PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Podgorica PSTR("CET-1CEST,M3.5.0,M10.5.0/3") @@ -378,17 +483,31 @@ #define TZ_Europe_Stockholm PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Tallinn PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Tirane PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Europe_Tiraspol PSTR("EET-2EEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Ulyanovsk PSTR("<+04>-4") #define TZ_Europe_Uzhgorod PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_Europe_Uzhhorod PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Vaduz PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vatican PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vienna PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vilnius PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") -#define TZ_Europe_Volgograd PSTR("<+03>-3") +#define TZ_Europe_Volgograd PSTR("MSK-3") #define TZ_Europe_Warsaw PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Zagreb PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Europe_Zaporizhzhia PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Zaporozhye PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Zurich PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Factory PSTR("<-00>0") +#define TZ_GB PSTR("GMT0BST,M3.5.0/1,M10.5.0") +#define TZ_GBmEire PSTR("GMT0BST,M3.5.0/1,M10.5.0") +#define TZ_GMT PSTR("GMT0") +#define TZ_GMTp0 PSTR("GMT0") +#define TZ_GMTm0 PSTR("GMT0") +#define TZ_GMT0 PSTR("GMT0") +#define TZ_Greenwich PSTR("GMT0") +#define TZ_HST PSTR("HST10") +#define TZ_Hongkong PSTR("HKT-8") +#define TZ_Iceland PSTR("GMT0") #define TZ_Indian_Antananarivo PSTR("EAT-3") #define TZ_Indian_Chagos PSTR("<+06>-6") #define TZ_Indian_Christmas PSTR("<+07>-7") @@ -400,6 +519,23 @@ #define TZ_Indian_Mauritius PSTR("<+04>-4") #define TZ_Indian_Mayotte PSTR("EAT-3") #define TZ_Indian_Reunion PSTR("<+04>-4") +#define TZ_Iran PSTR("<+0330>-3:30") +#define TZ_Israel PSTR("IST-2IDT,M3.4.4/26,M10.5.0") +#define TZ_Jamaica PSTR("EST5") +#define TZ_Japan PSTR("JST-9") +#define TZ_Kwajalein PSTR("<+12>-12") +#define TZ_Libya PSTR("EET-2") +#define TZ_MET PSTR("MET-1MEST,M3.5.0,M10.5.0/3") +#define TZ_MST PSTR("MST7") +#define TZ_MST7MDT PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_Mexico_BajaNorte PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_Mexico_BajaSur PSTR("MST7") +#define TZ_Mexico_General PSTR("CST6") +#define TZ_NZ PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") +#define TZ_NZmCHAT PSTR("<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45") +#define TZ_Navajo PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_PRC PSTR("CST-8") +#define TZ_PST8PDT PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_Pacific_Apia PSTR("<+13>-13") #define TZ_Pacific_Auckland PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Pacific_Bougainville PSTR("<+11>-11") @@ -416,6 +552,8 @@ #define TZ_Pacific_Guadalcanal PSTR("<+11>-11") #define TZ_Pacific_Guam PSTR("ChST-10") #define TZ_Pacific_Honolulu PSTR("HST10") +#define TZ_Pacific_Johnston PSTR("HST10") +#define TZ_Pacific_Kanton PSTR("<+13>-13") #define TZ_Pacific_Kiritimati PSTR("<+14>-14") #define TZ_Pacific_Kosrae PSTR("<+11>-11") #define TZ_Pacific_Kwajalein PSTR("<+12>-12") @@ -430,48 +568,39 @@ #define TZ_Pacific_Palau PSTR("<+09>-9") #define TZ_Pacific_Pitcairn PSTR("<-08>8") #define TZ_Pacific_Pohnpei PSTR("<+11>-11") +#define TZ_Pacific_Ponape PSTR("<+11>-11") #define TZ_Pacific_Port_Moresby PSTR("<+10>-10") #define TZ_Pacific_Rarotonga PSTR("<-10>10") #define TZ_Pacific_Saipan PSTR("ChST-10") +#define TZ_Pacific_Samoa PSTR("SST11") #define TZ_Pacific_Tahiti PSTR("<-10>10") #define TZ_Pacific_Tarawa PSTR("<+12>-12") #define TZ_Pacific_Tongatapu PSTR("<+13>-13") +#define TZ_Pacific_Truk PSTR("<+10>-10") #define TZ_Pacific_Wake PSTR("<+12>-12") #define TZ_Pacific_Wallis PSTR("<+12>-12") -#define TZ_Etc_GMT PSTR("GMT0") -#define TZ_Etc_GMTm0 PSTR("GMT0") -#define TZ_Etc_GMTm1 PSTR("<+01>-1") -#define TZ_Etc_GMTm2 PSTR("<+02>-2") -#define TZ_Etc_GMTm3 PSTR("<+03>-3") -#define TZ_Etc_GMTm4 PSTR("<+04>-4") -#define TZ_Etc_GMTm5 PSTR("<+05>-5") -#define TZ_Etc_GMTm6 PSTR("<+06>-6") -#define TZ_Etc_GMTm7 PSTR("<+07>-7") -#define TZ_Etc_GMTm8 PSTR("<+08>-8") -#define TZ_Etc_GMTm9 PSTR("<+09>-9") -#define TZ_Etc_GMTm10 PSTR("<+10>-10") -#define TZ_Etc_GMTm11 PSTR("<+11>-11") -#define TZ_Etc_GMTm12 PSTR("<+12>-12") -#define TZ_Etc_GMTm13 PSTR("<+13>-13") -#define TZ_Etc_GMTm14 PSTR("<+14>-14") -#define TZ_Etc_GMT0 PSTR("GMT0") -#define TZ_Etc_GMTp0 PSTR("GMT0") -#define TZ_Etc_GMTp1 PSTR("<-01>1") -#define TZ_Etc_GMTp2 PSTR("<-02>2") -#define TZ_Etc_GMTp3 PSTR("<-03>3") -#define TZ_Etc_GMTp4 PSTR("<-04>4") -#define TZ_Etc_GMTp5 PSTR("<-05>5") -#define TZ_Etc_GMTp6 PSTR("<-06>6") -#define TZ_Etc_GMTp7 PSTR("<-07>7") -#define TZ_Etc_GMTp8 PSTR("<-08>8") -#define TZ_Etc_GMTp9 PSTR("<-09>9") -#define TZ_Etc_GMTp10 PSTR("<-10>10") -#define TZ_Etc_GMTp11 PSTR("<-11>11") -#define TZ_Etc_GMTp12 PSTR("<-12>12") -#define TZ_Etc_UCT PSTR("UTC0") -#define TZ_Etc_UTC PSTR("UTC0") -#define TZ_Etc_Greenwich PSTR("GMT0") -#define TZ_Etc_Universal PSTR("UTC0") -#define TZ_Etc_Zulu PSTR("UTC0") - -#endif // TZDB_H +#define TZ_Pacific_Yap PSTR("<+10>-10") +#define TZ_Poland PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Portugal PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_ROC PSTR("CST-8") +#define TZ_ROK PSTR("KST-9") +#define TZ_Singapore PSTR("<+08>-8") +#define TZ_Turkey PSTR("<+03>-3") +#define TZ_UCT PSTR("UTC0") +#define TZ_US_Alaska PSTR("AKST9AKDT,M3.2.0,M11.1.0") +#define TZ_US_Aleutian PSTR("HST10HDT,M3.2.0,M11.1.0") +#define TZ_US_Arizona PSTR("MST7") +#define TZ_US_Central PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_US_EastmIndiana PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Eastern PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Hawaii PSTR("HST10") +#define TZ_US_IndianamStarke PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_US_Michigan PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Mountain PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_US_Pacific PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_US_Samoa PSTR("SST11") +#define TZ_UTC PSTR("UTC0") +#define TZ_Universal PSTR("UTC0") +#define TZ_WmSU PSTR("MSK-3") +#define TZ_WET PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_Zulu PSTR("UTC0") diff --git a/package/README.md b/package/README.md index de6f8382ab..b2d64ef76e 100644 --- a/package/README.md +++ b/package/README.md @@ -111,8 +111,8 @@ The following points assume work in a direct clone of the repository, and not in * [platform.txt](https://github.com/esp8266/Arduino/blob/master/platform.txt) and [package.json](https://github.com/esp8266/Arduino/blob/master/package.json): update `version` to the release E.g. `3.0.0`, - * [cores/esp8266/TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h): import the latest database with the following shell command:\ - `$ cd tools; sh TZupdate.sh` + * [cores/esp8266/TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h): import the latest database:\ + `$ pip install -U tzdata; python tools/format_tzdata.py --output cores/esp8266/TZ.h` * Update SSL/TLS certificates and public keys in examples:\ `$ cd tools; sh certsUpdate.sh` @@ -173,7 +173,7 @@ The following points assume work in a direct clone of the repository, and not in * [platform.txt](https://github.com/esp8266/Arduino/blob/master/platform.txt) * [package.json](https://github.com/esp8266/Arduino/blob/master/package.json) - * [TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h) (<= `cd tools; sh ./TZupdate.sh`) + * [TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h) (<= `pip install -U tzdata; python tools/format_tzdata.py --output cores/esp8266/TZ.h`) * Certificates (<= `cd tools; sh certsUpdate.sh`) - [ ] 5. Wait until the release notes have been checked by other maintainers (can be changed afterwards anyway) diff --git a/tools/TZupdate.sh b/tools/TZupdate.sh deleted file mode 100755 index 3c6f41e156..0000000000 --- a/tools/TZupdate.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh - -# this shell script refreshes world timezone definitions in -# cores/esp8266/TZ.h -# -# to run it, use: -# /path/to/TZupdate.sh -# tools/TZupdate.sh -# ./TZupdate.sh - -dir=$(cd ${0%/*} 2>/dev/null; pwd) -base=${0##*/} - -csv=https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv - -set -e - -tz_tmpdir=$(mktemp -d) -trap 'rm -r $tz_tmpdir' EXIT - -input=$tz_tmpdir/zones.csv -names=$tz_tmpdir/names.txt -values=$tz_tmpdir/values.txt - -wget -O $input $csv || curl $csv > $input - -sed -e 's/^[^,]*,//g' -e 's,^,PSTR(,g' -e 's,$,),g' < $input > $values -sed -e 's/^\([^,]*\),.*/#define TZ_\1/g' -e 's,["],,g' < $input | tr '/\-+' '_mp' > $names - -( - -cat << EOF - -// autogenerated from $csv -// by script /tools/${base} -// $(date -u) -// -// This database is autogenerated from IANA timezone database -// ${csv} -// (using https://www.iana.org/time-zones) -// and can be updated on demand in this repository -// or by yourself using the above script - -#ifndef TZDB_H -#define TZDB_H - -EOF - -paste $names $values - -cat << EOF - -#endif // TZDB_H -EOF - -) > $tz_tmpdir/TZ.h - -backup=$(date +%s) -mv ${dir}/../cores/esp8266/TZ.h ${dir}/../cores/esp8266/TZ.h.$backup -mv $tz_tmpdir/TZ.h ${dir}/../cores/esp8266/TZ.h - -cat << EOF - -Done: - '${dir}/../cores/esp8266/TZ.h' is updated - -Diff: -----8<-------8<------8<--- -$(diff -u ${dir}/../cores/esp8266/TZ.h.$backup ${dir}/../cores/esp8266/TZ.h) ---->8----->8------>8------ - -EOF diff --git a/tools/format_tzdata.py b/tools/format_tzdata.py new file mode 100755 index 0000000000..609a9218bf --- /dev/null +++ b/tools/format_tzdata.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 + +# this script refreshes world timezone definitions in +# cores/esp8266/TZ.h +# +# use the file output argument or stdout redirect to overwrite the target file + +import argparse +import contextlib +import datetime +import mmap +import os +import pathlib +import re +import sys +import pathlib + +from importlib import resources + +import tzdata # https://tzdata.readthedocs.io/en/latest/ + + +def known_alias(entry): + swaps = { + "Europe/Zaporozhye": "Europe/Zaporizhzhia", + "Europe/Uzhgorod": "Europe/Uzhhorod", + } + + return swaps.get(entry) + + +def fix_name(name): + swaps = [["-", "m"], ["+", "p"], ["/", "_"]] + + for lhs, rhs in swaps: + name = name.replace(lhs, rhs) + + return name + + +def utc_alias(zone): + return zone in ( + "Universal", + "UTC", + "UCT", + "Zulu", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + ) + + +def tzdata_resource_from_name(name): + pair = name.rsplit("/", 1) + if len(pair) == 1: + return resources.files("tzdata.zoneinfo") / pair[0] + + return resources.files(f'tzdata.zoneinfo.{pair[0].replace("/", ".")}') / pair[1] + + +def make_zones_list(f): + return [zone.strip() for zone in f.readlines()] + + +def make_zones(args): + out = [] + + for zone in make_zones_list(args.zones): + if args.root: + target = args.root / zone + else: + target = tzdata_resource_from_name(zone) + + with target.open("rb") as f: + magic = f.read(4) + if magic != b"TZif": + continue + + m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) + newline = m.rfind(b"\n", 0, len(m) - 1) + if newline < 0: + continue + + m.seek(newline + 1) + tz = m.readline().strip() + tz = tz.decode("ascii") + + if alias := known_alias(zone): + out.append([alias, tz]) + + out.append([zone, tz]) + + out.sort(key=lambda x: x[0]) + return out + + +def markdown(zones): + utcs = [] + rows = [] + + for name, value in zones: + if utc_alias(name): + utcs.append(name) + continue + + rows.append(f"|{name}|`{value}`|") + + print("|Name|Value|") + print("|---|---|") + for name in utcs: + print(f"|{name}|UTC0|") + + last = "" + for row in rows: + prefix, _, _ = row.partition("/") + if last != prefix: + last = prefix + print("|||") + print(row) + print() + print("---") + print() + print(f"*Generated with *{tzdata.IANA_VERSION=} {tzdata.__version__=}*") + + +def header(zones): + print("// ! ! ! DO NOT EDIT, AUTOMATICALLY GENERATED ! ! !") + print(f"// File created {datetime.datetime.now(tz=datetime.timezone.utc)}") + print(f"// Based on IANA database {tzdata.IANA_VERSION}") + print(f"// Re-run /tools/{sys.argv[0]} to update") + print() + print("#pragma once") + print() + for name, value in zones: + print(f'#define TZ_{fix_name(name)}\tPSTR("{value}")') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument( + "--output", + type=argparse.FileType("w", encoding="utf-8"), + default=sys.stdout, + ) + parser.add_argument( + "--format", + default="header", + choices=["header", "markdown"], + ) + parser.add_argument( + "--zones", + type=argparse.FileType("r", encoding="utf-8"), + help="Zone names file, one per line", + default=os.path.join(os.path.dirname(tzdata.__file__), "zones"), + ) + parser.add_argument( + "--root", + help="Where do we get raw zoneinfo files from", + type=pathlib.Path, + ) + + args = parser.parse_args() + zones = make_zones(args) + + with contextlib.redirect_stdout(args.output): + if args.format == "markdown": + markdown(zones) + elif args.format == "header": + header(zones) From b0d9e75d5049e5cfaffdee652035b4cfc28c1338 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 17 Mar 2024 21:28:39 +0330 Subject: [PATCH 02/10] LwipIntf - typo (#9103) --- cores/esp8266/LwipIntf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/LwipIntf.cpp b/cores/esp8266/LwipIntf.cpp index e142730df0..675063cd62 100644 --- a/cores/esp8266/LwipIntf.cpp +++ b/cores/esp8266/LwipIntf.cpp @@ -43,7 +43,7 @@ extern "C" // can return nullptr when STA is down // - Because WiFi is started in off mode at boot time, // wifi_station_set/get_hostname() is now no more used -// because setting hostname firt does not work anymore +// because setting hostname first does not work anymore // - wifi_station_hostname is overwritten by SDK when wifi is // woken up in WiFi::mode() // From 2064d437a310ec552e2ecc5c8c9c0e40638a2f38 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Sun, 17 Mar 2024 21:11:32 +0300 Subject: [PATCH 03/10] ESP8266WiFi - document event handler lifetime, add [[nodiscard]] (#9087) * disallow not assigning wifieventhandler somewhere * fix markdown syntax in rst * mention lifetime in example and docs --- doc/esp8266wifi/generic-examples.rst | 25 ++++++++++++++----- .../soft-access-point-examples.rst | 4 ++- .../examples/WiFiEvents/WiFiEvents.ino | 7 ++++-- .../ESP8266WiFi/src/ESP8266WiFiGeneric.h | 18 ++++++------- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/doc/esp8266wifi/generic-examples.rst b/doc/esp8266wifi/generic-examples.rst index bbac0cd839..e139e3e5b5 100644 --- a/doc/esp8266wifi/generic-examples.rst +++ b/doc/esp8266wifi/generic-examples.rst @@ -38,16 +38,29 @@ Register the Events To get events to work we need to complete just two steps: -1. Declare the event handler: +1. Declare the event handler in global scope. -``cpp WiFiEventHandler disconnectedEventHandler;`` +.. code:: cpp + WiFiEventHandler disconnectedEventHandler; + +Alternatively, it can be declared as ``static`` in both function and global scopes. -2. Select particular event (in this case ``onStationModeDisconnected``) - and add the code to be executed when event is fired. -``cpp disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event) { Serial.println("Station disconnected"); });`` If this event is fired the code will print out information that station has been disconnected. +2. Select particular event (in this case ``onStationModeDisconnected``). + When this event is fired the code will print out information that station has been disconnected: + +.. code:: cpp + disconnectedEventHandler = WiFi.onStationModeDisconnected( + [](auto&& event) { + Serial.println("Station disconnected"); + }); + +3. Disable ``disconnectedEventHandler``, so the event is no longer handled by our callback: + +.. code:: cpp + disconnectedEventHandler = nullptr; -That's it. It is all we need to do. +Take note that lifetime of the callback handler is up to the app. e.g. if ``onStationModeDisconnected`` is declared in the function scope, it would be discarded immediately after the function exists. The Code ~~~~~~~~ diff --git a/doc/esp8266wifi/soft-access-point-examples.rst b/doc/esp8266wifi/soft-access-point-examples.rst index c4cf39c6c2..2c9fee762c 100644 --- a/doc/esp8266wifi/soft-access-point-examples.rst +++ b/doc/esp8266wifi/soft-access-point-examples.rst @@ -79,7 +79,9 @@ Sketch is small so analysis shouldn't be difficult. In first line we are includi Setting up of the access point ``ESPsoftAP_01`` is done by executing: -``cpp boolean result = WiFi.softAP("ESPsoftAP_01", "pass-to-soft-AP");`` +.. code:: cpp + + boolean result = WiFi.softAP("ESPsoftAP_01", "pass-to-soft-AP"); If this operation is successful then ``result`` will be ``true`` or ``false`` if otherwise. Basing on that either ``Ready`` or ``Failed!`` will be printed out by the following ``if - else`` conditional statement. diff --git a/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino index dddfde9f5b..7d66553b61 100644 --- a/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino +++ b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino @@ -24,6 +24,9 @@ const char* ssid = APSSID; const char* password = APPSK; +// WiFi.on* methods **must** only be called **after** entering setup(). +// Assigning immediately in global scope is not adviced, neither is assigning them within any other object constructors. +// These variables **may** exist in function block, but **only** if they are declared as `static` WiFiEventHandler stationConnectedHandler; WiFiEventHandler stationDisconnectedHandler; WiFiEventHandler probeRequestPrintHandler; @@ -43,12 +46,12 @@ void setup() { WiFi.mode(WIFI_AP); WiFi.softAP(ssid, password); - // Register event handlers. - // Callback functions will be called as long as these handler objects exist. // Call "onStationConnected" each time a station connects stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected); + // Call "onStationDisconnected" each time a station disconnects stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected); + // Call "onProbeRequestPrint" and "onProbeRequestBlink" each time // a probe request is received. // Former will print MAC address of the station and RSSI to Serial, diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h index d0525176bd..e0ad560d0e 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h @@ -71,15 +71,15 @@ class ESP8266WiFiGenericClass { void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated)); // Subscribe to specific event and get event information as an argument to the callback - WiFiEventHandler onStationModeConnected(std::function); - WiFiEventHandler onStationModeDisconnected(std::function); - WiFiEventHandler onStationModeAuthModeChanged(std::function); - WiFiEventHandler onStationModeGotIP(std::function); - WiFiEventHandler onStationModeDHCPTimeout(std::function); - WiFiEventHandler onSoftAPModeStationConnected(std::function); - WiFiEventHandler onSoftAPModeStationDisconnected(std::function); - WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); - WiFiEventHandler onWiFiModeChange(std::function); + [[nodiscard]] WiFiEventHandler onStationModeConnected(std::function); + [[nodiscard]] WiFiEventHandler onStationModeDisconnected(std::function); + [[nodiscard]] WiFiEventHandler onStationModeAuthModeChanged(std::function); + [[nodiscard]] WiFiEventHandler onStationModeGotIP(std::function); + [[nodiscard]] WiFiEventHandler onStationModeDHCPTimeout(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeStationConnected(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeStationDisconnected(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); + [[nodiscard]] WiFiEventHandler onWiFiModeChange(std::function); uint8_t channel(void); From 760dbeeda9305d1f50c64be1668354cefbecdb20 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 17 Mar 2024 19:52:26 +0100 Subject: [PATCH 04/10] emulation-on-host: +memcmp_P (#9093) --- tests/host/sys/pgmspace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/host/sys/pgmspace.h b/tests/host/sys/pgmspace.h index ef878eaaff..ac60cb15be 100644 --- a/tests/host/sys/pgmspace.h +++ b/tests/host/sys/pgmspace.h @@ -82,5 +82,6 @@ inline int vsnprintf_P(char* str, size_t size, const char* format, va_list ap) #define strncmp_P strncmp #define strncasecmp_P strncasecmp #define strcat_P strcat +#define memcmp_P memcmp #endif From 1248d3874e0da70186925ec85cada6230de7b145 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Mon, 18 Mar 2024 00:25:29 +0330 Subject: [PATCH 05/10] Updater - missing error codes (#9104) Adds the two missing error states when beginning an Update. There were debugging logs for this but the error state was not set which would lead to confusion --- cores/esp8266/Updater.cpp | 20 ++++++++++++++------ cores/esp8266/Updater.h | 8 +++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 91f2a9e6ae..b4961b616d 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -70,6 +70,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { #ifdef DEBUG_UPDATER DEBUG_UPDATER.println(F("[begin] already running")); #endif + _setError(UPDATE_ERROR_RUNNING_ALREADY); return false; } @@ -86,7 +87,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { _setError(UPDATE_ERROR_BOOTSTRAP); return false; } - + #ifdef DEBUG_UPDATER if (command == U_FS) { DEBUG_UPDATER.println(F("[begin] Update Filesystem.")); @@ -133,7 +134,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { //make sure that the size of both sketches is less than the total space (updateEndAddress) if(updateStartAddress < currentSketchSize) { - _setError(UPDATE_ERROR_SPACE); + _setError(UPDATE_ERROR_SPACE); return false; } } @@ -162,6 +163,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { #ifdef DEBUG_UPDATER DEBUG_UPDATER.println(F("[begin] Unknown update command.")); #endif + _setError(UPDATE_ERROR_UNKNOWN_COMMAND); return false; } @@ -404,7 +406,7 @@ bool UpdaterClass::_writeBuffer(){ modifyFlashMode = true; } } - + if (eraseResult) { if(!_async) yield(); writeResult = ESP.flashWrite(_currentAddress, _buffer, _bufferLen); @@ -488,7 +490,7 @@ bool UpdaterClass::_verifyEnd() { uint8_t buf[4] __attribute__((aligned(4))); if(!ESP.flashRead(_startAddress, (uint32_t *) &buf[0], 4)) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_READ); + _setError(UPDATE_ERROR_READ); return false; } @@ -500,7 +502,7 @@ bool UpdaterClass::_verifyEnd() { return true; } else if (buf[0] != 0xE9) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_MAGIC_BYTE); + _setError(UPDATE_ERROR_MAGIC_BYTE); return false; } @@ -512,7 +514,7 @@ bool UpdaterClass::_verifyEnd() { // check if new bin fits to SPI flash if(bin_flash_size > ESP.getFlashChipRealSize()) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_NEW_FLASH_CONFIG); + _setError(UPDATE_ERROR_NEW_FLASH_CONFIG); return false; } #endif @@ -649,6 +651,12 @@ String UpdaterClass::getErrorString() const { case UPDATE_ERROR_OOM: out = F("Out of memory"); break; + case UPDATE_ERROR_RUNNING_ALREADY: + out = F("Update already running"); + break; + case UPDATE_ERROR_UNKNOWN_COMMAND: + out = F("Unknown update command"); + break; default: out = F("UNKNOWN"); break; diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index ad652d3806..7ee1d28311 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -21,6 +21,8 @@ #define UPDATE_ERROR_SIGN (12) #define UPDATE_ERROR_NO_DATA (13) #define UPDATE_ERROR_OOM (14) +#define UPDATE_ERROR_RUNNING_ALREADY (15) +#define UPDATE_ERROR_UNKNOWN_COMMAND (16) #define U_FLASH 0 #define U_FS 100 @@ -55,7 +57,7 @@ class UpdaterClass { using THandlerFunction_Progress = std::function; using THandlerFunction_Error = std::function; using THandlerFunction = std::function; - + UpdaterClass(); ~UpdaterClass(); @@ -69,7 +71,7 @@ class UpdaterClass { bool begin(size_t size, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW); /* - Run Updater from asynchronous callbacs + Run Updater from asynchronous callbacks */ void runAsync(bool async){ _async = async; } @@ -216,7 +218,7 @@ class UpdaterClass { bool _verifyHeader(uint8_t data); bool _verifyEnd(); - void _setError(int error); + void _setError(int error); bool _async = false; uint8_t _error = 0; From dc9abed8b91de32e36e61d11e4ed829e5ecf5556 Mon Sep 17 00:00:00 2001 From: Holger Lembke Date: Sun, 17 Mar 2024 22:04:44 +0100 Subject: [PATCH 06/10] ESP8266WiFiMulti - get number of APs in the list (#9082) When having some more complex setups it might be helpful to know the number of APs already added to the list. --- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index fab5829afd..3c77df02d4 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -69,7 +69,7 @@ class ESP8266WiFiMulti wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS); void cleanAPlist(); - + int count() { return _APlist.size(); } private: WifiAPlist _APlist; bool _firstRun; From 2bb1b5a4d5f3a80ce229b6d50d7b03ac2d007cec Mon Sep 17 00:00:00 2001 From: Clemens Kirchgatterer Date: Tue, 19 Mar 2024 16:01:59 +0100 Subject: [PATCH 07/10] Fix semantic typo in generic-examples.rst (#9107) exists -> exits --- doc/esp8266wifi/generic-examples.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/esp8266wifi/generic-examples.rst b/doc/esp8266wifi/generic-examples.rst index e139e3e5b5..8cd919d156 100644 --- a/doc/esp8266wifi/generic-examples.rst +++ b/doc/esp8266wifi/generic-examples.rst @@ -60,7 +60,7 @@ Alternatively, it can be declared as ``static`` in both function and global scop .. code:: cpp disconnectedEventHandler = nullptr; -Take note that lifetime of the callback handler is up to the app. e.g. if ``onStationModeDisconnected`` is declared in the function scope, it would be discarded immediately after the function exists. +Take note that lifetime of the callback handler is up to the app. e.g. if ``onStationModeDisconnected`` is declared in the function scope, it would be discarded immediately after the function exits. The Code ~~~~~~~~ From 877d44059ef05ccc6bfa794ea1e47802b0bedf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20M=C3=BCller?= Date: Sun, 24 Mar 2024 23:52:28 +0100 Subject: [PATCH 08/10] Add url redirect (#8970) * added getAvailableVersion(), moved _httpClientTimeout and _followRedirects to protected, added enum HTTPUpdateError * auto numbering of HTTPUpdateError enum * added getAvailableVersion(), debug output current current Sketch MD5 * Revert "added getAvailableVersion(), debug output current current Sketch MD5" This reverts commit 60d2c7762e7fb1fed7fae37fa99be149e12f125c. * Revert "auto numbering of HTTPUpdateError enum" This reverts commit 61785b27da3f2d42f8f95316d78ce22e5b00103a. * Revert "added getAvailableVersion(), moved _httpClientTimeout and _followRedirects to protected, added enum HTTPUpdateError" This reverts commit cec84ed17ab149d3e48082293f9e2723246b7d0b. * add redirect function * enhanced redirect() by cache control and client stop * updated redirect() comment * replaced redirect() API calls in examples * server.client().stop() not needed, redirect() does this --- .../CaptivePortalAdvanced/handleHttp.ino | 11 ++------- .../NAPTCaptivePortal/PortalRedirectHttp.ino | 4 +--- .../examples/WebServer/WebServer.ino | 3 +-- .../ESP8266WebServer/src/ESP8266WebServer.h | 24 +++++++++++++++++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino index aec2556a48..c7380017d1 100644 --- a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino +++ b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino @@ -27,9 +27,7 @@ void handleRoot() { boolean captivePortal() { if (!isIp(server.hostHeader()) && server.hostHeader() != (String(myHostname) + ".local")) { Serial.println("Request redirected to captive portal"); - server.sendHeader("Location", String("http://") + toStringIp(server.client().localIP()), true); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect(String("http://") + toStringIp(server.client().localIP())); return true; } return false; @@ -91,12 +89,7 @@ void handleWifiSave() { Serial.println("wifi save"); server.arg("n").toCharArray(ssid, sizeof(ssid) - 1); server.arg("p").toCharArray(password, sizeof(password) - 1); - server.sendHeader("Location", "wifi", true); - server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect("wifi"); saveCredentials(); connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID } diff --git a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino index 286490772d..5de12229a5 100644 --- a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino +++ b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino @@ -36,13 +36,11 @@ void sendPortalRedirect(String path, String targetName) { If the "Location" header element works the HTML stuff is never seen. */ // https://tools.ietf.org/html/rfc7231#section-6.4.3 - server.sendHeader("Location", path, true); - addNoCacheHeader(); String reply = FPSTR(portalRedirectHTML); reply.reserve(reply.length() + 2 * path.length() + 80); reply.replace("{t}", targetName); reply.replace("{1}", path); - server.send(302, "text/html", reply); + server.redirect(path, reply); } #endif // LWIP_FEATURES && !LWIP_IPV6 diff --git a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino index 81a58478f9..ffadddcca4 100644 --- a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino +++ b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino @@ -43,8 +43,7 @@ void handleRedirect() { if (!LittleFS.exists(url)) { url = "/$update.htm"; } - server.sendHeader("Location", url, true); - server.send(302); + server.redirect(url); } // handleRedirect() diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 397132f161..9f2b8b19c3 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -207,6 +207,30 @@ class ESP8266WebServerTemplate sendContent(emptyString); } + /** + * @brief Redirect to another URL, e.g. + * webserver.on("/index.html", HTTP_GET, []() { webserver.redirect("/"); }); + * There are 3 points of redirection here: + * 1) "Location" element in the header + * 2) Disable client caching + * 3) HTML "content" element to redirect + * If the "Location" header element works the HTML content is never seen. + * https://tools.ietf.org/html/rfc7231#section-6.4.3 + * @param url URL to redirect to + * @param content Optional redirect content + */ + void redirect(const String& url, const String& content = emptyString) { + sendHeader(F("Location"), url, true); + sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); + sendHeader(F("Pragma"), F("no-cache")); + sendHeader(F("Expires"), F("-1")); + send(302, F("text/html"), content); // send 302: "Found" + if (content.isEmpty()) { + // Empty content inhibits Content-length header so we have to close the socket ourselves. + client().stop(); // Stop is needed because we sent no content length + } + } + // Whether other requests should be accepted from the client on the // same socket after a response is sent. // This will automatically configure the "Connection" header of the response. From 8731f63594c3e77a645c2fd49440e97d7f1454df Mon Sep 17 00:00:00 2001 From: David Refoua Date: Mon, 25 Mar 2024 02:45:29 +0330 Subject: [PATCH 09/10] minor typo fixes (#9106) --- cores/esp8266/WString.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/WString.h b/cores/esp8266/WString.h index 47a9177534..1a2aebb298 100644 --- a/cores/esp8266/WString.h +++ b/cores/esp8266/WString.h @@ -33,7 +33,7 @@ #include #include -// an abstract class used as a means to proide a unique pointer type +// an abstract class used as a means to provide a unique pointer type // but really has no body class __FlashStringHelper; #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) @@ -204,7 +204,7 @@ class String { bool concat(double num); // if there's not enough memory for the concatenated value, the string - // will be left unchanged (but this isn't signalled in any way) + // will be left unchanged (but this isn't signaled in any way) template String &operator +=(const T &rhs) { concat(rhs); @@ -343,7 +343,7 @@ class String { char *wbuffer() { return const_cast(buffer()); } // Writable version of buffer // concatenation is done via non-member functions - // make sure we still have access to internal methods, since we optimize based on capacity of both sides and want to manipulate internal buffers directly + // make sure we still have access to internal methods, since we optimize based on the capacity of both sides and want to manipulate internal buffers directly friend String operator +(const String &lhs, String &&rhs); friend String operator +(String &&lhs, String &&rhs); friend String operator +(char lhs, String &&rhs); From 41ecd65c6a4a711d6d799629699a41400992c376 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 25 Mar 2024 00:35:19 +0100 Subject: [PATCH 10/10] Stream: +helpers to stream regular String (#9043) This allows to use a String as a destination Stream by using a temporary with streaming helpers. --- cores/esp8266/Stream.h | 4 ++++ cores/esp8266/StreamString.h | 16 +++++++-------- .../examples/StreamString/StreamString.ino | 20 +++++++++++++++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/cores/esp8266/Stream.h b/cores/esp8266/Stream.h index 21f319ee6b..0706bec001 100644 --- a/cores/esp8266/Stream.h +++ b/cores/esp8266/Stream.h @@ -196,21 +196,25 @@ class Stream: public Print { // returns number of transferred bytes size_t sendAvailable (Stream* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); } size_t sendAvailable (Stream& to) { return sendAvailable(&to); } + size_t sendAvailable (Stream&& to) { return sendAvailable(&to); } // transfers data until timeout // returns number of transferred bytes size_t sendAll (Stream* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); } size_t sendAll (Stream& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); } + size_t sendAll (Stream&& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); } // transfers data until a char is encountered (the char is swallowed but not transferred) with timeout // returns number of transferred bytes size_t sendUntil (Stream* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); } size_t sendUntil (Stream& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); } + size_t sendUntil (Stream&& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); } // transfers data until requested size or timeout // returns number of transferred bytes size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); } size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); } + size_t sendSize (Stream&& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); } // remaining size (-1 by default = unknown) virtual ssize_t streamRemaining () { return -1; } diff --git a/cores/esp8266/StreamString.h b/cores/esp8266/StreamString.h index 2331a3c51a..dced5aee80 100644 --- a/cores/esp8266/StreamString.h +++ b/cores/esp8266/StreamString.h @@ -29,7 +29,7 @@ #include "WString.h" /////////////////////////////////////////////////////////////// -// S2Stream points to a String and makes it a Stream +// S2Stream ("String to Stream") points to a String and makes it a Stream // (it is also the helper for StreamString) class S2Stream: public Stream @@ -184,19 +184,18 @@ class S2Stream: public Stream return peekPointer < 0 ? string->length() : string->length() - peekPointer; } - // calling setConsume() will consume bytes as the stream is read - // (enabled by default) + // calling setConsume() will make the string consumed as the stream is read. + // (default behaviour) void setConsume() { peekPointer = -1; } - // Reading this stream will mark the string as read without consuming - // (not enabled by default) - // Calling resetPointer() resets the read state and allows rereading. - void resetPointer(int pointer = 0) + // Calling resetPointer() resets the read cursor and allows rereading. + // (this is the opposite of default mode set by setConsume()) + void resetPointer(size_t pointer = 0) { - peekPointer = pointer; + peekPointer = std::min(pointer, (size_t)string->length()); } protected: @@ -204,6 +203,7 @@ class S2Stream: public Stream int peekPointer; // -1:String is consumed / >=0:resettable pointer }; +/////////////////////////////////////////////////////////////// // StreamString is a S2Stream holding the String class StreamString: public String, public S2Stream diff --git a/libraries/esp8266/examples/StreamString/StreamString.ino b/libraries/esp8266/examples/StreamString/StreamString.ino index f177b53edc..73512cf2af 100644 --- a/libraries/esp8266/examples/StreamString/StreamString.ino +++ b/libraries/esp8266/examples/StreamString/StreamString.ino @@ -54,7 +54,7 @@ void testStreamString() { { // We use a a lighter StreamConstPtr(input) to make a read-only Stream out of // a String that obviously should not be modified during the time the - // StreamConstPtr instance is used. It is used as a source to be sent to + // StreamConstPtr instance is used. It is used as a read-only source to be sent to // 'result'. result.clear(); @@ -77,7 +77,7 @@ void testStreamString() { // Now inputString is made into a Stream using S2Stream, // and set in non-consume mode (using ::resetPointer()). - // Then, after that input is read once, it won't be anymore readable + // Then, after input is read once, it won't be anymore readable // until the pointer is reset. S2Stream input(inputString); @@ -87,7 +87,7 @@ void testStreamString() { input.sendAll(result); input.sendAll(result); check("S2Stream.sendAll(StreamString)", result.c_str(), "hello"); - check("unmodified String given to S2Stream", inputString.c_str(), "hello"); + check("String given to S2Stream is unmodified", inputString.c_str(), "hello"); } { @@ -103,6 +103,17 @@ void testStreamString() { check("S2Stream.resetPointer(2):", result.c_str(), "llo"); } + { + // Streaming to a regular String + + String someSource{ F("hello") }; + String someDestString; + + StreamConstPtr(someSource).sendAll(S2Stream(someDestString)); + StreamConstPtr(someSource).sendAll(S2Stream(someDestString)); + check("StreamConstPtr(someSource).sendAll(S2Stream(someDestString))", someDestString.c_str(), "hellohello"); + } + { // inputString made into a Stream // reading the Stream consumes the String @@ -181,7 +192,8 @@ void setup() { testStreamString(); - Serial.printf("sizeof: String:%d Stream:%d StreamString:%d SStream:%d\n", (int)sizeof(String), (int)sizeof(Stream), (int)sizeof(StreamString), (int)sizeof(S2Stream)); + Serial.printf("sizeof: String:%zu Stream:%zu StreamString:%zu S2Stream:%zu StreamConstPtr:%zu\n", + sizeof(String), sizeof(Stream), sizeof(StreamString), sizeof(S2Stream), sizeof(StreamConstPtr)); } #endif